├── .gitignore ├── README.md ├── first-web-app-module ├── configurable-module.js ├── first-module.js └── index.js ├── first-web-app ├── config.json ├── demo-p.js ├── gulpfile.js ├── index.js ├── package.json └── www │ └── index.html ├── mongo-rest-api ├── app │ ├── config │ │ └── config.js │ ├── db │ │ └── mongoose.js │ ├── middlewares │ │ └── authenticate.js │ ├── models │ │ ├── todo.js │ │ └── user.js │ ├── server.js │ └── tests │ │ ├── seed │ │ └── seed.js │ │ └── server.test.js ├── experiments │ ├── mongo-connect.js │ ├── mongo-delete.js │ ├── mongo-fetch.js │ ├── mongo-update.js │ └── mongoose-queries.js └── package.json ├── note-taking-app ├── README.md ├── note-app.js ├── note-lib.js ├── notes.js ├── one.JPG ├── package.json ├── storage │ └── notes-data.json └── yargs-config.json ├── registration-login ├── app │ ├── configs │ │ └── index.js │ ├── db │ │ └── index.js │ ├── models │ │ └── user.js │ ├── server.js │ └── views │ │ ├── home.ejs │ │ ├── login.ejs │ │ ├── register.ejs │ │ └── secret.ejs └── package.json ├── simple-website ├── README.md ├── logs │ └── server.log ├── package.json ├── screenshot-1.JPG ├── screenshot-2.JPG ├── server.js └── views │ ├── 404.hbs │ ├── about.hbs │ ├── home.hbs │ ├── maintainance.hbs │ └── partials │ ├── footer.hbs │ ├── header.hbs │ └── materialize │ ├── css │ ├── materialize.css │ └── materialize.min.css │ ├── fonts │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 │ └── js │ ├── materialize.js │ └── materialize.min.js ├── streams-and-pipes ├── package.json ├── sample-big-file.txt ├── stream-and-pipes.js ├── stream-pipe-on-server.js ├── write-big-file.txt └── write-big-pipe.txt ├── testing-node ├── package.json ├── server │ ├── server.js │ └── server.test.js └── utils │ ├── utils.js │ └── utils.test.js └── weather-app ├── README.md ├── capture.JPG ├── geochords └── geochords.js ├── package.json ├── show-weather.js └── weather └── weather.js /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore the modules folder 2 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learning NodeJS 2 | 3 | This folder contains all the apps that I made/making while learning Node. 4 | As of now the apps that may be useful to you are : 5 | 6 | * _**Note App**_ 7 | * _**Weather App**_ 8 | * _**Simple Website**_ 9 |

10 | **Keep a watch on this folder to get push updates** 11 | 12 | ### _Star it if you liked it!_ 13 | -------------------------------------------------------------------------------- /first-web-app-module/configurable-module.js: -------------------------------------------------------------------------------- 1 | module.exports = (config)=> { 2 | return { 3 | log: (msg)=>{ 4 | console.log(config.prefix + msg); 5 | } 6 | } 7 | }; -------------------------------------------------------------------------------- /first-web-app-module/first-module.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | doIt: ()=>{ 3 | console.log("did it!"); 4 | }, 5 | doSomething: ()=>{ 6 | console.log("did something!"); 7 | }, 8 | getItDone: ()=>{ 9 | console.log("got it done!"); 10 | } 11 | }; -------------------------------------------------------------------------------- /first-web-app-module/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const firstModule = require('./first-module'); 4 | firstModule.doIt(); 5 | 6 | const configModule = require('./configurable-module'); 7 | const configModuleA = configModule({ prefix: 'A>'}); 8 | configModuleA.log('test 1'); 9 | 10 | const configModuleB = configModule({prefix:"B>"}); 11 | configModuleB.log('test 2'); 12 | 13 | // using ES6 destructuring 14 | const {getItDone, doSomething : doS} = require('./first-module'); 15 | getItDone(); 16 | // using ES6 destructuring alias 17 | doS(); 18 | -------------------------------------------------------------------------------- /first-web-app/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "webServer" : { 3 | "folder" : "www", 4 | "port" : "3030" 5 | } 6 | } -------------------------------------------------------------------------------- /first-web-app/demo-p.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('http'); 4 | const express = require('express'); 5 | const fs = require('fs'); 6 | 7 | //open config file asynchronously 8 | const configJSON = fs.readFile('./config.json', 'utf-8', (err, file)=>{ 9 | const data = JSON.parse(file); 10 | const app = express(); 11 | 12 | // folder in which out static web page are stored 13 | app.use(express.static(data.webServer.folder)); 14 | 15 | const httpServer = http.createServer(app); 16 | 17 | httpServer.listen(data.webServer.port, (err)=>{ 18 | if (err){ 19 | console.log(err.message); 20 | return; 21 | } 22 | 23 | console.log(`Server running at port : ${data.webServer.port}`); 24 | }); 25 | }); 26 | 27 | console.log("opening config file"); 28 | -------------------------------------------------------------------------------- /first-web-app/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const gulp = require('gulp'); 4 | 5 | gulp.task('default', ()=>{ 6 | console.log("running our first gulp task"); 7 | }) 8 | -------------------------------------------------------------------------------- /first-web-app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('http'); 4 | const express = require('express'); 5 | const fs = require('fs'); 6 | 7 | // loading folder and port number from config file 8 | const configJSON = fs.readFileSync('./config.json'); 9 | const config = JSON.parse(configJSON); 10 | 11 | const app = express(); 12 | app.use(express.static(config.webServer.folder)); 13 | 14 | const httpServer = http.createServer(app); 15 | 16 | httpServer.listen(config.webServer.port, (err)=>{ 17 | if (err) { 18 | console.log(err.message); 19 | return; 20 | } 21 | 22 | console.log(`server running at port:${config.webServer.port}`); 23 | }); -------------------------------------------------------------------------------- /first-web-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-web-app", 3 | "version": "0.1.0", 4 | "description": "my first node app", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Ashok Dey", 11 | "license": "MIT", 12 | "dependencies": { 13 | "express": "^4.14.0" 14 | }, 15 | "devDependencies": { 16 | "gulp": "^3.9.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /first-web-app/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

My static page

9 | 10 | -------------------------------------------------------------------------------- /mongo-rest-api/app/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let env = process.env.NODE_ENV || 'development'; 3 | console.log('****Working Environment is : ', env); 4 | 5 | if (env === 'development') { 6 | process.env.PORT = 3000; 7 | process.env.MONGODB_URI = 'mongodb://127.0.0.1:27017/TodoApp'; 8 | } 9 | else if (env === 'test'){ 10 | process.env.PORT = 3000; 11 | process.env.MONGODB_URI = 'mongodb://127.0.0.1:27017/TodoAppTest'; 12 | } 13 | -------------------------------------------------------------------------------- /mongo-rest-api/app/db/mongoose.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mongoose = require('mongoose'); 4 | 5 | mongoose.Promise = global.Promise; 6 | mongoose.connect(process.env.MONGODB_URI); 7 | 8 | module.exports = {mongoose}; -------------------------------------------------------------------------------- /mongo-rest-api/app/middlewares/authenticate.js: -------------------------------------------------------------------------------- 1 | const {User} = require('./../models/user'); 2 | 3 | let authenticate = (req, res, next) => { 4 | let token = req.header('x-auth'); 5 | 6 | User.findByToken(token).then((user) => { 7 | if(!user) { 8 | return Promise.reject(); 9 | } 10 | // modify the req object to be used in the route 11 | req.user = user; 12 | req.token = token; 13 | next(); 14 | }).catch((err) => { 15 | res.status(401).send({ 16 | err, 17 | status : 401 18 | }); 19 | }); 20 | } 21 | 22 | module.exports = {authenticate}; -------------------------------------------------------------------------------- /mongo-rest-api/app/models/todo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const mongoose = require('mongoose'); 3 | 4 | let Todo = mongoose.model('Todo', { 5 | text : { 6 | type : String, 7 | required : true, 8 | minlength : 5, 9 | trim : true 10 | }, 11 | completed : { 12 | type : Boolean, 13 | default : false 14 | }, 15 | completedAt : { 16 | type : Number, 17 | default : null 18 | }, 19 | _creator : { 20 | type : mongoose.Schema.Types.ObjectId, 21 | required : true 22 | } 23 | }); 24 | 25 | module.exports = {Todo}; -------------------------------------------------------------------------------- /mongo-rest-api/app/models/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const mongoose = require('mongoose'); 3 | const validator = require('validator'); 4 | const jwt = require('jsonwebtoken'); 5 | const _ = require('lodash'); 6 | const bcrypt = require('bcryptjs'); 7 | 8 | let UserSchema = new mongoose.Schema({ 9 | name : { 10 | type : String, 11 | required : true, 12 | minlength : 5, 13 | trim : true 14 | }, 15 | email : { 16 | type : String, 17 | required : true, 18 | minlength : 5, 19 | trim : true, 20 | unique : true, 21 | validate : { 22 | validator : validator.isEmail, 23 | message : '{value} is invalid email' 24 | } 25 | }, 26 | password : { 27 | type : String, 28 | required : true, 29 | minlength : 5, 30 | trim : true 31 | }, 32 | tokens : [{ 33 | access : { 34 | type : String, 35 | required : true 36 | }, 37 | token : { 38 | type : String, 39 | required : true 40 | } 41 | }] 42 | }); 43 | 44 | 45 | UserSchema.methods.generateAuthToken = function () { 46 | let user = this; 47 | let access = 'auth'; 48 | let token = jwt.sign({_id : user._id.toHexString(), access}, 'abc123').toString(); 49 | 50 | // console.log('Token generated : ' + token); 51 | 52 | user.tokens.push({access, token}); 53 | 54 | return user.save().then(() => { 55 | return token; 56 | }); 57 | } 58 | 59 | UserSchema.methods.toJSON = function() { 60 | let user = this; 61 | let userObject = user.toObject(); 62 | return _.pick(userObject, ['_id', 'email']); 63 | }; 64 | 65 | UserSchema.methods.removeToken = function(token) { 66 | let user = this; 67 | return user.update({ 68 | $pull : { 69 | tokens : { 70 | token // similat to 'token : token' 71 | } 72 | } 73 | }); 74 | }; 75 | 76 | 77 | UserSchema.statics.findByToken = function(token) { 78 | let User = this; 79 | let decoded; 80 | 81 | try { 82 | decoded = jwt.verify(token, 'abc123'); 83 | } 84 | catch (e) { 85 | return Promise.reject('No user found with the given token'); 86 | } 87 | 88 | return User.findOne({ 89 | _id : decoded._id, 90 | 'tokens.token' : token, 91 | 'tokens.access' : 'auth' 92 | }) 93 | }; 94 | 95 | UserSchema.statics.findByCredentials = function(email, password) { 96 | let User = this; 97 | return User.findOne({email}).then((user) => { 98 | if(!user){ 99 | return Promise.reject('Invalid email, user not found'); 100 | } 101 | return new Promise((resolve, reject) => { 102 | bcrypt.compare(password, user.password, (err, res) => { 103 | //console.log('comparing password'); 104 | if(res) { 105 | resolve(user); 106 | } else { 107 | reject('incorrect password'); 108 | } 109 | }); 110 | }); 111 | }); 112 | }; 113 | 114 | 115 | UserSchema.pre('save', function(next) { 116 | let user = this; 117 | 118 | if (user.isModified('password')){ 119 | bcrypt.genSalt(10, (err, salt) => { 120 | if (err) { 121 | 122 | } 123 | bcrypt.hash(user.password, salt, (err, hash) => { 124 | user.password = hash; 125 | next(); 126 | }) 127 | }); 128 | } 129 | else { 130 | next(); 131 | } 132 | }); 133 | 134 | let User = mongoose.model('User', UserSchema); 135 | 136 | 137 | module.exports = {User}; -------------------------------------------------------------------------------- /mongo-rest-api/app/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const config = require('./config/config'); 3 | const _ = require('lodash'); 4 | const app = require('express')(); 5 | const bodyParser = require('body-parser'); 6 | 7 | const {ObjectID} = require('mongodb'); 8 | const {mongoose} = require('./db/mongoose'); 9 | const {Todo} = require('./models/todo'); 10 | const {User} = require('./models/user'); 11 | const {authenticate} = require('./middlewares/authenticate'); 12 | 13 | let port = process.env.PORT || 3000; 14 | 15 | // the body-parser middleware 16 | app.use(bodyParser.json()); 17 | 18 | // create a GET /todos route 19 | app.get('/todos', authenticate, (req, res) => { 20 | 21 | Todo.find({ 22 | _creator : req.user._id 23 | }).then((data) => { 24 | res.send({data}); 25 | }, (err) => { 26 | res.status(400).send(err); 27 | }); 28 | }); 29 | 30 | // create a POST /todos route 31 | app.post('/todos', authenticate, (req, res) => { 32 | // make a todo and save it into the database 33 | let todo = new Todo({ 34 | text : req.body.text, 35 | _creator : req.user._id 36 | }); 37 | 38 | todo.save().then((data) => { 39 | // send the todo as a response 40 | res.send(data); 41 | }, (err) => { 42 | // send the error as a response 43 | res.status(400).send(err); 44 | }); 45 | }); 46 | 47 | // get todos by id GET /todos/id 48 | app.get('/todos/:id', authenticate, (req, res) => { 49 | //get the todo id in todoID 50 | let todoID = req.params.id; 51 | 52 | // if the ID is valid not valid, send a message 53 | if (!ObjectID.isValid(todoID)) { 54 | //console.log('Invalid todo ID'); 55 | return res.status(400).send({ 56 | message : 'InvalidID', 57 | status : 400 58 | }); 59 | } 60 | // search for todo with the todo id and the creator 61 | // do not displa todo if the creator id is different 62 | Todo.findOne({ 63 | _id : todoID, 64 | _creator : req.user._id 65 | }).then((data) => { 66 | if (!data) { 67 | return res.status(404).send({ 68 | message : 'Todo not found', 69 | status : 404 70 | }); 71 | } 72 | 73 | res.status(200).send({ 74 | todo : data, 75 | status : 200 76 | }); 77 | 78 | }).catch((err) => { 79 | res.sendStatus(400).send({err}); 80 | //console.log('todoId not found'); 81 | }); 82 | }); 83 | 84 | // create the delete todo by id route 85 | app.delete('/todos/:id', authenticate, (req, res) => { 86 | let todoID = req.params.id; 87 | 88 | if (!ObjectID.isValid(todoID)) { 89 | return res.status(400).send({ 90 | message : 'InvalidID', 91 | status : 400 92 | }); 93 | } 94 | 95 | Todo.findOneAndRemove({ 96 | _id : todoID, 97 | _creator : req.user._id 98 | }).then((data) => { 99 | if(!data) { 100 | return res.status(404).send({ 101 | message : 'Todo not found', 102 | status : 404 103 | }); 104 | } 105 | 106 | res.status(200).send({ 107 | todo : data, 108 | status : 200 109 | }); 110 | }).catch((err)=> res.status(400).send({ 111 | message : 'Error', 112 | status : 400 113 | })); 114 | }); 115 | 116 | app.patch('/todos/:id', authenticate, (req, res) => { 117 | let todoID = req.params.id; 118 | let body = _.pick(req.body, ['text', 'completed']); 119 | 120 | if (!ObjectID.isValid(todoID)) { 121 | console.log('id rejected by isValid()'); 122 | return res.status(400).send({ 123 | message : 'InvalidID', 124 | status : 400 125 | }); 126 | } 127 | // check if the completed field is boolena or not 128 | // and it's value is true 129 | 130 | if(_.isBoolean(body.completed) && body.completed) { 131 | // set the completed as true and the timestamp 132 | body.completed = true; 133 | body.completedAt = new Date().getTime(); 134 | } else { 135 | body.completed = false; 136 | body.completedAt = null; 137 | } 138 | 139 | // update the database 140 | Todo.findOneAndUpdate({ 141 | _id : todoID, 142 | _creator : req.user._id 143 | }, { $set : body}, {new : true}).then((data) => { 144 | if (!data) { 145 | return res.status(404).send({ 146 | message : 'Todo not found', 147 | status : 404 148 | }); 149 | } 150 | 151 | res.status(200).send({todo : data, status : 200}); 152 | 153 | }).catch((e) => { 154 | res.status(400).send({ 155 | message : 'Failed to Update', 156 | status : 400 157 | }); 158 | }); 159 | }); 160 | 161 | // user routes here 162 | // POST /users route 163 | 164 | app.post('/users', (req, res) => { 165 | // pick the email name and password using lodash pick method 166 | let userData = _.pick(req.body, ['name', 'email', 'password']); 167 | 168 | // create new instance of the User model 169 | let user = new User(userData); 170 | // save the user data inside the DB 171 | user.save().then(() => { 172 | ///generate token 173 | return user.generateAuthToken(); 174 | 175 | }).then((token) => { 176 | res.header('x-auth', token).send({user}); 177 | //console.log('User signup successful'); 178 | 179 | }).catch((err) => { 180 | //console.log('error : ', err); 181 | // send the error 182 | res.status(400).send({ 183 | error : 'error occured', 184 | status : 400 185 | }) 186 | }) 187 | }); 188 | 189 | // GET users/me route, using the token header 190 | app.get('/users/me', authenticate, (req, res) => { 191 | res.status(200).send(req.user) 192 | }); 193 | 194 | // login route 195 | 196 | app.post('/users/login', (req, res) => { 197 | let userData = _.pick(req.body, ['email', 'password']); 198 | // search for the user in using the email 199 | User.findByCredentials(userData.email, userData.password).then((user) => { 200 | return user.generateAuthToken().then((token) => { 201 | res.header('x-auth', token).send(user); 202 | }); 203 | }).catch((err) => { 204 | res.status(400).send({err, status: 400}); 205 | }); 206 | }); 207 | 208 | //logout route 209 | 210 | app.delete('/users/me/token', authenticate, (req, res) => { 211 | req.user.removeToken(req.token).then(() => { 212 | res.status(200).send(); 213 | }, () => { 214 | res.status(400).send(); 215 | }); 216 | }); 217 | 218 | // Listen to the port 219 | app.listen(port, () => { 220 | console.log('server listening at port : ' + port); 221 | }); 222 | 223 | 224 | module.exports = {app}; -------------------------------------------------------------------------------- /mongo-rest-api/app/tests/seed/seed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {ObjectID} = require('mongodb'); 4 | const jwt = require('jsonwebtoken'); 5 | 6 | const {Todo} = require('./../../models/todo'); 7 | const {User} = require('./../../models/user'); 8 | 9 | // create an id for the user data 10 | const userOneID = new ObjectID(); 11 | const userTwoID = new ObjectID(); 12 | 13 | // seed data 14 | const dummyTodos = [{ 15 | _id : new ObjectID(), 16 | text : 'first dummy todo', 17 | _creator : userOneID 18 | },{ 19 | _id : new ObjectID(), 20 | text : 'second dummy todo', 21 | completed : true, 22 | completedAt : 1484982333753, 23 | _creator : userOneID 24 | },{ 25 | _id : new ObjectID(), 26 | text : 'third dummy todos', 27 | _creator : userTwoID 28 | }]; 29 | 30 | // the function that populates the data in the todo collection 31 | const populateTodos = (done) => { 32 | Todo.remove({}).then(() => { 33 | return Todo.insertMany(dummyTodos); 34 | }).then(() => done()); 35 | } 36 | 37 | 38 | const dummyUsers = [ 39 | { 40 | _id : userOneID, 41 | name : 'Jhon Doe', 42 | email : 'johndoe@jd.com', 43 | password : 'dummypass123', 44 | tokens : [{ 45 | access : 'auth', 46 | token : jwt.sign({_id : userOneID, access : 'auth'}, 'abc123').toString() 47 | }] 48 | }, 49 | { 50 | _id : userTwoID, 51 | name : 'Jane Doe', 52 | email : 'janedoe@gmail.com', 53 | password : 'secondpassword213', 54 | tokens : [{ 55 | access : 'auth', 56 | token : jwt.sign({_id : userTwoID, access : 'auth'}, 'abc123').toString() 57 | }] 58 | } 59 | ]; 60 | 61 | const populateUsers = (done) => { 62 | User.remove({}).then(() => { 63 | let userOne = new User(dummyUsers[0]).save(); 64 | let userTwo = new User(dummyUsers[1]).save(); 65 | 66 | return Promise.all([userOne, userTwo]); 67 | }).then(() => done()); 68 | } 69 | 70 | 71 | module.exports = { 72 | dummyTodos, 73 | populateTodos, 74 | dummyUsers, 75 | populateUsers 76 | } 77 | -------------------------------------------------------------------------------- /mongo-rest-api/app/tests/server.test.js: -------------------------------------------------------------------------------- 1 | const expect = require('expect'); 2 | const request = require('supertest'); 3 | const {app} = require('./../server'); 4 | const {ObjectID} = require('mongodb'); 5 | const {Todo} = require('./../models/todo'); 6 | const {User} = require('./../models/user'); 7 | 8 | const {dummyTodos, populateTodos, dummyUsers, populateUsers} = require('./seed/seed'); 9 | 10 | 11 | // make the DB empty first 12 | beforeEach(populateUsers); 13 | beforeEach(populateTodos); 14 | 15 | // write tests 16 | describe ('GET /todos', () => { 17 | it('should get all todos', (done) => { 18 | 19 | request(app) 20 | .get('/todos') 21 | .set('x-auth', dummyUsers[0].tokens[0].token) 22 | .expect(200) 23 | .expect((res) => { 24 | expect(res.body.data.length).toBe(2); 25 | }) 26 | .end(done) 27 | }); 28 | }); 29 | 30 | describe ('POST /todos', () => { 31 | 32 | it('should create a new todo', (done) => { 33 | let text = 'make a test suit'; 34 | 35 | request(app) 36 | .post('/todos') 37 | .set('x-auth', dummyUsers[0].tokens[0].token) 38 | .send({text}) 39 | .expect(200) 40 | .expect((res) => { 41 | expect(res.body.text).toBe(text); 42 | }).end((err, res) => { 43 | if (err) { 44 | return done(err); 45 | } 46 | 47 | Todo.find({text}).then((todos) => { 48 | expect(todos.length).toBe(1); 49 | expect(todos[0].text).toBe(text); 50 | done(); 51 | }).catch((err) => done(err)); 52 | }); 53 | }); 54 | 55 | it ('should not create a todo for invalid data', (done) => { 56 | 57 | request(app) 58 | .post('/todos') 59 | .set('x-auth', dummyUsers[0].tokens[0].token) 60 | .send({}) 61 | .expect(400) 62 | .end((err, res) => { 63 | if(err) { 64 | return done(err); 65 | } 66 | 67 | Todo.find().then((todos) => { 68 | expect(todos.length).toBe(3); 69 | done(); 70 | }).catch((err) => done(err)); 71 | }); 72 | }); 73 | 74 | }); 75 | 76 | 77 | describe ('GET /todos/:id', () => { 78 | it('should return a todo doc', (done) => { 79 | request(app) 80 | .get(`/todos/${dummyTodos[0]._id.toHexString()}`) 81 | .set('x-auth', dummyUsers[0].tokens[0].token) 82 | .expect(200) 83 | .expect((res) => { 84 | expect(res.body.todo.text).toBe(dummyTodos[0].text); 85 | }) 86 | .end(done); 87 | }); 88 | 89 | it('should not return a todo doc created by othe ruser', (done) => { 90 | request(app) 91 | .get(`/todos/${dummyTodos[2]._id.toHexString()}`) 92 | .set('x-auth', dummyUsers[0].tokens[0].token) 93 | .expect(404) 94 | .end(done); 95 | }); 96 | 97 | it('should give a 404 if id not found', (done) => { 98 | //create a new id for testing 99 | let hexID = new ObjectID(); 100 | request(app) 101 | .get('/todos/' + hexID) 102 | .set('x-auth', dummyUsers[0].tokens[0].token) 103 | .expect(404) 104 | .expect((res) => { 105 | expect(res.body.status).toBe(404); 106 | }) 107 | .end(done); 108 | }); 109 | 110 | it('should return a 400 if id is invalid', (done) => { 111 | request(app) 112 | .get(`/todos/${dummyTodos[0]._id.toHexString() + '21'}`) 113 | .set('x-auth', dummyUsers[0].tokens[0].token) 114 | .expect(400) 115 | .expect((res) => { 116 | expect(res.body.status).toBe(400); 117 | }) 118 | .end(done); 119 | }); 120 | }); 121 | 122 | describe('DELETE /todos/:id', () => { 123 | 124 | let hexID = new ObjectID(); 125 | 126 | it('should delete a todo for a valid id', (done) => { 127 | let todoHexID = dummyTodos[0]._id.toHexString(); 128 | 129 | request(app) 130 | .delete(`/todos/${todoHexID}`) 131 | .set('x-auth', dummyUsers[0].tokens[0].token) 132 | .expect(200) 133 | .expect((res) => { 134 | expect(res.body.todo._id).toBe(todoHexID); 135 | expect(res.body.status).toBe(200); 136 | }) 137 | .end((err, res) => { 138 | if(err) { 139 | return done(err); 140 | } 141 | 142 | Todo.findById(todoHexID).then((todo) => { 143 | expect(todo).toNotExist(); 144 | done(); 145 | }).catch((err) => done(err)); 146 | }); 147 | }); 148 | 149 | it('should not delete a todo created by other user', (done) => { 150 | let todoHexID = dummyTodos[2]._id.toHexString(); 151 | 152 | request(app) 153 | .delete(`/todos/${todoHexID}`) 154 | .set('x-auth', dummyUsers[0].tokens[0].token) 155 | .expect(404) 156 | .end((err, res) => { 157 | if(err) { 158 | return done(err); 159 | } 160 | 161 | Todo.findById(todoHexID).then((todo) => { 162 | expect(todo).toExist(); 163 | done(); 164 | }).catch((err) => done(err)); 165 | }); 166 | }); 167 | 168 | it('should give 400 for invalid id', (done) => { 169 | request(app) 170 | .delete(`/todos/${hexID.toHexString() + '45'}`) 171 | .set('x-auth', dummyUsers[0].tokens[0].token) 172 | .expect(400) 173 | .expect((res) => { 174 | expect(res.body.status).toBe(400); 175 | }) 176 | .end(done); 177 | }); 178 | 179 | it('should give 404 if todo not found', (done) => { 180 | request(app) 181 | .delete(`/todos/${hexID.toHexString()}`) 182 | .set('x-auth', dummyUsers[0].tokens[0].token) 183 | .expect(404) 184 | .expect((res) => { 185 | expect(res.body.status).toBe(404); 186 | }) 187 | .end(done); 188 | }); 189 | }); 190 | 191 | describe('PATCH /todos/:id', () => { 192 | 193 | it('should set completed of a todo as true', (done) => { 194 | let hexID = dummyTodos[0]._id.toHexString(); 195 | let text = 'This should be the new text'; 196 | 197 | request(app) 198 | .patch(`/todos/${hexID}`) 199 | .set('x-auth', dummyUsers[0].tokens[0].token) 200 | .send({ 201 | text, 202 | completed : true 203 | }) 204 | .expect(200) 205 | .expect((res) => { 206 | expect(res.body.todo.text).toBe(text); 207 | expect(res.body.todo.completed).toBe(true); 208 | expect(res.body.todo.completedAt).toBeA('number'); 209 | }) 210 | .end(done); 211 | }); 212 | 213 | it('should not set completed of a todo as true for other user', (done) => { 214 | let hexID = dummyTodos[2]._id.toHexString(); 215 | let text = 'This should be the new text'; 216 | 217 | request(app) 218 | .patch(`/todos/${hexID}`) 219 | .set('x-auth', dummyUsers[0].tokens[0].token) 220 | .send({ 221 | text, 222 | completed : true 223 | }) 224 | .expect(404) 225 | .end(done); 226 | }); 227 | 228 | it('should clear completed when todo edited/renamed', (done) => { 229 | let hexID = dummyTodos[1]._id.toHexString(); 230 | text = 'Renamed to a new task'; 231 | 232 | request(app) 233 | .patch(`/todos/${hexID}`) 234 | .set('x-auth', dummyUsers[0].tokens[0].token) 235 | .send({ 236 | completed : false, 237 | completedAt : null, 238 | text 239 | }) 240 | .expect(200) 241 | .expect((res) => { 242 | expect(res.body.todo.completed).toBe(false); 243 | expect(res.body.todo.text).toBe(text); 244 | expect(res.body.todo.completedAt).toNotExist(); 245 | 246 | }) 247 | .end(done); 248 | 249 | }); 250 | 251 | }); 252 | 253 | describe('GET /users/me', () => { 254 | 255 | it('should return a user for valid token', (done) => { 256 | request(app) 257 | .get('/users/me') 258 | .set('x-auth', dummyUsers[0].tokens[0].token) 259 | .expect(200) 260 | .expect((res) => { 261 | expect(res.body._id).toBe(dummyUsers[0]._id.toHexString()); 262 | expect(res.body.email).toBe(dummyUsers[0].email); 263 | }).end(done); 264 | }); 265 | 266 | it('should give 401 for invalid token', (done) => { 267 | let value = undefined; 268 | request(app) 269 | .get('/users/me') 270 | .expect(401) 271 | .expect((res) => { 272 | expect(res.body.status).toBe(401) 273 | }).end(done); 274 | }); 275 | }); 276 | 277 | describe('POST /users', () => { 278 | it('should create a user with valid email and name', (done) => { 279 | let name = 'example'; 280 | let email = 'ex@mail.co'; 281 | let password = 'example@pass'; 282 | 283 | request(app) 284 | .post('/users') 285 | .send({name, email, password}) 286 | .expect(200) 287 | .expect((res) => { 288 | expect(res.body.user.email).toBe(email); 289 | expect(res.body.user._id).toExist(); 290 | expect(res.headers['x-auth']).toExist(); 291 | }).end((err) => { 292 | if (err) { 293 | return done(); 294 | } 295 | User.findOne({email}).then((user) => { 296 | expect(user).toExist(); 297 | expect(user.email).toBe(email); 298 | expect(user.password).toNotBe(password); 299 | done(); 300 | }).catch((err) => done(err)); 301 | }); 302 | }); 303 | 304 | it('should give validation error for invalid data', (done) => { 305 | let email = 'error'; 306 | let password = 'abc'; 307 | 308 | request(app) 309 | .post('/users') 310 | .send({}) 311 | .expect(400) 312 | .end(done); 313 | }); 314 | 315 | it('should give a 400 for duplicate email', (done) => { 316 | request(app) 317 | .post('/users') 318 | .send(dummyUsers[0]) 319 | .expect(400) 320 | .end(done); 321 | }); 322 | }); 323 | 324 | describe('POST /users/login', () => { 325 | 326 | it('should return a token and user for valid login', (done) => { 327 | 328 | request(app) 329 | .post('/users/login') 330 | .send({ 331 | email : dummyUsers[1].email, 332 | password : dummyUsers[1].password 333 | }) 334 | .expect(200) 335 | .expect((res) => { 336 | expect(res.headers['x-auth']).toExist(); 337 | expect(res.body.email).toBe(dummyUsers[1].email); 338 | }).end((err, res) => { 339 | if(err) { 340 | return done(err); 341 | } 342 | 343 | User.findById(dummyUsers[1]._id).then((user) => { 344 | expect(user.tokens[1]).toInclude({ 345 | access : 'auth', 346 | token : res.headers['x-auth'] 347 | }); 348 | done(); 349 | }).catch((err) => done(err)); 350 | }); 351 | }); 352 | 353 | it('should return 400 for invalid email and password', (done) => { 354 | 355 | request(app) 356 | .post('/users/login') 357 | .send({ 358 | email : dummyUsers[1].email, 359 | password : dummyUsers[1].password + 'abc' 360 | }) 361 | .expect(400) 362 | .expect((res) => { 363 | expect(res.headers['x-auth']).toNotExist(); 364 | }).end((err, res) => { 365 | if(err) { 366 | return done(err); 367 | } 368 | 369 | User.findById(dummyUsers[1]._id).then((user) => { 370 | expect(user.tokens.length).toBe(1); 371 | done(); 372 | }).catch((err) => done(err)); 373 | }); 374 | }); 375 | }); 376 | 377 | describe('DELETE /users/me/token', () => { 378 | it('should remove the valid token on logout', (done) => { 379 | 380 | request(app) 381 | .delete('/users/me/token') 382 | .set('x-auth', dummyUsers[0].tokens[0].token) 383 | .expect(200) 384 | .end((err, res) => { 385 | if(err) { 386 | return done(err); 387 | } 388 | 389 | User.findById(dummyUsers[0]._id).then((user) => { 390 | expect(user.tokens.length).toBe(0); 391 | done(); 392 | }).catch((err) => done(err)); 393 | }); 394 | }); 395 | }); -------------------------------------------------------------------------------- /mongo-rest-api/experiments/mongo-connect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {MongoClient} = require('mongodb'); 4 | 5 | MongoClient.connect('mongodb://localhost:27017/JokesApp', (err, db) => { 6 | if (err) 7 | return console.log('unable to connect MongoDB' + err); 8 | console.log('Connected to MongoDB Server'); 9 | 10 | // creating a new collection, a table like structure 11 | db.collection('Jokes').insertOne({ 12 | joke : 'Sample joke 2', 13 | likes : 0, 14 | }, (err, result) => { 15 | if (err) 16 | return console.log('unable to insert data' + err); 17 | 18 | console.log(JSON.stringify(result.ops, undefined, 2)); 19 | }); 20 | 21 | // one more users collection 22 | db.collection('Users').insertOne({ 23 | name : 'Ashok Dey', 24 | age : 22, 25 | location : 'Delhi' 26 | }, (err, result) => { 27 | if (err) 28 | return console.log('Failed to insert data into the user collection'); 29 | 30 | console.log(JSON.stringify(result.ops, undefined, 2)); 31 | }); 32 | 33 | // close the database 34 | db.close(); 35 | }); -------------------------------------------------------------------------------- /mongo-rest-api/experiments/mongo-delete.js: -------------------------------------------------------------------------------- 1 | const {MongoClient} = require('mongodb'); 2 | 3 | MongoClient.connect('mongodb://localhost:27017/JokesApp', (err, db) => { 4 | if (err){ 5 | return console.log('failed to connect to mongodb server. ', err); 6 | } 7 | 8 | console.log('Connected to MongoDB Server'); 9 | 10 | //deleteMany - delete all the occcurences 11 | db.collection('Jokes').deleteMany({joke : 'Sample joke 2'}).then((result) => { 12 | console.log(result.result); 13 | }, (err) => { 14 | cosole.log('Error deleting many. E : ', err) 15 | }); 16 | 17 | //deleteOne - deletes only first occurence of all the occurences 18 | db.collection('Jokes').deleteOne({joke : 'Test 1'}).then((result) => { 19 | console.log(result.result); 20 | }); 21 | 22 | db.collection('Jokes').findOneAndDelete({joke : 'Test 2'}).then((doc) => { 23 | console.log(doc); 24 | }, (err) => { 25 | console.log('Error find one and delete. E: ', err); 26 | }); 27 | 28 | //close the DB 29 | // db.close(); 30 | }); -------------------------------------------------------------------------------- /mongo-rest-api/experiments/mongo-fetch.js: -------------------------------------------------------------------------------- 1 | // import MongoClient from the mongodb package 2 | const {MongoClient} = require('mongodb'); 3 | 4 | // connect to mongodb server 5 | MongoClient.connect('mongodb://localhost:27017/JokesApp', (err, db) => { 6 | if (err) { 7 | return console.log('Failed to connect to mongoDB server : ' + err); 8 | } 9 | 10 | console.log('Connected to MongoDB Server'); 11 | 12 | //get the count of jokes stored 13 | db.collection('Jokes').count().then((count) => { 14 | console.log(`Jokes count = ${count}\n`); 15 | }, (err) => { 16 | if (err) { 17 | return console.log('error getting count', err); 18 | } 19 | }); 20 | 21 | // fetch all the jokes/documets with 10 likes 22 | db.collection('Jokes').find({likes : 10}).toArray().then((docs) => { 23 | console.log(JSON.stringify(docs, undefined, 2)); 24 | }, (err)=> { 25 | if (err) { 26 | return console.log('Fetch error : ', err); 27 | } 28 | }); 29 | 30 | //fetch all the users from the db 31 | db.collection('Users').find().toArray().then((docs) => { 32 | // print all the users 33 | console.log(JSON.stringify(docs, undefined, 2)); 34 | }, (err) => { 35 | if(err) { 36 | return console.log('Error Fetching users : ', err); 37 | } 38 | }); 39 | 40 | //db.close(); 41 | }); -------------------------------------------------------------------------------- /mongo-rest-api/experiments/mongo-update.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {MongoClient} = require('mongodb'); 3 | 4 | MongoClient.connect('mongodb://localhost:27017/JokesApp', (err, db) => { 5 | if (err) { 6 | return console.log('error connecting to mongodb server'); 7 | } 8 | 9 | console.log('connected to mongodb server'); 10 | 11 | db.collection('Jokes').findOneAndUpdate({ 12 | joke : 'Sample joke' 13 | }, 14 | { 15 | $set : { 16 | joke : 'This was updated joke', 17 | likes : 1 18 | } 19 | }, { 20 | returnOriginal : true 21 | }).then((updatedDoc) => { 22 | console.log(updatedDoc); 23 | }, (err) => { 24 | console.log('Error updating. E: ', err); 25 | }); 26 | 27 | // display all the jokes after updating 28 | db.collection('Jokes').find().toArray().then((docs) => { 29 | console.log(docs); 30 | }, (err) => { 31 | console.log('error displaying all jokes. E: ', err); 32 | }); 33 | //db.close(); 34 | }); -------------------------------------------------------------------------------- /mongo-rest-api/experiments/mongoose-queries.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {ObjectID} = require('mongodb'); 3 | const {mongoose} = require('./../app/db/mongoose'); 4 | const {Todo} = require('./../app/models/todo'); 5 | const {User} = require('./../app/models/user'); 6 | 7 | let todoID = '5880842ef93e9523e07eece8' + '21'; 8 | let userID = '587fc1bc462a2b16144f8a07'; 9 | 10 | if (!ObjectID.isValid(todoID)) { 11 | console.log('Invalid todo ID'); 12 | } 13 | else { 14 | // Todo.find({ 15 | // _id:id 16 | // }).then((data) => { 17 | // console.log('Todos : ', data); 18 | // }, (err) => { 19 | // console.log(err); 20 | // }); 21 | 22 | // Todo.findOne({ 23 | // _id: id 24 | // }).then((data) => { 25 | // console.log('Todo : ', data); 26 | // }); 27 | 28 | Todo.findById(todoID).then((data) => { 29 | //returns todo as null in case of invalid id 30 | if (!data) { 31 | return console.log('id not found'); 32 | } 33 | console.log('Todo by findById : ', data); 34 | }).catch((err) => console.log(err)); 35 | 36 | } 37 | 38 | if (!ObjectID.isValid(userID)) { 39 | console.log('Invalid user ID'); 40 | } 41 | else { 42 | User.findById(userID).then((data) => { 43 | if (!data) { 44 | return console.log('User ID not found'); 45 | } 46 | console.log(data); 47 | }).catch((err) => console.log(err)); 48 | } -------------------------------------------------------------------------------- /mongo-rest-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongo-rest-api", 3 | "version": "0.1.0", 4 | "description": "a simple REST API", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "export NODE_ENV=test || set \"NODE_ENV=test\" && mocha app/**/*test.js", 8 | "test-watch": " nodemon --exec \"npm test\" ", 9 | "start": "node app/server.js" 10 | }, 11 | "engines" : { 12 | "node" : "6.2.2" 13 | }, 14 | "author": "Ashok Dey", 15 | "license": "MIT", 16 | "dependencies": { 17 | "bcryptjs": "^2.4.0", 18 | "body-parser": "^1.16.0", 19 | "crypto-js": "^3.1.9-1", 20 | "express": "^4.14.0", 21 | "jsonwebtoken": "^7.2.1", 22 | "lodash": "^4.17.4", 23 | "mongodb": "^2.2.21", 24 | "mongoose": "^4.7.7", 25 | "validator": "^6.2.1" 26 | }, 27 | "devDependencies": { 28 | "expect": "^1.20.2", 29 | "mocha": "^3.2.0", 30 | "nodemon": "^1.11.0", 31 | "supertest": "^2.0.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /note-taking-app/README.md: -------------------------------------------------------------------------------- 1 | #Note Taking Command Line Utility 2 | * This is a command line utility to take notes on the go 3 | * This is the third app by me while learning Node 4 | * It uses **Yargs** and **Lodash** libraries 5 | 6 | 7 | ###How to Setup? 8 | 9 | _In the terminal, type **npm install & npm start** to setup and run the application._ 10 | 11 | ###How to Use? 12 | 13 | _In the terminal, give following commands:_ 14 | * _**node note-app -add -t="Some title" -b="Some content"** to add a new note_ 15 | * _**node note-app -del -t="Some title"** to delete a new note_ 16 | * _**node note-app -view -t="Some title"** to view a new note_ 17 | * _**node note-app -list** to view all the notes_ 18 | 19 | ###Screenshot 20 | ![Screenshot](one.JPG) 21 | 22 | 23 | **You liked it? _Star it_ !** -------------------------------------------------------------------------------- /note-taking-app/note-app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const _ = require('lodash'); 5 | const yargs = require('yargs'); 6 | 7 | const noteLib = require('./note-lib'); 8 | 9 | // load the command objects for yargs 10 | const yargsOptions = fs.readFileSync('yargs-config.json'); 11 | // parse the file 12 | const options = JSON.parse(yargsOptions); 13 | 14 | const titleOptions = options.title; 15 | const bodyOptions = options.body 16 | 17 | // get command line arguments using yargs argv 18 | const argv = yargs.command('list', 'List all your notes') 19 | .command('add', 'Add a new note', { 20 | title : titleOptions, 21 | body : bodyOptions 22 | }) 23 | .command('del', 'Delete a note', { 24 | title : titleOptions 25 | }) 26 | .command('view', 'View a note', { 27 | title : titleOptions 28 | }) 29 | .help() 30 | .argv; 31 | const command = argv._[0]; 32 | //console.log(`Command given : ${command}`); 33 | 34 | if (command === 'add') 35 | { 36 | const note = noteLib.addNote(argv.title, argv.body); 37 | note ? console.log('Your note is saved.') 38 | : console.log('Title already exists! Choose a different title'); 39 | } 40 | 41 | else if (command == 'list') 42 | { 43 | let gotNotes = noteLib.getAll(); 44 | 45 | if (gotNotes) { 46 | console.log('Getting all the notes...'); 47 | 48 | //print each note 49 | for (let i in gotNotes) { 50 | noteLib.printNote(gotNotes[i]); 51 | } 52 | } 53 | else { 54 | console.log('Currently your note box is empty'); 55 | } 56 | } 57 | 58 | else if (command === 'view') 59 | { 60 | let requiredNote = noteLib.getNote(argv.title); 61 | 62 | if (requiredNote.title) { 63 | noteLib.printNote(requiredNote); 64 | } 65 | else if (requiredNote.empty) { 66 | console.log('File empty or corrupted'); 67 | } 68 | else { 69 | console.log('Note not found'); 70 | } 71 | } 72 | 73 | else if (command === 'del') 74 | { 75 | const deleted = noteLib.removeNote(argv.title); 76 | deleted ? console.log(`Note with title '${argv.title}' deleted`) 77 | : console.log ('Invalid Title! Try "node note-app --help"'); 78 | } 79 | 80 | else 81 | { 82 | console.log('Invalid Command. Try Again!'); 83 | } -------------------------------------------------------------------------------- /note-taking-app/note-lib.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | /* 6 | -----------------Functions not to be exported ------------------ 7 | */ 8 | 9 | let fetchNotes = () => 10 | { 11 | try { 12 | // if the file already exixsts, read all the contents from it 13 | // use Sync version so that work is synchronized 14 | let notesData = fs.readFileSync('./storage/notes-data.json'); 15 | 16 | // parse that string into the notes array and return 17 | return JSON.parse(notesData); 18 | } 19 | catch (error) 20 | { 21 | 22 | // in case of missing/corrupt file 23 | console.log("Creating storage"); 24 | } 25 | } 26 | 27 | 28 | let saveNote = (notes) => 29 | { 30 | // write to file after converting to a string 31 | // use Sync version so that work is synchronized 32 | fs.writeFileSync('./storage/notes-data.json', JSON.stringify(notes)); 33 | } 34 | 35 | /* 36 | -----------------Functions to be exported ------------------ 37 | */ 38 | 39 | let addNote = (title, body) => 40 | { 41 | //fetch notes if already exixts 42 | let notes = fetchNotes(); 43 | 44 | if (notes == undefined) { 45 | notes = []; 46 | } 47 | 48 | // creating the note object using es6 syntax 49 | let note = { 50 | title, // similar to title:title bcoz both names are same 51 | body 52 | }; 53 | 54 | // check whether title already exixsts 55 | // filter will return an array containig true for duplicate 56 | // titles, if length of array is 0, no duplicates exixts 57 | let duplicateTitle = notes.filter((note) => note.title === title) 58 | 59 | if (duplicateTitle.length == 0) 60 | { 61 | // if the title do not exixsts in the storage, push the data in 62 | // push the new note into the notes array 63 | notes.push(note); 64 | 65 | // save the notes array into storage 66 | saveNote(notes); 67 | 68 | //return the note 69 | return note; 70 | } 71 | } 72 | 73 | 74 | let getAll = () => 75 | { 76 | // return all the notes 77 | return fetchNotes(); 78 | } 79 | 80 | 81 | let getNote = (title) => { 82 | // fetch the notes 83 | let notes = fetchNotes(); 84 | 85 | // check if the notes available or not 86 | if (notes) { 87 | let requiredNote = notes.filter((note) => note.title == title); 88 | 89 | if (requiredNote[0]){ 90 | return requiredNote[0]; 91 | } 92 | else { 93 | return {title:false} 94 | } 95 | } 96 | else { 97 | return {empty: true}; 98 | } 99 | } 100 | 101 | let removeNote = (title) => { 102 | // fetch the notes from storage 103 | let notes = fetchNotes(); 104 | 105 | //fileter the notes using filer 106 | let newNotes = notes.filter((note) => note.title !== title); 107 | 108 | //save new notes in storage 109 | saveNote(newNotes); 110 | 111 | return !(notes.length === newNotes.length); 112 | } 113 | 114 | let printNote = (note) => { 115 | let noteContents = 116 | `------\n${note.title}\n${note.body}\n` 117 | console.log(noteContents) 118 | } 119 | 120 | /* 121 | -------------------Exporting functions ----------------- 122 | */ 123 | 124 | module.exports = { 125 | addNote, 126 | getNote, 127 | getAll, 128 | removeNote, 129 | printNote 130 | } -------------------------------------------------------------------------------- /note-taking-app/notes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | /* 6 | -----------------Functions not to be exported ------------------ 7 | */ 8 | 9 | let fetchNotes = () => 10 | { 11 | try { 12 | // if the file already exixsts, read all the contents from it 13 | // use Sync version so that work is synchronized 14 | let notesData = fs.readFileSync('./storage/notes-data.json'); 15 | 16 | // parse that string into the notes array and return 17 | return JSON.parse(notesData); 18 | } 19 | catch (error) 20 | { 21 | 22 | // in case of missing/corrupt file 23 | console.log("Creating storage"); 24 | } 25 | } 26 | 27 | 28 | let saveNote = (notes) => 29 | { 30 | // write to file after converting to a string 31 | // use Sync version so that work is synchronized 32 | fs.writeFileSync('./storage/notes-data.json', JSON.stringify(notes)); 33 | } 34 | 35 | /* 36 | -----------------Functions to be exported ------------------ 37 | */ 38 | 39 | let addNote = (title, body) => 40 | { 41 | //fetch notes if already exixts 42 | let notes = fetchNotes(); 43 | 44 | if (notes == undefined) { 45 | notes = []; 46 | } 47 | 48 | // creating the note object using es6 syntax 49 | let note = { 50 | title, // similar to title:title bcoz both names are same 51 | body 52 | }; 53 | 54 | // check whether title already exixsts 55 | // filter will return an array containig true for duplicate 56 | // titles, if length of array is 0, no duplicates exixts 57 | let duplicateTitle = notes.filter((note) => note.title === title) 58 | 59 | if (duplicateTitle.length == 0) 60 | { 61 | // if the title do not exixsts in the storage, push the data in 62 | // push the new note into the notes array 63 | notes.push(note); 64 | 65 | // save the notes array into storage 66 | saveNote(notes); 67 | 68 | //return the note 69 | return note; 70 | } 71 | } 72 | 73 | 74 | let getAll = () => 75 | { 76 | // return all the notes 77 | return fetchNotes(); 78 | } 79 | 80 | 81 | let getNote = (title) => { 82 | // fetch the notes 83 | let notes = fetchNotes(); 84 | 85 | // check if the notes available or not 86 | if (notes) { 87 | let requiredNote = notes.filter((note) => note.title == title); 88 | return requiredNote[0]; 89 | } 90 | else { 91 | return { 92 | empty: true 93 | }; 94 | } 95 | } 96 | 97 | let removeNote = (title) => { 98 | // fetch the notes from storage 99 | let notes = fetchNotes(); 100 | 101 | //fileter the notes using filer 102 | let newNotes = notes.filter((note) => note.title !== title); 103 | 104 | //save new notes in storage 105 | saveNote(newNotes); 106 | 107 | return !(notes.length === newNotes.length); 108 | } 109 | 110 | let printNote = (note) => { 111 | let noteContents = 112 | `------\n${note.title}\n${note.body}\n` 113 | console.log(noteContents) 114 | } 115 | 116 | /* 117 | -------------------Exporting functions ----------------- 118 | */ 119 | 120 | module.exports = { 121 | addNote, 122 | getNote, 123 | getAll, 124 | removeNote, 125 | printNote 126 | } -------------------------------------------------------------------------------- /note-taking-app/one.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/note-taking-app/one.JPG -------------------------------------------------------------------------------- /note-taking-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "note-taking-app", 3 | "version": "0.1.0", 4 | "description": "simple note taking app", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node note-app --help", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Ashok Dey", 11 | "license": "MIT", 12 | "dependencies": { 13 | "lodash": "^4.17.4", 14 | "yargs": "^4.7.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /note-taking-app/storage/notes-data.json: -------------------------------------------------------------------------------- 1 | [{"title":"Test 2","body":"Sample test 1"},{"title":"Test 1","body":"testing 1 2 3..."}] -------------------------------------------------------------------------------- /note-taking-app/yargs-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title" : { 3 | "describe" : "Title of the note", 4 | "demand": "true", 5 | "alias" : "t" 6 | }, 7 | 8 | "body" : { 9 | "describe" : "The content of your note", 10 | "demand" : "true", 11 | "alias" : "b" 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /registration-login/app/configs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let environment = process.env.NODE_ENV || 'development'; 3 | 4 | if (environment === 'development') { 5 | process.env.PORT = 5000; 6 | process.env.MONGODB_URI = 'mongodb://127.0.0.1:27017/login-register'; 7 | } 8 | else if (environment === 'test') { 9 | process.env.PORT = 5000; 10 | process.env.MONGODB_URI = 'mongodb://127.0.0.1:27017/login-register-test'; 11 | } -------------------------------------------------------------------------------- /registration-login/app/db/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const mongoose = require('mongoose'); 3 | 4 | // set mongoose to use promises 5 | mongoose.Promise = global.Promise; 6 | 7 | // connect to the database 8 | mongoose.connect(process.env.MONGODB_URI); 9 | 10 | // export mongoose 11 | module.exports = {mongoose}; -------------------------------------------------------------------------------- /registration-login/app/models/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mongoose = require('mongoose'); 4 | const validator = require('validator'); 5 | const passportLocalMongoose = require('passport-local-mongoose'); 6 | // create the User model 7 | let UserSchema = new mongoose.Schema({ 8 | username : { 9 | type : String, 10 | minlength : 5, 11 | trim : true, 12 | required : true, 13 | validate : { 14 | validator : validator.isEmail, 15 | message : '{value} is not a valid email' 16 | } 17 | }, 18 | password : { 19 | type : String, 20 | minlength : 6, 21 | trim : true, 22 | }, 23 | _createdAt : { 24 | type : Number, 25 | required : true 26 | } 27 | }); 28 | 29 | // add the passport mongoose plugin 30 | UserSchema.plugin(passportLocalMongoose); 31 | 32 | let User = mongoose.model('User', UserSchema); 33 | 34 | module.exports = {User}; -------------------------------------------------------------------------------- /registration-login/app/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // impoort the configs 4 | const configs = require('./configs'); 5 | 6 | // npm and node modules here 7 | const path = require('path'); 8 | const express = require('express'); 9 | const expressSession = require('express-session'); 10 | const bodyParser = require('body-parser'); 11 | const ejs = require('ejs'); 12 | const passport = require('passport'); 13 | const LocalStrategy = require('passport-local'); 14 | const passportLocalMongoose = require('passport-local-mongoose'); 15 | 16 | // custom modules here 17 | const db = require('./db'); 18 | const {User} = require('./models/user'); 19 | 20 | //create the app 21 | const app = express(); 22 | //set the port 23 | const port = process.env.PORT; 24 | 25 | // MIDDLEWARES here 26 | 27 | // use the express session 28 | app.use(expressSession({ 29 | secret : 'this is just a demo test', 30 | resave : false, 31 | saveUninitialized : false 32 | })); 33 | 34 | // use passport and passport sessions 35 | app.use(passport.initialize()); 36 | app.use(passport.session()); 37 | 38 | // use body parser 39 | app.use(bodyParser.urlencoded({extended : true})); 40 | 41 | // SETTINGS here 42 | 43 | // set the views 44 | app.set('view engine', 'ejs'); 45 | // set the views folder {because my views are inside /app folder} 46 | app.set('views', path.join(__dirname, '/views')); 47 | // set the static directory 48 | app.use(express.static(__dirname + '/_public')); 49 | 50 | // passport serialize and deserialize 51 | 52 | // use this form of code if you have your input fields are named other than usernam and password 53 | // passport.use(new LocalStrategy({ 54 | // usernameField:'user[username]', 55 | // passwordField:'user[password]' 56 | // }, 57 | // User.authenticate())); 58 | 59 | passport.use(new LocalStrategy(User.authenticate())); 60 | passport.serializeUser(User.serializeUser()); 61 | passport.deserializeUser(User.deserializeUser()); 62 | 63 | // custom middlewares 64 | let isLoggedIn = (req, res, next) => { 65 | if(req.isAuthenticated()) { 66 | return next(); 67 | } 68 | res.redirect('/'); 69 | } 70 | 71 | // ROUTES here 72 | 73 | app.get('/', (req, res) => { 74 | res.render('home'); 75 | }); 76 | 77 | 78 | app.get('/secret',isLoggedIn, (req, res) => { 79 | 80 | res.render('secret'); 81 | }); 82 | 83 | app.get('/register', (req, res) => { 84 | res.render('register'); 85 | }); 86 | 87 | app.post('/register', (req, res) => { 88 | // register the user 89 | User.register(new User({ 90 | username : req.body.username, 91 | _createdAt : new Date().getTime() 92 | }), req.body.password, (err, user) => { 93 | if(err) { 94 | console.log(err); 95 | return res.render('register'); 96 | } 97 | passport.authenticate('local')(req, res, function(){ 98 | console.log('inside passport.authenticate : 80'); 99 | res.redirect('/secret'); 100 | }); 101 | }); 102 | }); 103 | 104 | app.get('/login', (req, res) => { 105 | res.render('login'); 106 | }); 107 | 108 | app.post('/login',passport.authenticate('local', { 109 | successRedirect : '/secret', 110 | failureRedirect : '/login' 111 | }),(req, res) => { 112 | }); 113 | 114 | app.get('/logout', (req, res) => { 115 | req.logOut(); 116 | res.redirect('/'); 117 | }); 118 | 119 | // listen to the port 120 | app.listen(port, () => { 121 | console.log('server started...'); 122 | }) -------------------------------------------------------------------------------- /registration-login/app/views/home.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |
9 |

Welcome to Home Page

10 |

11 | New user? Register. 12 |

13 | Login 14 | 15 | 16 | -------------------------------------------------------------------------------- /registration-login/app/views/login.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |
9 |

Welcome to Home Page

10 |

11 |
12 | Email :

13 | Password :

14 |

15 | New user? Register. 16 |
17 | 18 | -------------------------------------------------------------------------------- /registration-login/app/views/register.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |
9 |

Welcome to Home Page

10 |

11 |
12 | Email :

13 | Password :

14 | Password Again :

15 |

16 | Already registered? Login. 17 |
18 | 19 | -------------------------------------------------------------------------------- /registration-login/app/views/secret.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

9 |

Welcome to the secret page

10 |
11 |
12 |
13 |
14 |
15 | Logout 16 | 17 | -------------------------------------------------------------------------------- /registration-login/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "registration-login", 3 | "version": "1.0.0", 4 | "description": "Learning reg-login system", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Ashok Dey", 10 | "license": "MIT", 11 | "dependencies": { 12 | "body-parser": "^1.16.0", 13 | "ejs": "^2.5.5", 14 | "express": "^4.14.1", 15 | "express-session": "^1.15.0", 16 | "mongoose": "^4.8.1", 17 | "passport": "^0.3.2", 18 | "passport-local": "^1.0.0", 19 | "passport-local-mongoose": "^4.0.0", 20 | "validator": "^6.2.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /simple-website/README.md: -------------------------------------------------------------------------------- 1 | #Simple NodeJS Website 2 | * This is the fifth app by me while learning Node 3 | * It uses **Express** and **Handlebars(hbs)** as templating engine, **MaterializeCSS** for CSS 4 | * It includes the header and footer from the **views/partials** folder 5 | * It also shows a 404 page in case of invalid urls 6 | * It logs the requests and timestamp in the **server.log** file located in **logs** folder 7 | 8 | ###How to Setup and Run? 9 | 10 | * _In the terminal, type **npm install & npm start** to setup and run the server first_ 11 | * _Open your favourite browser, type **localhost:5000"**_ 12 | 13 | ###Screenshots 14 | 15 | **_Main Page_** 16 | 17 | ![Main Page](screenshot-1.JPG) 18 |
19 | 20 | **_404 Page_** 21 | 22 | ![404 Page](screenshot-2.JPG) 23 | 24 | ###See maintaniance in action 25 | 26 | _Remove the comments in the line number 26-28 in **serve.js** to see the maintainance state of the app_ 27 | 28 | ###Uses 29 | * You can use if for serve the static pages of your website 30 | * You can setup the routes in the **server.js** file according to your needs for the above purpose. 31 | 32 | **You liked it? _Star it_ !** 33 | -------------------------------------------------------------------------------- /simple-website/logs/server.log: -------------------------------------------------------------------------------- 1 | Sat Jan 07 2017 19:56:50 GMT+0530 (India Standard Time) GET / 2 | Sat Jan 07 2017 19:56:58 GMT+0530 (India Standard Time) GET / 3 | Sat Jan 07 2017 19:57:16 GMT+0530 (India Standard Time) GET / 4 | Sat Jan 07 2017 19:57:29 GMT+0530 (India Standard Time) GET /about 5 | Sat Jan 07 2017 19:57:57 GMT+0530 (India Standard Time) GET /about 6 | Sat Jan 07 2017 19:59:07 GMT+0530 (India Standard Time) GET /about 7 | Sat Jan 07 2017 20:09:50 GMT+0530 (India Standard Time) GET /about 8 | Sat Jan 07 2017 20:12:02 GMT+0530 (India Standard Time) GET /about 9 | Sat Jan 07 2017 20:12:04 GMT+0530 (India Standard Time) GET /about 10 | Sat Jan 07 2017 20:12:15 GMT+0530 (India Standard Time) GET /bad 11 | Sat Jan 07 2017 20:12:27 GMT+0530 (India Standard Time) GET / 12 | Sat Jan 07 2017 20:12:37 GMT+0530 (India Standard Time) GET / 13 | Sat Jan 07 2017 20:12:38 GMT+0530 (India Standard Time) GET / 14 | Sat Jan 07 2017 20:12:38 GMT+0530 (India Standard Time) GET / 15 | Sat Jan 07 2017 20:12:38 GMT+0530 (India Standard Time) GET / 16 | Sat Jan 07 2017 20:12:39 GMT+0530 (India Standard Time) GET / 17 | Sat Jan 07 2017 20:12:39 GMT+0530 (India Standard Time) GET / 18 | Sat Jan 07 2017 20:12:39 GMT+0530 (India Standard Time) GET / 19 | Sat Jan 07 2017 20:12:39 GMT+0530 (India Standard Time) GET / 20 | Sat Jan 07 2017 20:13:00 GMT+0530 (India Standard Time) GET / 21 | Sat Jan 07 2017 20:13:01 GMT+0530 (India Standard Time) GET / 22 | Sat Jan 07 2017 20:13:01 GMT+0530 (India Standard Time) GET / 23 | Sat Jan 07 2017 20:13:02 GMT+0530 (India Standard Time) GET / 24 | Sat Jan 07 2017 20:13:02 GMT+0530 (India Standard Time) GET / 25 | Sat Jan 07 2017 20:13:02 GMT+0530 (India Standard Time) GET / 26 | Sat Jan 07 2017 20:13:02 GMT+0530 (India Standard Time) GET / 27 | Sat Jan 07 2017 20:13:03 GMT+0530 (India Standard Time) GET / 28 | Sat Jan 07 2017 20:13:16 GMT+0530 (India Standard Time) GET / 29 | Sat Jan 07 2017 20:25:46 GMT+0530 (India Standard Time) GET / 30 | Sat Jan 07 2017 20:25:58 GMT+0530 (India Standard Time) GET /about 31 | Sat Jan 07 2017 20:26:02 GMT+0530 (India Standard Time) GET /bad 32 | Sat Jan 07 2017 20:26:05 GMT+0530 (India Standard Time) GET / 33 | Sat Jan 07 2017 21:10:30 GMT+0530 (India Standard Time) GET /rer 34 | Sat Jan 07 2017 21:10:40 GMT+0530 (India Standard Time) GET / 35 | Sat Jan 07 2017 21:11:14 GMT+0530 (India Standard Time) GET / 36 | Sat Jan 07 2017 21:11:18 GMT+0530 (India Standard Time) GET /ew 37 | Sat Jan 07 2017 21:14:51 GMT+0530 (India Standard Time) GET /ew 38 | Sat Jan 07 2017 21:29:31 GMT+0530 (India Standard Time) GET / 39 | Sat Jan 07 2017 21:29:37 GMT+0530 (India Standard Time) GET / 40 | Sat Jan 07 2017 21:29:52 GMT+0530 (India Standard Time) GET /about 41 | Sat Jan 07 2017 21:42:39 GMT+0530 (India Standard Time) GET / 42 | Sat Jan 07 2017 21:42:39 GMT+0530 (India Standard Time) GET /css/materialize.min.css 43 | Sat Jan 07 2017 21:42:40 GMT+0530 (India Standard Time) GET /favicon.ico 44 | Sat Jan 07 2017 21:43:29 GMT+0530 (India Standard Time) GET / 45 | Sat Jan 07 2017 21:43:29 GMT+0530 (India Standard Time) GET /css/materialize.min.css 46 | Sat Jan 07 2017 21:43:29 GMT+0530 (India Standard Time) GET /favicon.ico 47 | Sat Jan 07 2017 21:43:31 GMT+0530 (India Standard Time) GET / 48 | Sat Jan 07 2017 21:43:31 GMT+0530 (India Standard Time) GET /css/materialize.min.css 49 | Sat Jan 07 2017 21:43:32 GMT+0530 (India Standard Time) GET /favicon.ico 50 | Sat Jan 07 2017 21:43:33 GMT+0530 (India Standard Time) GET / 51 | Sat Jan 07 2017 21:43:33 GMT+0530 (India Standard Time) GET /css/materialize.min.css 52 | Sat Jan 07 2017 21:43:33 GMT+0530 (India Standard Time) GET /favicon.ico 53 | Sat Jan 07 2017 21:43:37 GMT+0530 (India Standard Time) GET /css/materialize.min.css 54 | Sat Jan 07 2017 21:43:59 GMT+0530 (India Standard Time) GET / 55 | Sat Jan 07 2017 21:43:59 GMT+0530 (India Standard Time) GET /css/materialize.min.css 56 | Sat Jan 07 2017 21:43:59 GMT+0530 (India Standard Time) GET /favicon.ico 57 | Sat Jan 07 2017 21:44:05 GMT+0530 (India Standard Time) GET / 58 | Sat Jan 07 2017 21:44:05 GMT+0530 (India Standard Time) GET /css/materialize.min.css 59 | Sat Jan 07 2017 21:44:06 GMT+0530 (India Standard Time) GET /favicon.ico 60 | Sat Jan 07 2017 21:44:23 GMT+0530 (India Standard Time) GET / 61 | Sat Jan 07 2017 21:44:23 GMT+0530 (India Standard Time) GET /css/materialize.min.css 62 | Sat Jan 07 2017 21:44:24 GMT+0530 (India Standard Time) GET /favicon.ico 63 | Sat Jan 07 2017 21:46:16 GMT+0530 (India Standard Time) GET / 64 | Sat Jan 07 2017 21:46:16 GMT+0530 (India Standard Time) GET /css/materialize.min.css 65 | Sat Jan 07 2017 21:46:16 GMT+0530 (India Standard Time) GET /favicon.ico 66 | Sat Jan 07 2017 21:46:23 GMT+0530 (India Standard Time) GET / 67 | Sat Jan 07 2017 21:46:23 GMT+0530 (India Standard Time) GET /css/materialize.min.css 68 | Sat Jan 07 2017 21:46:23 GMT+0530 (India Standard Time) GET /favicon.ico 69 | Sat Jan 07 2017 21:46:27 GMT+0530 (India Standard Time) GET /css/materialize.min.css 70 | Sat Jan 07 2017 21:48:33 GMT+0530 (India Standard Time) GET / 71 | Sat Jan 07 2017 21:48:33 GMT+0530 (India Standard Time) GET /css/materialize.min.css 72 | Sat Jan 07 2017 21:48:34 GMT+0530 (India Standard Time) GET /favicon.ico 73 | Sat Jan 07 2017 21:48:35 GMT+0530 (India Standard Time) GET / 74 | Sat Jan 07 2017 21:48:35 GMT+0530 (India Standard Time) GET /css/materialize.min.css 75 | Sat Jan 07 2017 21:48:36 GMT+0530 (India Standard Time) GET /favicon.ico 76 | Sat Jan 07 2017 21:48:38 GMT+0530 (India Standard Time) GET / 77 | Sat Jan 07 2017 21:48:38 GMT+0530 (India Standard Time) GET /css/materialize.min.css 78 | Sat Jan 07 2017 21:48:38 GMT+0530 (India Standard Time) GET /favicon.ico 79 | Sat Jan 07 2017 21:48:54 GMT+0530 (India Standard Time) GET / 80 | Sat Jan 07 2017 21:48:54 GMT+0530 (India Standard Time) GET /css/materialize.min.css 81 | Sat Jan 07 2017 21:48:55 GMT+0530 (India Standard Time) GET /favicon.ico 82 | Sat Jan 07 2017 21:49:20 GMT+0530 (India Standard Time) GET / 83 | Sat Jan 07 2017 21:49:22 GMT+0530 (India Standard Time) GET /favicon.ico 84 | Sat Jan 07 2017 21:50:44 GMT+0530 (India Standard Time) GET / 85 | Sat Jan 07 2017 21:50:45 GMT+0530 (India Standard Time) GET /favicon.ico 86 | Sat Jan 07 2017 21:51:14 GMT+0530 (India Standard Time) GET /about 87 | Sat Jan 07 2017 21:51:15 GMT+0530 (India Standard Time) GET /favicon.ico 88 | Sat Jan 07 2017 21:51:51 GMT+0530 (India Standard Time) GET /about 89 | Sat Jan 07 2017 21:51:52 GMT+0530 (India Standard Time) GET /favicon.ico 90 | Sat Jan 07 2017 21:52:54 GMT+0530 (India Standard Time) GET /about 91 | Sat Jan 07 2017 21:52:54 GMT+0530 (India Standard Time) GET /favicon.ico 92 | Sat Jan 07 2017 21:52:56 GMT+0530 (India Standard Time) GET /about 93 | Sat Jan 07 2017 21:52:56 GMT+0530 (India Standard Time) GET /favicon.ico 94 | Sat Jan 07 2017 21:53:04 GMT+0530 (India Standard Time) GET /about 95 | Sat Jan 07 2017 21:53:04 GMT+0530 (India Standard Time) GET /favicon.ico 96 | Sat Jan 07 2017 21:53:16 GMT+0530 (India Standard Time) GET /about 97 | Sat Jan 07 2017 21:53:17 GMT+0530 (India Standard Time) GET /favicon.ico 98 | Sat Jan 07 2017 21:54:06 GMT+0530 (India Standard Time) GET /about 99 | Sat Jan 07 2017 21:54:06 GMT+0530 (India Standard Time) GET /favicon.ico 100 | Sat Jan 07 2017 21:54:14 GMT+0530 (India Standard Time) GET /about 101 | Sat Jan 07 2017 21:54:14 GMT+0530 (India Standard Time) GET /favicon.ico 102 | Sat Jan 07 2017 21:54:20 GMT+0530 (India Standard Time) GET /about 103 | Sat Jan 07 2017 21:54:21 GMT+0530 (India Standard Time) GET /favicon.ico 104 | Sat Jan 07 2017 21:54:21 GMT+0530 (India Standard Time) GET /about 105 | Sat Jan 07 2017 21:54:21 GMT+0530 (India Standard Time) GET /favicon.ico 106 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /about 107 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /favicon.ico 108 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /about 109 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /favicon.ico 110 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /about 111 | Sat Jan 07 2017 21:54:22 GMT+0530 (India Standard Time) GET /favicon.ico 112 | Sat Jan 07 2017 21:54:44 GMT+0530 (India Standard Time) GET /about 113 | Sat Jan 07 2017 21:54:44 GMT+0530 (India Standard Time) GET /favicon.ico 114 | Sat Jan 07 2017 21:54:46 GMT+0530 (India Standard Time) GET /about 115 | Sat Jan 07 2017 21:54:46 GMT+0530 (India Standard Time) GET /favicon.ico 116 | Sat Jan 07 2017 21:54:46 GMT+0530 (India Standard Time) GET /about 117 | Sat Jan 07 2017 21:54:47 GMT+0530 (India Standard Time) GET /favicon.ico 118 | Sat Jan 07 2017 21:54:47 GMT+0530 (India Standard Time) GET /about 119 | Sat Jan 07 2017 21:54:47 GMT+0530 (India Standard Time) GET /favicon.ico 120 | Sat Jan 07 2017 21:54:47 GMT+0530 (India Standard Time) GET /about 121 | Sat Jan 07 2017 21:54:47 GMT+0530 (India Standard Time) GET /favicon.ico 122 | Sat Jan 07 2017 21:55:20 GMT+0530 (India Standard Time) GET /about 123 | Sat Jan 07 2017 21:55:21 GMT+0530 (India Standard Time) GET /favicon.ico 124 | Sat Jan 07 2017 21:55:28 GMT+0530 (India Standard Time) GET / 125 | Sat Jan 07 2017 21:55:29 GMT+0530 (India Standard Time) GET /favicon.ico 126 | Sat Jan 07 2017 21:55:32 GMT+0530 (India Standard Time) GET /about 127 | Sat Jan 07 2017 21:55:32 GMT+0530 (India Standard Time) GET /favicon.ico 128 | Sat Jan 07 2017 21:55:34 GMT+0530 (India Standard Time) GET /bad 129 | Sat Jan 07 2017 21:55:34 GMT+0530 (India Standard Time) GET /favicon.ico 130 | Sat Jan 07 2017 21:55:37 GMT+0530 (India Standard Time) GET /favicon.ico 131 | Sat Jan 07 2017 21:55:40 GMT+0530 (India Standard Time) GET / 132 | Sat Jan 07 2017 21:55:40 GMT+0530 (India Standard Time) GET /favicon.ico 133 | Sat Jan 07 2017 21:56:43 GMT+0530 (India Standard Time) GET / 134 | Sat Jan 07 2017 21:56:46 GMT+0530 (India Standard Time) GET /favicon.ico 135 | Sat Jan 07 2017 21:57:30 GMT+0530 (India Standard Time) GET / 136 | Sat Jan 07 2017 21:57:30 GMT+0530 (India Standard Time) GET /favicon.ico 137 | Sat Jan 07 2017 21:57:36 GMT+0530 (India Standard Time) GET /about 138 | Sat Jan 07 2017 21:57:36 GMT+0530 (India Standard Time) GET /favicon.ico 139 | Sat Jan 07 2017 21:59:15 GMT+0530 (India Standard Time) GET / 140 | Sat Jan 07 2017 21:59:16 GMT+0530 (India Standard Time) GET /favicon.ico 141 | Sat Jan 07 2017 22:05:03 GMT+0530 (India Standard Time) GET / 142 | Sat Jan 07 2017 22:05:03 GMT+0530 (India Standard Time) GET /favicon.ico 143 | Sat Jan 07 2017 22:05:10 GMT+0530 (India Standard Time) GET / 144 | Sat Jan 07 2017 22:05:10 GMT+0530 (India Standard Time) GET /favicon.ico 145 | Sat Jan 07 2017 22:05:11 GMT+0530 (India Standard Time) GET /about 146 | Sat Jan 07 2017 22:05:12 GMT+0530 (India Standard Time) GET /favicon.ico 147 | Sat Jan 07 2017 22:05:16 GMT+0530 (India Standard Time) GET /aboutwq 148 | Sat Jan 07 2017 22:05:16 GMT+0530 (India Standard Time) GET /favicon.ico 149 | Sat Jan 07 2017 22:05:23 GMT+0530 (India Standard Time) GET / 150 | Sat Jan 07 2017 22:05:23 GMT+0530 (India Standard Time) GET /favicon.ico 151 | Sat Jan 07 2017 22:07:38 GMT+0530 (India Standard Time) GET / 152 | Sat Jan 07 2017 22:07:39 GMT+0530 (India Standard Time) GET /favicon.ico 153 | Sat Jan 07 2017 22:07:45 GMT+0530 (India Standard Time) GET / 154 | Sat Jan 07 2017 22:07:45 GMT+0530 (India Standard Time) GET /favicon.ico 155 | Sat Jan 07 2017 22:07:47 GMT+0530 (India Standard Time) GET /about 156 | Sat Jan 07 2017 22:07:47 GMT+0530 (India Standard Time) GET /favicon.ico 157 | Sat Jan 07 2017 22:07:48 GMT+0530 (India Standard Time) GET /bad 158 | Sat Jan 07 2017 22:07:48 GMT+0530 (India Standard Time) GET /favicon.ico 159 | Sat Jan 07 2017 22:07:49 GMT+0530 (India Standard Time) GET / 160 | Sat Jan 07 2017 22:07:50 GMT+0530 (India Standard Time) GET /favicon.ico 161 | Sat Jan 07 2017 22:07:51 GMT+0530 (India Standard Time) GET /about 162 | Sat Jan 07 2017 22:07:51 GMT+0530 (India Standard Time) GET /favicon.ico 163 | Sat Jan 07 2017 22:07:52 GMT+0530 (India Standard Time) GET /bad 164 | Sat Jan 07 2017 22:07:52 GMT+0530 (India Standard Time) GET /favicon.ico 165 | Sat Jan 07 2017 22:07:53 GMT+0530 (India Standard Time) GET / 166 | Sat Jan 07 2017 22:07:53 GMT+0530 (India Standard Time) GET /favicon.ico 167 | Mon Jan 09 2017 16:09:28 GMT+0530 (India Standard Time) GET / 168 | Mon Jan 09 2017 16:09:29 GMT+0530 (India Standard Time) GET /favicon.ico 169 | Mon Jan 09 2017 16:11:10 GMT+0530 (India Standard Time) GET / 170 | Mon Jan 09 2017 16:11:11 GMT+0530 (India Standard Time) GET /favicon.ico 171 | Mon Jan 09 2017 16:11:24 GMT+0530 (India Standard Time) GET /about 172 | Mon Jan 09 2017 16:11:24 GMT+0530 (India Standard Time) GET /favicon.ico 173 | Mon Jan 09 2017 16:11:41 GMT+0530 (India Standard Time) GET /aboutzxer325 174 | Mon Jan 09 2017 16:11:41 GMT+0530 (India Standard Time) GET /favicon.ico 175 | Mon Jan 09 2017 16:12:12 GMT+0530 (India Standard Time) GET /bad 176 | Mon Jan 09 2017 16:12:13 GMT+0530 (India Standard Time) GET /favicon.ico 177 | Mon Jan 09 2017 16:13:15 GMT+0530 (India Standard Time) GET /favicon.ico 178 | Mon Jan 09 2017 16:13:17 GMT+0530 (India Standard Time) GET / 179 | Mon Jan 09 2017 16:13:17 GMT+0530 (India Standard Time) GET /favicon.ico 180 | -------------------------------------------------------------------------------- /simple-website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-dynamic-site", 3 | "version": "0.1.0", 4 | "description": "simple dynamic site using node and hbs", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "Ashok Dey", 11 | "license": "MIT", 12 | "dependencies": { 13 | "express": "^4.14.0", 14 | "hbs": "^4.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /simple-website/screenshot-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/screenshot-1.JPG -------------------------------------------------------------------------------- /simple-website/screenshot-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/screenshot-2.JPG -------------------------------------------------------------------------------- /simple-website/server.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const express = require('express'); 4 | const hbs = require('hbs'); 5 | const fs = require('fs'); 6 | 7 | const app = express(); 8 | 9 | hbs.registerPartials(__dirname + '/views/partials'); 10 | 11 | //creating a middleware 12 | app.use((req, res, next) => { 13 | //get current time 14 | let timestamp = new Date().toString(); 15 | let data = `${timestamp} ${req.method} ${req.url}\n`; 16 | console.log(data); 17 | fs.appendFile('./logs/server.log', data, (err) => { 18 | if (err) { 19 | console.log('Erroe logging data to file'); 20 | } 21 | }) 22 | next(); 23 | }); 24 | 25 | // remove the comments for maintainance 26 | //app.use((req, res, next) => { 27 | // res.render('maintainance.hbs'); 28 | //}); 29 | 30 | hbs.registerHelper('getCurrentYear', () => { 31 | return new Date().getFullYear(); 32 | }); 33 | 34 | hbs.registerHelper('toUpper', (text) => { 35 | return text.toUpperCase(); 36 | }); 37 | 38 | //set the views template engine 39 | app.set('view engine', 'hbs'); 40 | 41 | 42 | app.get('/', (req, res) => { 43 | res.render('home.hbs', { 44 | pageTitle : 'Welcome to my Page', 45 | message : 'This is made using node', 46 | }) 47 | }) 48 | 49 | app.get('/about', (req, res) => { 50 | res.render('about.hbs', { 51 | pageTitle : 'About Page', 52 | }); 53 | }); 54 | 55 | app.get('/api', (req, res) => { 56 | res.send({ 57 | status : 400, 58 | errorMessage : 'bad_request' 59 | }); 60 | }); 61 | 62 | //in case of invalid urls 63 | app.get('*', (req, res) => { 64 | res.render('404.hbs', { 65 | pageTitle: '404 Not found' 66 | }); 67 | }); 68 | 69 | app.listen(5000, () => { 70 | console.log("Server Running at port number: 5000"); 71 | }); 72 | -------------------------------------------------------------------------------- /simple-website/views/404.hbs: -------------------------------------------------------------------------------- 1 | {{>header}} 2 |
3 |
4 |
5 |
6 |
7 | Not Found! 8 |

The URL you are trying to access is either broken or invalid.

9 |
10 |
11 | Back to Home 12 | About Us 13 |
14 |
15 |
16 |
17 |
18 | {{>footer}} -------------------------------------------------------------------------------- /simple-website/views/about.hbs: -------------------------------------------------------------------------------- 1 | {{>header}} 2 |

{{toUpper pageTitle}}

3 | This is the about page. 4 | {{>footer}} 5 | -------------------------------------------------------------------------------- /simple-website/views/home.hbs: -------------------------------------------------------------------------------- 1 | {{>header}} 2 |

3 |

{{toUpper message}}

4 |
5 |
6 |
7 |
8 | Card Title 9 |

I am a very simple card. I am good at containing small bits of information. 10 | I am convenient because I require little markup to use effectively.

11 |
12 | 16 |
17 |
18 |
19 | {{>footer}} 20 | -------------------------------------------------------------------------------- /simple-website/views/maintainance.hbs: -------------------------------------------------------------------------------- 1 | {{>header}} 2 |

3 |

warningWe are under maintainance! Please visit after sometime

4 | {{>footer}} -------------------------------------------------------------------------------- /simple-website/views/partials/footer.hbs: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /simple-website/views/partials/header.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{pageTitle}} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 25 | -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/css/materialize.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Materialize v0.97.8 (http://materializecss.com) 3 | * Copyright 2014-2015 Materialize 4 | * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) 5 | */ 6 | .materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default) li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.valign-wrapper .valign{display:block}.clearfix{clear:both}.z-depth-0{box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-floating,.dropdown-content,.collapsible,.side-nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 1px 5px 0 rgba(0,0,0,0.12),0 3px 1px -2px rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-floating:hover{box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{box-shadow:0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.3)}.z-depth-4,.modal{box-shadow:0 8px 10px 1px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.3)}.z-depth-5{box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -5px rgba(0,0,0,0.3)}.hoverable{transition:box-shadow .25s;box-shadow:0}.hoverable:hover{transition:box-shadow .25s;box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax img{display:none;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}footer.page-footer{margin-top:20px;padding-top:20px;background-color:#ee6e73}footer.page-footer .footer-copyright{overflow:hidden;height:50px;line-height:50px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table}table.bordered>thead>tr,table.bordered>tbody>tr{border-bottom:1px solid #d0d0d0}table.striped>tbody>tr:nth-child(odd){background-color:#f2f2f2}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:#f2f2f2}table.centered thead tr th,table.centered tbody tr td{text-align:center}thead{border-bottom:1px solid #d0d0d0}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid #d0d0d0}table.responsive-table.bordered th{border-bottom:0;border-left:0}table.responsive-table.bordered td{border-left:0;border-right:0;border-bottom:0}table.responsive-table.bordered tr{border:0}table.responsive-table.bordered tbody tr{border-right:1px solid #d0d0d0}}.collection{margin:0.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar .circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:inherit;color:#757575;float:right;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px}.side-nav span.badge.new,.collapsible span.badge.new{position:relative;background-color:transparent}.side-nav span.badge.new::before,.collapsible span.badge.new::before{content:'';position:absolute;top:10px;right:0;bottom:10px;left:0;background-color:#26a69a;border-radius:2px;z-index:-1}.collapsible span.badge.new{z-index:1}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:0.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.container .row{margin-left:-0.75rem;margin-right:-0.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;box-sizing:border-box;padding:0 0.75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{height:auto}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.button-collapse{display:none}}nav .button-collapse{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .button-collapse i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0;white-space:nowrap}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav ul{margin:0}nav ul li{transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);transition:color .3s}nav .input-field label.active i{color:#fff}nav .input-field label.active{-webkit-transform:translateY(0);transform:translateY(0)}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav,nav .nav-wrapper i,nav a.button-collapse,nav a.button-collapse i{height:64px;line-height:64px}.navbar-fixed{height:64px}}@font-face{font-family:"Roboto";src:local(Roboto Thin),url("../fonts/roboto/Roboto-Thin.eot");src:url("../fonts/roboto/Roboto-Thin.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Thin.woff2") format("woff2"),url("../fonts/roboto/Roboto-Thin.woff") format("woff"),url("../fonts/roboto/Roboto-Thin.ttf") format("truetype");font-weight:200}@font-face{font-family:"Roboto";src:local(Roboto Light),url("../fonts/roboto/Roboto-Light.eot");src:url("../fonts/roboto/Roboto-Light.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Light.woff2") format("woff2"),url("../fonts/roboto/Roboto-Light.woff") format("woff"),url("../fonts/roboto/Roboto-Light.ttf") format("truetype");font-weight:300}@font-face{font-family:"Roboto";src:local(Roboto Regular),url("../fonts/roboto/Roboto-Regular.eot");src:url("../fonts/roboto/Roboto-Regular.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Regular.woff2") format("woff2"),url("../fonts/roboto/Roboto-Regular.woff") format("woff"),url("../fonts/roboto/Roboto-Regular.ttf") format("truetype");font-weight:400}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Medium.eot");src:url("../fonts/roboto/Roboto-Medium.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Medium.woff2") format("woff2"),url("../fonts/roboto/Roboto-Medium.woff") format("woff"),url("../fonts/roboto/Roboto-Medium.ttf") format("truetype");font-weight:500}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Bold.eot");src:url("../fonts/roboto/Roboto-Bold.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Bold.woff2") format("woff2"),url("../fonts/roboto/Roboto-Bold.woff") format("woff"),url("../fonts/roboto/Roboto-Bold.ttf") format("truetype");font-weight:700}a{text-decoration:none}html{line-height:1.5;font-family:"Roboto", sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.1}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.1rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:1.78rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.46rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.14rem 0 0.912rem 0}h5{font-size:1.64rem;line-height:110%;margin:0.82rem 0 0.656rem 0}h6{font-size:1rem;line-height:110%;margin:0.5rem 0 0.4rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light,footer.page-footer .footer-copyright{font-weight:300}.thin{font-weight:200}.flow-text{font-weight:300}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.card-panel{transition:box-shadow .25s;padding:20px;margin:0.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:0.5rem 0 1rem 0;background-color:#fff;transition:box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;padding:20px}.card .card-content{padding:20px;border-radius:0 0 2px 2px}.card .card-content p{margin:0;color:inherit}.card .card-content .card-title{line-height:48px}.card .card-action{position:relative;background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);padding:20px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:20px;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:20px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:0;width:auto;clear:both;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;word-break:break-all;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.toast .btn,.toast .btn-large,.toast .btn-flat{margin:0;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}@media only screen and (min-width: 601px) and (max-width: 992px){.toast{float:left}}@media only screen and (min-width: 993px){.toast{float:right}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;transition:color .28s ease}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.7);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;display:none;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none}.backdrop{position:absolute;opacity:0;display:none;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.btn,.btn-large,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 2rem;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.btn-floating.disabled,.btn-large.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-flat:disabled,.btn[disabled],[disabled].btn-large,.btn-floating[disabled],.btn-large[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,[disabled].btn-large:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-floating,.btn-large,.btn-flat{outline:0}.btn i,.btn-large i,.btn-floating i,.btn-large i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;transition:.2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;transition:.3s;cursor:pointer;vertical-align:middle}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px}.btn-floating.btn-large i{line-height:56px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:998}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.horizontal{padding:0 0 0 15px}.fixed-action-btn.horizontal ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.horizontal ul li{display:inline-block;margin:15px 15px 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0}.fixed-action-btn.toolbar ul li{-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;transition:background-color .2s}.btn-flat:focus,.btn-flat:active{background-color:transparent}.btn-flat:focus,.btn-flat:hover{background-color:rgba(0,0,0,0.1);box-shadow:none}.btn-flat:active{background-color:rgba(0,0,0,0.2)}.btn-flat.disabled{background-color:transparent !important;color:#b3b3b3 !important;cursor:default}.btn-large{height:54px;line-height:54px}.btn-large i{font-size:1.6rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;max-height:650px;overflow-y:auto;opacity:0;position:absolute;z-index:999;will-change:width, height}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left;text-transform:none}.dropdown-content li:hover,.dropdown-content li.active,.dropdown-content li.selected{background-color:#eee}.dropdown-content li.active.selected{background-color:#e1e1e1}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px}/*! 7 | * Waves v0.6.0 8 | * http://fian.my.id/Waves 9 | * 10 | * Copyright 2014 Alfiana E. Sibuea and other contributors 11 | * Released under the MIT license 12 | * https://github.com/fians/Waves/blob/master/LICENSE 13 | */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;will-change:opacity, transform;transition:.3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);transition:all 0.7s ease-out;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;-webkit-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-effect input[type="button"],.waves-effect input[type="reset"],.waves-effect input[type="submit"]{border:0;font-style:normal;font-size:inherit;text-transform:inherit;background:none}.waves-effect img{position:relative;z-index:-1}.waves-notransition{transition:none !important}.waves-circle{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, #fff 100%, #000 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;border-radius:2px;will-change:top, opacity}@media only screen and (max-width: 992px){.modal{width:80%}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-close{cursor:pointer}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-flat{float:right;margin:6px 0}.modal-overlay{position:fixed;z-index:999;top:-100px;left:0;bottom:0;right:0;height:125%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:absolute;height:calc(100% - 56px);max-height:100%;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:absolute;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:0.5rem 0 1rem 0}.collapsible-header{display:block;cursor:pointer;min-height:3rem;line-height:3rem;padding:0 1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header i{width:2rem;font-size:1.6rem;line-height:3rem;display:block;float:left;text-align:center;margin-right:1rem}.collapsible-body{display:none;border-bottom:1px solid #ddd;box-sizing:border-box}.collapsible-body p{margin:0;padding:2rem}.side-nav .collapsible,.side-nav.fixed .collapsible{border:none;box-shadow:none}.side-nav .collapsible li,.side-nav.fixed .collapsible li{padding:0}.side-nav .collapsible-header,.side-nav.fixed .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;padding:0 16px}.side-nav .collapsible-header:hover,.side-nav.fixed .collapsible-header:hover{background-color:rgba(0,0,0,0.05)}.side-nav .collapsible-header i,.side-nav.fixed .collapsible-header i{line-height:inherit}.side-nav .collapsible-body,.side-nav.fixed .collapsible-body{border:0;background-color:#fff}.side-nav .collapsible-body li a,.side-nav.fixed .collapsible-body li a{padding:0 23.5px 0 31px}.collapsible.popout{border:none;box-shadow:none}.collapsible.popout>li{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);margin:0 24px;transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0}.chip{display:inline-block;height:32px;font-size:13px;font-weight:500;color:rgba(0,0,0,0.6);line-height:32px;padding:0 12px;border-radius:16px;background-color:#e4e4e4;margin-bottom:5px;margin-right:5px}.chip img{float:left;margin:0 8px 0 -12px;height:32px;width:32px;border-radius:50%}.chip .close{cursor:pointer;float:right;font-size:16px;line-height:32px;padding-left:8px}.chips{border:none;border-bottom:1px solid #9e9e9e;box-shadow:none;margin:0 0 20px 0;min-height:45px;outline:none;transition:all .3s}.chips.focus{border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}.chips:hover{cursor:text}.chips .chip.selected{background-color:#26a69a;color:#fff}.chips .input{background:none;border:0;color:rgba(0,0,0,0.6);display:inline-block;font-size:1rem;height:3rem;line-height:32px;outline:0;margin:0;padding:0 !important;width:120px !important}.chips .input:focus{border:0 !important;box-shadow:none !important}.prefix ~ .chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty ~ label{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;transition:opacity .4s}.materialboxed:hover{will-change:left, top, width, height}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#292929;z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:0.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}:-moz-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}input:not([type]),input[type=text],input[type=password],input[type=email],input[type=url],input[type=time],input[type=date],input[type=datetime],input[type=datetime-local],input[type=tel],input[type=number],input[type=search],textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;box-shadow:none;box-sizing:content-box;transition:all 0.3s}input:not([type]):disabled,input:not([type])[readonly="readonly"],input[type=text]:disabled,input[type=text][readonly="readonly"],input[type=password]:disabled,input[type=password][readonly="readonly"],input[type=email]:disabled,input[type=email][readonly="readonly"],input[type=url]:disabled,input[type=url][readonly="readonly"],input[type=time]:disabled,input[type=time][readonly="readonly"],input[type=date]:disabled,input[type=date][readonly="readonly"],input[type=datetime]:disabled,input[type=datetime][readonly="readonly"],input[type=datetime-local]:disabled,input[type=datetime-local][readonly="readonly"],input[type=tel]:disabled,input[type=tel][readonly="readonly"],input[type=number]:disabled,input[type=number][readonly="readonly"],input[type=search]:disabled,input[type=search][readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.26);border-bottom:1px dotted rgba(0,0,0,0.26)}input:not([type]):disabled+label,input:not([type])[readonly="readonly"]+label,input[type=text]:disabled+label,input[type=text][readonly="readonly"]+label,input[type=password]:disabled+label,input[type=password][readonly="readonly"]+label,input[type=email]:disabled+label,input[type=email][readonly="readonly"]+label,input[type=url]:disabled+label,input[type=url][readonly="readonly"]+label,input[type=time]:disabled+label,input[type=time][readonly="readonly"]+label,input[type=date]:disabled+label,input[type=date][readonly="readonly"]+label,input[type=datetime]:disabled+label,input[type=datetime][readonly="readonly"]+label,input[type=datetime-local]:disabled+label,input[type=datetime-local][readonly="readonly"]+label,input[type=tel]:disabled+label,input[type=tel][readonly="readonly"]+label,input[type=number]:disabled+label,input[type=number][readonly="readonly"]+label,input[type=search]:disabled+label,input[type=search][readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.26)}input:not([type]):focus:not([readonly]),input[type=text]:focus:not([readonly]),input[type=password]:focus:not([readonly]),input[type=email]:focus:not([readonly]),input[type=url]:focus:not([readonly]),input[type=time]:focus:not([readonly]),input[type=date]:focus:not([readonly]),input[type=datetime]:focus:not([readonly]),input[type=datetime-local]:focus:not([readonly]),input[type=tel]:focus:not([readonly]),input[type=number]:focus:not([readonly]),input[type=search]:focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}input:not([type]):focus:not([readonly])+label,input[type=text]:focus:not([readonly])+label,input[type=password]:focus:not([readonly])+label,input[type=email]:focus:not([readonly])+label,input[type=url]:focus:not([readonly])+label,input[type=time]:focus:not([readonly])+label,input[type=date]:focus:not([readonly])+label,input[type=datetime]:focus:not([readonly])+label,input[type=datetime-local]:focus:not([readonly])+label,input[type=tel]:focus:not([readonly])+label,input[type=number]:focus:not([readonly])+label,input[type=search]:focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input:not([type]).valid,input:not([type]):focus.valid,input[type=text].valid,input[type=text]:focus.valid,input[type=password].valid,input[type=password]:focus.valid,input[type=email].valid,input[type=email]:focus.valid,input[type=url].valid,input[type=url]:focus.valid,input[type=time].valid,input[type=time]:focus.valid,input[type=date].valid,input[type=date]:focus.valid,input[type=datetime].valid,input[type=datetime]:focus.valid,input[type=datetime-local].valid,input[type=datetime-local]:focus.valid,input[type=tel].valid,input[type=tel]:focus.valid,input[type=number].valid,input[type=number]:focus.valid,input[type=search].valid,input[type=search]:focus.valid,textarea.materialize-textarea.valid,textarea.materialize-textarea:focus.valid{border-bottom:1px solid #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input:not([type]).valid+label:after,input:not([type]):focus.valid+label:after,input[type=text].valid+label:after,input[type=text]:focus.valid+label:after,input[type=password].valid+label:after,input[type=password]:focus.valid+label:after,input[type=email].valid+label:after,input[type=email]:focus.valid+label:after,input[type=url].valid+label:after,input[type=url]:focus.valid+label:after,input[type=time].valid+label:after,input[type=time]:focus.valid+label:after,input[type=date].valid+label:after,input[type=date]:focus.valid+label:after,input[type=datetime].valid+label:after,input[type=datetime]:focus.valid+label:after,input[type=datetime-local].valid+label:after,input[type=datetime-local]:focus.valid+label:after,input[type=tel].valid+label:after,input[type=tel]:focus.valid+label:after,input[type=number].valid+label:after,input[type=number]:focus.valid+label:after,input[type=search].valid+label:after,input[type=search]:focus.valid+label:after,textarea.materialize-textarea.valid+label:after,textarea.materialize-textarea:focus.valid+label:after{content:attr(data-success);color:#4CAF50;opacity:1}input:not([type]).invalid,input:not([type]):focus.invalid,input[type=text].invalid,input[type=text]:focus.invalid,input[type=password].invalid,input[type=password]:focus.invalid,input[type=email].invalid,input[type=email]:focus.invalid,input[type=url].invalid,input[type=url]:focus.invalid,input[type=time].invalid,input[type=time]:focus.invalid,input[type=date].invalid,input[type=date]:focus.invalid,input[type=datetime].invalid,input[type=datetime]:focus.invalid,input[type=datetime-local].invalid,input[type=datetime-local]:focus.invalid,input[type=tel].invalid,input[type=tel]:focus.invalid,input[type=number].invalid,input[type=number]:focus.invalid,input[type=search].invalid,input[type=search]:focus.invalid,textarea.materialize-textarea.invalid,textarea.materialize-textarea:focus.invalid{border-bottom:1px solid #F44336;box-shadow:0 1px 0 0 #F44336}input:not([type]).invalid+label:after,input:not([type]):focus.invalid+label:after,input[type=text].invalid+label:after,input[type=text]:focus.invalid+label:after,input[type=password].invalid+label:after,input[type=password]:focus.invalid+label:after,input[type=email].invalid+label:after,input[type=email]:focus.invalid+label:after,input[type=url].invalid+label:after,input[type=url]:focus.invalid+label:after,input[type=time].invalid+label:after,input[type=time]:focus.invalid+label:after,input[type=date].invalid+label:after,input[type=date]:focus.invalid+label:after,input[type=datetime].invalid+label:after,input[type=datetime]:focus.invalid+label:after,input[type=datetime-local].invalid+label:after,input[type=datetime-local]:focus.invalid+label:after,input[type=tel].invalid+label:after,input[type=tel]:focus.invalid+label:after,input[type=number].invalid+label:after,input[type=number]:focus.invalid+label:after,input[type=search].invalid+label:after,input[type=search]:focus.invalid+label:after,textarea.materialize-textarea.invalid+label:after,textarea.materialize-textarea:focus.invalid+label:after{content:attr(data-error);color:#F44336;opacity:1}input:not([type]).validate+label,input[type=text].validate+label,input[type=password].validate+label,input[type=email].validate+label,input[type=url].validate+label,input[type=time].validate+label,input[type=date].validate+label,input[type=datetime].validate+label,input[type=datetime-local].validate+label,input[type=tel].validate+label,input[type=number].validate+label,input[type=search].validate+label,textarea.materialize-textarea.validate+label{width:100%;pointer-events:none}input:not([type])+label:after,input[type=text]+label:after,input[type=password]+label:after,input[type=email]+label:after,input[type=url]+label:after,input[type=time]+label:after,input[type=date]+label:after,input[type=datetime]+label:after,input[type=datetime-local]+label:after,input[type=tel]+label:after,input[type=number]+label:after,input[type=search]+label:after,textarea.materialize-textarea+label:after{display:block;content:"";position:absolute;top:60px;opacity:0;transition:.2s opacity ease-out, .2s color ease-out}.input-field{position:relative;margin-top:1rem}.input-field.inline{display:inline-block;vertical-align:middle;margin-left:5px}.input-field.inline input,.input-field.inline .select-dropdown{margin-bottom:1rem}.input-field.col label{left:0.75rem}.input-field.col .prefix ~ label,.input-field.col .prefix ~ .validate ~ label{width:calc(100% - 3rem - 1.5rem)}.input-field label{color:#9e9e9e;position:absolute;top:0.8rem;left:0;font-size:1rem;cursor:text;transition:.2s ease-out}.input-field label.active{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;transition:color .2s}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea,.input-field .prefix ~ label,.input-field .prefix ~ .validate ~ label,.input-field .prefix ~ .autocomplete-content{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width: 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width: 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;padding-left:4rem;width:calc(100% - 4rem)}.input-field input[type=search]:focus{background-color:#fff;border:0;box-shadow:none;color:#444}.input-field input[type=search]:focus+label i,.input-field input[type=search]:focus ~ .mdi-navigation-close,.input-field input[type=search]:focus ~ .material-icons{color:#444}.input-field input[type=search]+label{left:1rem}.input-field input[type=search] ~ .mdi-navigation-close,.input-field input[type=search] ~ .material-icons{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{overflow-y:hidden;padding:.8rem 0 1.6rem 0;resize:none;min-height:3rem}.hiddendiv{display:none;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem}.autocomplete-content{margin-top:-15px;display:block;opacity:1;position:static}.autocomplete-content li .highlight{color:#444}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;left:-9999px;opacity:0}[type="radio"]:not(:checked)+label,[type="radio"]:checked+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="radio"]+label:before,[type="radio"]+label:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;transition:.28s ease}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after,[type="radio"]:checked+label:before,[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border-radius:50%}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after{border:2px solid #5a5a5a}[type="radio"]:not(:checked)+label:after{-webkit-transform:scale(0);transform:scale(0)}[type="radio"]:checked+label:before{border:2px solid transparent}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border:2px solid #26a69a}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:after{background-color:#26a69a}[type="radio"]:checked+label:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+label:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type="radio"].tabbed:focus+label:before{box-shadow:0 0 0 10px rgba(0,0,0,0.1)}[type="radio"].with-gap:disabled:checked+label:before{border:2px solid rgba(0,0,0,0.26)}[type="radio"].with-gap:disabled:checked+label:after{border:none;background-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before,[type="radio"]:disabled:checked+label:before{background-color:transparent;border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled+label{color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before{border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:checked+label:after{background-color:rgba(0,0,0,0.26);border-color:#BDBDBD}form p{margin-bottom:10px;text-align:left}form p:last-child{margin-bottom:0}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;left:-9999px;opacity:0}[type="checkbox"]+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="checkbox"]+label:before,[type="checkbox"]:not(.filled-in)+label:after{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:2px;transition:.2s}[type="checkbox"]:not(.filled-in)+label:after{border:0;-webkit-transform:scale(0);transform:scale(0)}[type="checkbox"]:not(:checked):disabled+label:before{border:none;background-color:rgba(0,0,0,0.26)}[type="checkbox"].tabbed:focus+label:after{-webkit-transform:scale(1);transform:scale(1);border:0;border-radius:50%;box-shadow:0 0 0 10px rgba(0,0,0,0.1);background-color:rgba(0,0,0,0.1)}[type="checkbox"]:checked+label:before{top:-4px;left:-5px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);border-bottom:2px solid rgba(0,0,0,0.26)}[type="checkbox"]:indeterminate+label:before{top:-11px;left:-12px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);background-color:transparent}[type="checkbox"].filled-in+label:after{border-radius:2px}[type="checkbox"].filled-in+label:before,[type="checkbox"].filled-in+label:after{content:'';left:0;position:absolute;transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+label:before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:20% 40%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+label:after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+label:before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+label:after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in.tabbed:focus+label:after{border-radius:2px;border-color:#5a5a5a;background-color:rgba(0,0,0,0.1)}[type="checkbox"].filled-in.tabbed:checked:focus+label:after{border-radius:2px;background-color:#26a69a;border-color:#26a69a}[type="checkbox"].filled-in:disabled:not(:checked)+label:before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+label:after{border-color:transparent;background-color:#BDBDBD}[type="checkbox"].filled-in:disabled:checked+label:before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+label:after{background-color:#BDBDBD;border-color:#BDBDBD}.switch,.switch *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a;left:24px}.switch label .lever{content:"";display:inline-block;position:relative;width:40px;height:15px;background-color:#818181;border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:after{content:"";position:absolute;display:inline-block;width:21px;height:21px;background-color:#F1F1F1;border-radius:21px;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-3px;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease}input[type=checkbox]:checked:not(:disabled) ~ .lever:active::after,input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(38,166,154,0.1)}input[type=checkbox]:not(:disabled) ~ .lever:active:after,input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.08)}.switch input[type=checkbox][disabled]+.lever{cursor:default}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#BDBDBD}select{display:none}select.browser-default{display:block}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;display:block}.select-wrapper span.caret{color:initial;position:absolute;right:0;top:0;bottom:0;height:10px;margin:auto 0;font-size:10px;line-height:10px}.select-wrapper span.caret.disabled{color:rgba(0,0,0,0.26)}.select-wrapper+label{position:absolute;top:-14px;font-size:0.8rem}select:disabled{color:rgba(0,0,0,0.3)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.3);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;border-bottom:1px solid rgba(0,0,0,0.3)}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:rgba(0,0,0,0.3);background-color:transparent}.prefix ~ .select-wrapper{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.prefix ~ label{margin-left:3rem}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;float:right}.select-dropdown li.optgroup{border-top:1px solid #eee}.select-dropdown li.optgroup.selected>span{color:rgba(0,0,0,0.7)}.select-dropdown li.optgroup>span{color:rgba(0,0,0,0.4)}.select-dropdown li.optgroup ~ li.optgroup-option{padding-left:1rem}.file-field{position:relative}.file-field .file-path-wrapper{overflow:hidden;padding-left:10px}.file-field input.file-path{width:100%}.file-field .btn,.file-field .btn-large{float:left;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0;padding:0}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;top:10px;margin-left:-6px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:14px;width:14px;border-radius:50%;background-color:#26a69a;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0;transition:.3s}input[type=range]:focus::-webkit-slider-runnable-track{background:#ccc}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#ddd;border:none}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input[type=range]:focus::-moz-range-track{background:#ccc}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a}input[type=range]:focus::-ms-fill-lower{background:#888}input[type=range]:focus::-ms-fill-upper{background:#ccc}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:20px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:19px;border-left:1px solid #ea4a4f}.table-of-contents a.active{font-weight:500;padding-left:18px;border-left:2px solid #ea4a4f}.side-nav{position:fixed;width:300px;left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#fff;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.side-nav .collapsible{margin:0}.side-nav li{float:none;line-height:48px}.side-nav li.active{background-color:rgba(0,0,0,0.05)}.side-nav a{color:rgba(0,0,0,0.87);display:block;font-size:14px;font-weight:500;height:48px;line-height:48px;padding:0 32px}.side-nav a:hover{background-color:rgba(0,0,0,0.05)}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-flat,.side-nav a.btn-floating{margin:10px 15px}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-floating{color:#fff}.side-nav a.btn-flat{color:#343434}.side-nav a.btn:hover,.side-nav a.btn-large:hover,.side-nav a.btn-large:hover{background-color:#2bbbad}.side-nav a.btn-floating:hover{background-color:#26a69a}.side-nav li>a>i,.side-nav li>a>[class^="mdi-"],.side-nav li>a>[class*="mdi-"],.side-nav li>a>i.material-icons{float:left;height:48px;line-height:48px;margin:0 32px 0 0;width:24px;color:rgba(0,0,0,0.54)}.side-nav .divider{margin:8px 0 0 0}.side-nav .subheader{cursor:initial;pointer-events:none;color:rgba(0,0,0,0.54);font-size:14px;font-weight:500;line-height:48px}.side-nav .subheader:hover{background-color:transparent}.side-nav .userView{position:relative;padding:32px 32px 0;margin-bottom:8px}.side-nav .userView>a{height:auto;padding:0}.side-nav .userView>a:hover{background-color:transparent}.side-nav .userView .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.side-nav .userView .circle,.side-nav .userView .name,.side-nav .userView .email{display:block}.side-nav .userView .circle{height:64px;width:64px}.side-nav .userView .name,.side-nav .userView .email{font-size:14px;line-height:24px}.side-nav .userView .name{margin-top:16px;font-weight:500}.side-nav .userView .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.side-nav.fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.side-nav.fixed.right-aligned{right:0;left:auto}@media only screen and (max-width: 992px){.side-nav.fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.side-nav a{padding:0 16px}.side-nav .userView{padding:16px 16px 0}}.side-nav .collapsible-body>ul:not(.collapsible)>li.active,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active{background-color:#ee6e73}.side-nav .collapsible-body>ul:not(.collapsible)>li.active a,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active a{color:#fff}#sidenav-overlay{position:fixed;top:0;left:0;right:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;will-change:opacity}.preloader-wrapper{display:inline-block;position:relative;width:48px;height:48px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:#26a69a}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.carousel{overflow:hidden;position:relative;width:100%;height:400px;-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0;height:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:400px;position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{display:none;width:200px;height:400px;position:absolute;top:0;left:0}.carousel .carousel-item img{width:100%}.carousel .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:rgba(255,255,255,0.5);transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:#fff}.picker{font-size:16px;text-align:left;line-height:1.2;color:#000000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*! 14 | * Default mobile-first, responsive styling for pickadate.js 15 | * Demo: http://amsul.github.io/pickadate.js 16 | */.picker__holder,.picker__frame{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;transition:background 0.15s ease-out, top 0s 0.15s;-webkit-backface-visibility:hidden}.picker__frame{position:absolute;margin:0 auto;min-width:256px;width:300px;max-height:350px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all 0.15s ease-out}@media (min-height: 28.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height: 40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height: 28.875em){.picker__wrap{display:block}}.picker__box{background:#ffffff;display:table-cell;vertical-align:middle}@media (min-height: 28.875em){.picker__box{display:block;border:1px solid #777777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,0.24)}}.picker--opened .picker__holder{top:0;background:transparent;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";zoom:1;background:rgba(0,0,0,0.32);transition:background 0.15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height: 35.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__input.picker__input--active{border-color:#E3F2FD}.picker__frame{margin:0 auto;max-width:325px}@media (min-height: 38.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{display:inline-block;margin-left:.25em;margin-right:.25em}.picker__select--month,.picker__select--year{height:2em;padding:0;margin-left:.25em;margin-right:.25em}.picker__select--month.browser-default{display:inline;background-color:#FFFFFF;width:40%}.picker__select--year.browser-default{display:inline;background-color:#FFFFFF;width:26%}.picker__select--month:focus,.picker__select--year:focus{border-color:rgba(0,0,0,0.05)}.picker__nav--prev,.picker__nav--next{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-0.25em}.picker__nav--prev{left:-1em;padding-right:1.25em}.picker__nav--next{right:-1em;padding-left:1.25em}.picker__nav--disabled,.picker__nav--disabled:hover,.picker__nav--disabled:before,.picker__nav--disabled:before:hover{cursor:default;background:none;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:1rem;width:100%;margin-top:.75em;margin-bottom:.5em}.picker__table th,.picker__table td{text-align:center}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999999;font-weight:500}@media (min-height: 33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day--today{position:relative;color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day--disabled:before{border-top-color:#aaaaaa}.picker__day--infocus:hover{cursor:pointer;color:#000;font-weight:500}.picker__day--outfocus{display:none;padding:.75rem 0;color:#fff}.picker__day--outfocus:hover{cursor:pointer;color:#dddddd;font-weight:500}.picker__day--highlighted:hover,.picker--focused .picker__day--highlighted{cursor:pointer}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.75);transform:scale(0.75);background:#0089ec;color:#ffffff}.picker__day--disabled,.picker__day--disabled:hover,.picker--focused .picker__day--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbbbbb}.picker__footer{text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.picker__button--today,.picker__button--clear,.picker__button--close{border:1px solid #ffffff;background:#ffffff;font-size:.8em;padding:.66em 0;font-weight:bold;width:33%;display:inline-block;vertical-align:bottom}.picker__button--today:hover,.picker__button--clear:hover,.picker__button--close:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--today:focus,.picker__button--clear:focus,.picker__button--close:focus{background:#b1dcfb;border-color:rgba(0,0,0,0.05);outline:none}.picker__button--today:before,.picker__button--clear:before,.picker__button--close:before{position:relative;display:inline-block;height:0}.picker__button--today:before,.picker__button--clear:before{content:" ";margin-right:.45em}.picker__button--today:before{top:-0.05em;width:0;border-top:0.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{top:-0.25em;width:.66em;border-top:3px solid #ee2200}.picker__button--close:before{content:"\D7";top:-0.1em;vertical-align:top;font-size:1.1em;margin-right:.35em;color:#777777}.picker__button--today[disabled],.picker__button--today[disabled]:hover{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__button--today[disabled]:before{border-top-color:#aaaaaa}.picker__box{border-radius:2px;overflow:hidden}.picker__date-display{text-align:center;background-color:#26a69a;color:#fff;padding-bottom:15px;font-weight:300}.picker__nav--prev:hover,.picker__nav--next:hover{cursor:pointer;color:#000000;background:#a1ded8}.picker__weekday-display{background-color:#1f897f;padding:10px;font-weight:200;letter-spacing:.5;font-size:1rem;margin-bottom:15px}.picker__month-display{text-transform:uppercase;font-size:2rem}.picker__day-display{font-size:4.5rem;font-weight:400}.picker__year-display{font-size:1.8rem;color:rgba(255,255,255,0.4)}.picker__box{padding:0}.picker__calendar-container{padding:0 1rem}.picker__calendar-container thead{border:none}.picker__table{margin-top:0;margin-bottom:.5em}.picker__day--infocus{color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day.picker__day--today{color:#26a69a}.picker__day.picker__day--today.picker__day--selected{color:#fff}.picker__weekday{font-size:.9rem}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.9);transform:scale(0.9);background-color:#26a69a;color:#ffffff}.picker__day--selected.picker__day--outfocus,.picker__day--selected:hover.picker__day--outfocus,.picker--focused .picker__day--selected.picker__day--outfocus{background-color:#a1ded8}.picker__footer{text-align:right;padding:5px 10px}.picker__close,.picker__today{font-size:1.1rem;padding:0 1rem;color:#26a69a}.picker__nav--prev:before,.picker__nav--next:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:0.75em solid #676767;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:0.75em solid #676767}button.picker__today:focus,button.picker__clear:focus,button.picker__close:focus{background-color:#a1ded8}.picker__list{list-style:none;padding:0.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #dddddd;border-top:1px solid #dddddd;margin-bottom:-1px;position:relative;background:#ffffff;padding:.75em 1.25em}@media (min-height: 46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker__list-item--highlighted:hover,.picker--focused .picker__list-item--highlighted{cursor:pointer;color:#000000;background:#b1dcfb}.picker__list-item--selected,.picker__list-item--selected:hover,.picker--focused .picker__list-item--selected{background:#0089ec;color:#ffffff;z-index:10}.picker__list-item--disabled,.picker__list-item--disabled:hover,.picker--focused .picker__list-item--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default;border-color:#dddddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:none;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:hover,.picker--time .picker__button--clear:focus{color:#000000;background:#b1dcfb;background:#ee2200;border-color:#ee2200;cursor:pointer;color:#ffffff;outline:none}.picker--time .picker__button--clear:before{top:-0.25em;color:#666;font-size:1.25em;font-weight:bold}.picker--time .picker__button--clear:hover:before,.picker--time .picker__button--clear:focus:before{color:#ffffff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height: 40.125em){.picker--time .picker__box{margin-bottom:5em}} 17 | -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.eot -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.ttf -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.eot -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.ttf -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.eot -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.ttf -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.eot -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.ttf -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.eot -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.ttf -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/simple-website/views/partials/materialize/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /streams-and-pipes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "streams-and-pipes", 3 | "version": "0.1.0", 4 | "description": "demostration of streams and pipes", 5 | "main": "stream-pipe-on-server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Ashok Dey", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.14.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /streams-and-pipes/stream-and-pipes.js: -------------------------------------------------------------------------------- 1 | /*** 2 | * Streams breaks large files into smaller chunks that 3 | * can travel on the network easily. 4 | */ 5 | 6 | const fs = require('fs'); 7 | 8 | // read a file 9 | let readStream = fs.createReadStream(__dirname + '/sample-big-file.txt', 'utf8'); 10 | 11 | //use the .on() method to take the chunk and write it to another file 12 | 13 | // create a new file 14 | let writeStream = fs.createWriteStream(__dirname + '/write-big-file.txt'); 15 | 16 | let i = 1; 17 | 18 | readStream.on('data', (chunk) => { 19 | console.log('chunk received :' + i++); 20 | writeStream.write(chunk); 21 | }); 22 | 23 | //it took 6 chunks to completely read the sample-big-file.txt 24 | 25 | /** 26 | * Using Pipes 27 | * ---------------- 28 | * when we use pipes, then we do not manually need to do the writing task 29 | * by taking the chunks. The .pipe() method does everything for us 30 | */ 31 | 32 | //create a new write file to write the data using pipes 33 | let writeStreamPipe = fs.createWriteStream(__dirname + '/write-big-pipe.txt'); 34 | 35 | readStream.pipe(writeStreamPipe) -------------------------------------------------------------------------------- /streams-and-pipes/stream-pipe-on-server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const fs = require('fs'); 3 | 4 | const myApp = express(); 5 | 6 | myApp.get('*', (req, res) => { 7 | // do the streaming work here 8 | // send the data as response 9 | const readStream = fs.createReadStream(__dirname + '/sample-big-file.txt', 'utf8'); 10 | readStream.pipe(res); 11 | console.log(req.url); 12 | }); 13 | 14 | myApp.listen(3000, () => { 15 | console.log('listening to port 3000'); 16 | }) -------------------------------------------------------------------------------- /testing-node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testing-node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "server.js", 8 | "test": "mocha **/*.test.js", 9 | "test-watch": "nodemon --exec \" npm test\"" 10 | }, 11 | "author": "Ashok Dey", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "expect": "^1.20.2", 15 | "mocha": "^3.2.0", 16 | "supertest": "^2.0.1" 17 | }, 18 | "dependencies": { 19 | "express": "^4.14.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testing-node/server/server.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const express = require('express'); 4 | 5 | const app = express(); 6 | 7 | 8 | app.get('/', (req, res) => { 9 | res.send('Hello Folks'); 10 | }); 11 | 12 | 13 | app.listen(3000); 14 | 15 | module.exports.app = app; -------------------------------------------------------------------------------- /testing-node/server/server.test.js: -------------------------------------------------------------------------------- 1 | const request = require('supertest'); 2 | let app = require('./server').app; 3 | 4 | it('shoud return hello folk response', (done) => { 5 | request(app) 6 | .get('/') 7 | .expect('Hello Folks') 8 | .end(done); 9 | }); -------------------------------------------------------------------------------- /testing-node/utils/utils.js: -------------------------------------------------------------------------------- 1 | module.exports.add = (a, b) => a + b; 2 | 3 | module.exports.square = (a) => a * a; 4 | 5 | module.exports.setName = (user, fullName) => { 6 | let names = fullName.split(' '); 7 | 8 | user.firstName = names[0]; 9 | user.lastName = names[1]; 10 | return user; 11 | } 12 | 13 | module.exports.asyncAdd = (a, b, callback) => { 14 | setTimeout(() => { 15 | callback(a, b); 16 | }, 1000) 17 | } -------------------------------------------------------------------------------- /testing-node/utils/utils.test.js: -------------------------------------------------------------------------------- 1 | const expect = require('expect'); 2 | const utils = require('./utils'); 3 | 4 | it('should add 2 numbers', () => { 5 | let res = utils.add(11, 33); 6 | if (res != 44) { 7 | throw Error(`Expected 44, got ${res}`); 8 | } 9 | }); 10 | 11 | it('should square a number', () => { 12 | let res = utils.square(5); 13 | // using expect here instead of the if-else block 14 | 15 | expect(res).toBe(25).toBeA('number'); 16 | 17 | // if (res != 25) { 18 | // throw Error(`Expected 4 but got ${res}`); 19 | // } 20 | }); 21 | 22 | it('should set first and last name', () => { 23 | let user = {age : 23, location: 'Delhi'}; 24 | let res = utils.setName(user, 'Ashok Dey'); 25 | expect(res).toInclude({ 26 | firstName : 'Ashok', 27 | lastName: 'Dey' 28 | }) 29 | }); 30 | 31 | //testing async functions 32 | 33 | it('should async add two numbers', () => { 34 | utils.asyncAdd(3, 4, (sum) => { 35 | expect(sum).toBe(7).toBeA('number'); 36 | }); 37 | }); -------------------------------------------------------------------------------- /weather-app/README.md: -------------------------------------------------------------------------------- 1 | #Weather App - A Command Line Utility 2 | * This is a command line utility to get the weather details 3 | * This is the fourth app by me while learning Node 4 | * It uses **Yargs** and **Request** libraries 5 | 6 | ###How to Setup? 7 | 8 | _In the terminal, type **npm install & npm start** to setup and run the application._ 9 | 10 | ###How to Run? 11 | _Open terminal, type **node show-weather -a "address/pin code/city name"**_ 12 | 13 | ###Screenshot 14 | ![Screenshot](capture.JPG) 15 | 16 | 17 | **You liked it? _Star it_ !** -------------------------------------------------------------------------------- /weather-app/capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashokdey/LearningNode/de7911584371cd78746b8ce7d4fb8b8bcc6c764c/weather-app/capture.JPG -------------------------------------------------------------------------------- /weather-app/geochords/geochords.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const request = require('request'); 4 | 5 | let getAddress = (address, callback) => 6 | { 7 | //encode the adddress - removing spaces 8 | const encodedAddress = encodeURIComponent(address); 9 | 10 | request({ 11 | url : `https://maps.googleapis.com/maps/api/geocode/json?address=${encodedAddress}`, 12 | json : true 13 | }, (error, response, body) => { 14 | if (error) 15 | { 16 | callback('Bad day! Failed to connect.') 17 | } 18 | else if (body.status === `ZERO_RESULTS`) 19 | { 20 | callback(`Invalid address. Are you drunk?`); 21 | } 22 | else if (body.status === `OK`) 23 | { 24 | callback(undefined, { 25 | address : body.results[0].formatted_address, 26 | latitude : body.results[0].geometry.location.lat, 27 | longitude : body.results[0].geometry.location.lng 28 | }); 29 | } 30 | }); 31 | } 32 | 33 | module.exports = { 34 | getAddress 35 | }; -------------------------------------------------------------------------------- /weather-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather-app", 3 | "version": "0.1.0", 4 | "description": "command line weather app using node ", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Ashok Dey", 10 | "license": "MIT", 11 | "dependencies": { 12 | "request": "^2.79.0", 13 | "yargs": "^6.6.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /weather-app/show-weather.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const request = require('request'); 3 | const yargs = require('yargs'); 4 | const geochords = require('./geochords/geochords'); 5 | const weather = require('./weather/weather'); 6 | 7 | const argv = yargs.options({ 8 | address : { 9 | description : "get weather for address", 10 | demand : true, 11 | alias : 'a', 12 | string : true 13 | } 14 | }).help().alias('help', 'h').argv; 15 | 16 | // get the latitude and longitude 17 | geochords.getAddress(argv.address, (errorMessage, result) => { 18 | if (errorMessage){ 19 | console.log(errorMessage); 20 | } 21 | else { 22 | //print the address 23 | console.log(`----------\nWeather for : ${result.address}`); 24 | // get the weather details using latitude and longitude 25 | weather.getWeather(result.latitude, result.longitude, (error, result) => { 26 | if (error) { 27 | console.log(error); 28 | } 29 | else { 30 | console.log(`Temperature : ${result.temp} \u00B0C\nFeels Like : ${result.feelTemp} \u00B0C\nHumidity : ${result.humidity}%\nWind Speed : ${result.ws}km/h\nPowered by : https://darksky.net/poweredby`); 31 | } 32 | }); 33 | } 34 | }); -------------------------------------------------------------------------------- /weather-app/weather/weather.js: -------------------------------------------------------------------------------- 1 | 'use sctict'; 2 | const request = require('request'); 3 | 4 | let getWeather = (lat, lng, callback) => 5 | { 6 | request({ 7 | url :`https://api.darksky.net/forecast/6cad342a1caf0f17020d8228ed704249/${lat},${lng}?units=si&exclude=minutely,hourly,daily,flags`, 8 | json : true 9 | }, (error, response, body) => { 10 | if (!error && response.statusCode === 200) { 11 | callback(undefined, { 12 | temp : body.currently.temperature, 13 | feelTemp: body.currently.apparentTemperature, 14 | humidity : body.currently.humidity * 100, 15 | ws : body.currently.windSpeed 16 | }); 17 | } 18 | else 19 | { 20 | callback('Sorry, failed to fetch weather details'); 21 | } 22 | }); 23 | } 24 | 25 | module.exports = { 26 | getWeather 27 | }; --------------------------------------------------------------------------------