Browse Source

here we go

master
Guilmour 2 years ago
parent
commit
9c1eda7e69
100 changed files with 9683 additions and 162 deletions
  1. +6
    -0
      .gitignore
  2. +189
    -0
      config/passport.js
  3. +47
    -0
      controllers/contact.js
  4. +18
    -0
      controllers/home.js
  5. +36
    -0
      controllers/upload.js
  6. +358
    -0
      controllers/user.js
  7. +107
    -0
      controllers/watch.js
  8. BIN
      imgs/ico-next.png
  9. BIN
      imgs/ico-play-next.png
  10. +62
    -0
      models/User.js
  11. +41
    -0
      models/Watch.js
  12. +34
    -0
      package.json
  13. +41
    -0
      public/css/blog_focus.css
  14. +496
    -0
      public/css/custom.css
  15. +4
    -0
      public/css/font-awesome.min.css
  16. +7
    -0
      public/css/jquery.tagsinput.css
  17. +311
    -0
      public/css/main.css
  18. +527
    -0
      public/css/normalize.css
  19. +191
    -162
      public/css/style.css
  20. +6916
    -0
      public/css/vendor/bootstrap.css
  21. BIN
      public/fonts/glyphicons-halflings-regular.eot
  22. +288
    -0
      public/fonts/glyphicons-halflings-regular.svg
  23. BIN
      public/fonts/glyphicons-halflings-regular.ttf
  24. BIN
      public/fonts/glyphicons-halflings-regular.woff
  25. BIN
      public/fonts/glyphicons-halflings-regular.woff2
  26. BIN
      public/img/10-anos-jean-charles-relatos/fundo.jpg
  27. BIN
      public/img/10-anos-jean-charles-relatos/thumb.jpg
  28. BIN
      public/img/3porcento/fundo.jpg
  29. BIN
      public/img/3porcento/thumb.jpg
  30. BIN
      public/img/3porcento/thumb2.jpg
  31. BIN
      public/img/3porcento/thumb3.jpg
  32. BIN
      public/img/afk/fundo.jpg
  33. BIN
      public/img/afk/thumb.jpg
  34. BIN
      public/img/cargando.gif
  35. +1
    -0
      public/img/cargando.svg
  36. BIN
      public/img/castelo-ratimbum/fundo.jpg
  37. BIN
      public/img/castelo-ratimbum/thumb.jpg
  38. BIN
      public/img/deep-web/fundo.jpg
  39. BIN
      public/img/deep-web/thumb.jpg
  40. BIN
      public/img/deus-e-o-diabo-em-cima-da-muralha/fundo.jpg
  41. BIN
      public/img/deus-e-o-diabo-em-cima-da-muralha/thumb.jpg
  42. BIN
      public/img/earthlings/fundo.jpg
  43. BIN
      public/img/earthlings/thumb.jpg
  44. BIN
      public/img/eu-nao-quero-voltar-sozinho/fundo.jpg
  45. BIN
      public/img/eu-nao-quero-voltar-sozinho/thumb.jpg
  46. BIN
      public/img/freenet/fundo.jpg
  47. BIN
      public/img/freenet/thumb.jpg
  48. BIN
      public/img/grounded-last-of-us/fundo.jpg
  49. BIN
      public/img/grounded-last-of-us/thumb.jpg
  50. BIN
      public/img/hotel-laide/fundo.jpg
  51. BIN
      public/img/hotel-laide/thumb.jpg
  52. BIN
      public/img/hotel-laide/thumb.png
  53. BIN
      public/img/human/fundo.jpg
  54. BIN
      public/img/human/thumb.jpg
  55. BIN
      public/img/human/thumb2.jpg
  56. BIN
      public/img/human/thumb3.jpg
  57. BIN
      public/img/ico-exit.png
  58. +0
    -0
      public/img/ico-fullscreen-exit.png
  59. +0
    -0
      public/img/ico-fullscreen.png
  60. +0
    -0
      public/img/ico-mute.png
  61. BIN
      public/img/ico-next.png
  62. +0
    -0
      public/img/ico-pause.png
  63. BIN
      public/img/ico-play-next.png
  64. +0
    -0
      public/img/ico-play.png
  65. +0
    -0
      public/img/ico-volume.png
  66. BIN
      public/img/kungfury/fundo.jpg
  67. BIN
      public/img/kungfury/thumb.jpg
  68. BIN
      public/img/life-in-a-day/fundo.jpg
  69. BIN
      public/img/life-in-a-day/thumb.jpg
  70. BIN
      public/img/life-in-a-day/thumb.png
  71. +0
    -0
      public/img/loading.png
  72. BIN
      public/img/metropolis/fundo.jpg
  73. BIN
      public/img/metropolis/thumb.jpg
  74. BIN
      public/img/o-fim-do-recreio/fundo.jpg
  75. BIN
      public/img/o-fim-do-recreio/thumb.jpg
  76. BIN
      public/img/o-menino-da-internet/fundo.jpg
  77. BIN
      public/img/o-menino-da-internet/thumb.jpg
  78. +0
    -0
      public/img/obsabsorver.jpg
  79. BIN
      public/img/observareabsorver/thumb.jpg
  80. BIN
      public/img/observareabsorver/thumb.png
  81. BIN
      public/img/planet-ocean/fundo.jpg
  82. BIN
      public/img/planet-ocean/thumb.jpg
  83. BIN
      public/img/play.png
  84. +3
    -0
      public/img/play.svg
  85. BIN
      public/img/quebrando-o-tabu/fundo.jpg
  86. BIN
      public/img/quebrando-o-tabu/thumb.jpg
  87. BIN
      public/img/quem-matou-eloa/fundo.jpg
  88. BIN
      public/img/quem-matou-eloa/thumb.jpg
  89. BIN
      public/img/revolution-os/fundo.jpg
  90. BIN
      public/img/revolution-os/thumb.jpg
  91. BIN
      public/img/serra-pelada-a-lenda/fundo.jpg
  92. BIN
      public/img/serra-pelada-a-lenda/thumb.jpg
  93. +0
    -0
      public/img/stars.png
  94. BIN
      public/img/the-code/fundo.jpg
  95. BIN
      public/img/the-code/thumb.jpg
  96. BIN
      public/img/vips/fundo.jpg
  97. BIN
      public/img/vips/thumb.jpg
  98. BIN
      public/img/voltar.png
  99. BIN
      public/img/we-are-legion/fundo.jpg
  100. BIN
      public/img/we-are-legion/thumb.jpg

+ 6
- 0
.gitignore View File

@@ -1,4 +1,10 @@
_jekyll/
_mean/
_vue/
_docs/
_media/
node_modules/

.env

notes.md

+ 189
- 0
config/passport.js View File

@@ -0,0 +1,189 @@
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GithubStrategy = require('passport-github').Strategy;


var User = require('../models/User');

passport.serializeUser(function(user, done) {
done(null, user.id);
});

passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});

// Sign in with Email and Password
passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, password, done) {
User.findOne({ email: email }, function(err, user) {
if (!user) {
return done(null, false, { msg: 'O endereço de e-mail ' + email + ' não está associado com nenhuma conta. ' +
'Cheque seu e-mail e tente novamente.' });
}
user.comparePassword(password, function(err, isMatch) {
if (!isMatch) {
return done(null, false, { msg: 'Endereço de e-mail ou senha inválidos.' });
}
return done(null, user);
});
});
}));

// Sign in with Facebook
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_ID,
clientSecret: process.env.FACEBOOK_SECRET,
callbackURL: '/auth/facebook/callback',
profileFields: ['name', 'email', 'gender', 'location'],
passReqToCallback: true
}, function(req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({ facebook: profile.id }, function(err, user) {
if (user) {
req.flash('error', { msg: 'There is already an existing account linked with Facebook that belongs to you.' });
done(err);
} else {
User.findById(req.user.id, function(err, user) {
user.name = user.name || profile.name.givenName + ' ' + profile.name.familyName;
user.gender = user.gender || profile._json.gender;
user.username = profile.id;
user.picture = user.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large';
user.facebook = profile.id;
user.save(function(err) {
req.flash('success', { msg: 'Your Facebook account has been linked.' });
done(err, user);
});
});
}
});
} else {
User.findOne({ facebook: profile.id }, function(err, user) {
if (user) {
return done(err, user);
}
User.findOne({ email: profile._json.email }, function(err, user) {
if (user) {
req.flash('error', { msg: user.email + ' is already associated with another account.' });
done(err);
} else {
var newUser = new User({
name: profile.name.givenName + ' ' + profile.name.familyName,
email: profile._json.email,
username: profile.id,
gender: profile._json.gender,
location: profile._json.location && profile._json.location.name,
picture: 'https://graph.facebook.com/' + profile.id + '/picture?type=large',
facebook: profile.id
});
newUser.save(function(err) {
done(err, newUser);
});
}
});
});
}
}));

// Sign in with Twitter
passport.use(new TwitterStrategy({
consumerKey: process.env.TWITTER_KEY,
consumerSecret: process.env.TWITTER_SECRET,
callbackURL: '/auth/twitter/callback',
passReqToCallback: true
}, function(req, accessToken, tokenSecret, profile, done) {
if (req.user) {
User.findOne({ twitter: profile.id }, function(err, user) {
if (user) {
req.flash('error', { msg: 'There is already an existing account linked with Twitter that belongs to you.' });
done(err);
} else {
User.findById(req.user.id, function(err, user) {
user.name = user.name || profile.displayName;
user.location = user.location || profile._json.location;
user.picture = user.picture || profile._json.profile_image_url_https;
user.twitter = profile.id;
user.username = profile.id;
user.save(function(err) {
req.flash('success', { msg: 'Your Twitter account has been linked.' });
done(err, user);
});
});
}
});
} else {
User.findOne({ twitter: profile.id }, function(err, existingUser) {
if (existingUser) {
return done(null, existingUser);
}
// Twitter does not provide an email address, but email is a required field in our User schema.
// We can "fake" a Twitter email address as follows: username@twitter.com.
// Ideally, it should be changed by a user to their real email address afterwards.
// For example, after login, check if email contains @twitter.com, then redirect to My Account page,
// and restrict user's page navigation until they update their email address.
var newUser = new User({
name: profile.displayName,
email: profile.username + '@twitter.com',
location: profile._json.location,
picture: profile._json.profile_image_url_https,
twitter: profile.id,
username: profile.username
});
newUser.save(function(err) {
done(err, newUser);
});
});
}
}));

// Sign in with Github
passport.use(new GithubStrategy({
clientID: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
callbackURL: '/auth/github/callback',
passReqToCallback: true
}, function(req, accessToken, refreshToken, profile, done) {
if (req.user) {
User.findOne({ github: profile.id }, function(err, user) {
if (user) {
req.flash('error', { msg: 'There is already an existing account linked with Github that belongs to you.' });
} else {
User.findById(req.user.id, function(err, user) {
user.name = user.name || profile.displayName;
user.picture = user.picture || profile._json.avatar_url;
user.github = profile.id;
user.save(function(err) {
req.flash('success', { msg: 'Your Github account has been linked.' });
done(err, user);
});
});
}
});
} else {
User.findOne({ github: profile.id }, function(err, user) {
if (user) {
return done(null, user);
}
User.findOne({ email: profile.email }, function(err, user) {
if (user) {
req.flash('error', { msg: user.email + ' is already associated with another account.' });
done(err);
} else {
var newUser = new User({
name: profile.displayName,
email: profile._json.email,
location: profile._json.location,
picture: profile._json.avatar_url,
github: profile.id
});
newUser.save(function(err) {
done(err, newUser);
});
}
});
});
}
}));

+ 47
- 0
controllers/contact.js View File

@@ -0,0 +1,47 @@
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'Mailgun',
auth: {
user: process.env.MAILGUN_USERNAME,
pass: process.env.MAILGUN_PASSWORD
}
});

/**
* GET /contact
*/
exports.contactGet = function(req, res) {
res.render('contact', {
title: 'Contato'
});
};

/**
* POST /contact
*/
exports.contactPost = function(req, res) {
req.assert('name', 'Nome não pode estar em branco').notEmpty();
req.assert('email', 'O e-mail inserido não é valido').isEmail();
req.assert('email', 'E-mail é obrigatório').notEmpty();
req.assert('message', 'A mensagem não pode estar em branco').notEmpty();
req.sanitize('email').normalizeEmail({ remove_dots: false });

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('/contato');
}

var mailOptions = {
from: req.body.name + ' ' + '<'+ req.body.email + '>',
to: 'guilmour@alunos.utfpr.edu.br',
subject: 'Formulário de Contato | acredito.me',
text: req.body.message
};

transporter.sendMail(mailOptions, function(err) {
req.flash('success', { msg: 'Obrigado! Sua mensagem foi enviada.' });
res.redirect('/contato');
});
};

+ 18
- 0
controllers/home.js View File

@@ -0,0 +1,18 @@
let Watch = require('../models/Watch');

/**
* GET /
*/

exports.index = function(req, res) {
Watch.find({}, null, {sort: '-year'}, function(err, watch){
if(err){
console.log(err);
} else {
res.render('home', {
title:'Início',
watch: watch
});
}
});
};

+ 36
- 0
controllers/upload.js View File

@@ -0,0 +1,36 @@
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
const uuidV1 = require('uuid/v1');


exports.uploadImage = function(req, res){

// create an incoming form object
var form = new formidable.IncomingForm();

// specify that we want to allow the user to upload multiple files in a single request
form.multiples = false;

// every time a file has been uploaded successfully,
// rename it to it's orignal name
form.on('file', function(field, file) {
fileEndName = uuidV1() + file.name;
fs.rename(file.path, path.join(uploadDir + fileEndName));
});

// log any errors that occur
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});

// once all the files have been uploaded, send a response to the client
form.on('end', function() {
res.end('/media/' + fileEndName);

});

// parse the incoming request containing the form data
form.parse(req);

};

+ 358
- 0
controllers/user.js View File

@@ -0,0 +1,358 @@
var async = require('async');
var crypto = require('crypto');
var nodemailer = require('nodemailer');
var passport = require('passport');
var User = require('../models/User');

/**
* Login required middleware
*/
exports.ensureAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect('/login');
}
};

/**
* GET /login
*/
exports.loginGet = function(req, res) {
if (req.user) {
return res.redirect('/');
}
res.render('account/login', {
title: 'Log in'
});
};

/**
* POST /login
*/
exports.loginPost = function(req, res, next) {
req.assert('email', 'O e-mail inserido não é válido').isEmail();
req.assert('email', 'O e-mail não pode ficar em branco').notEmpty();
req.assert('password', 'A senha não pode ficar em branco').notEmpty();
req.sanitize('email').normalizeEmail({ remove_dots: false });

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('/login');
}

passport.authenticate('local', function(err, user, info) {
if (!user) {
req.flash('error', info);
return res.redirect('/login')
}
req.logIn(user, function(err) {
res.redirect('/');
});
})(req, res, next);
};

/**
* GET /logout
*/
exports.logout = function(req, res) {
req.logout();
res.redirect('/');
};

/**
* GET /signup
*/
exports.signupGet = function(req, res) {
if (req.user) {
return res.redirect('/');
}
res.render('account/signup', {
title: 'Criar conta'
});
};

/**
* POST /signup
*/
exports.signupPost = function(req, res, next) {
req.assert('name', 'O nome não pode ficar em branco').notEmpty();
req.assert('email', 'O e-mail inserido não é válido').isEmail();
req.assert('email', 'O e-mail não pode ficar em branco').notEmpty();
req.assert('password', 'A senha precisa ter pelo menos 4 caracteres').len(4);
req.sanitize('email').normalizeEmail({ remove_dots: false });

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('/signup');
}

User.findOne({ email: req.body.email }, function(err, user) {
if (user) {
req.flash('error', { msg: 'O e-mail inserido já está associado com outra conta.' });
return res.redirect('/signup');
}
user = new User({
name: req.body.name,
username: req.body.username,
email: req.body.email,
password: req.body.password
});
user.save(function(err) {
req.logIn(user, function(err) {
res.redirect('/');
});
});
});

};

/**
* GET /account
*/
exports.accountGet = function(req, res) {
res.render('account/profile', {
title: 'Minha Conta'
});
};

/**
* PUT /account
* Update profile information OR change password.
*/
exports.accountPut = function(req, res, next) {
if ('password' in req.body) {
req.assert('password', 'A senha precisa ter pelo menos 4 caracteres.').len(4);
req.assert('confirm', 'As senhas inseridas não conferem.').equals(req.body.password);
} else {
req.assert('email', 'Este e-mail não é válido.').isEmail();
req.assert('email', 'O campo "Email" precisa ser preenchido.').notEmpty();
req.sanitize('email').normalizeEmail({ remove_dots: false });
}

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('/account');
}

User.findById(req.user.id, function(err, user) {
if ('password' in req.body) {
user.password = req.body.password;
} else {
user.email = req.body.email;
user.username = req.body.username;
user.name = req.body.name;
user.gender = req.body.gender;
user.location = req.body.location;
user.website = req.body.website;
}
user.save(function(err) {
if ('password' in req.body) {
req.flash('success', { msg: 'Sua senha foi redefinida com sucesso.' });
} else if (err && err.code === 11000) {
req.flash('error', { msg: 'E-mail ou username inseridos já estão associados com outra conta.' });
} else {
req.flash('success', { msg: 'Suas informações foram alteradas com sucesso.' });
}
res.redirect('/account');
});
});
};

/**
* DELETE /account
*/
exports.accountDelete = function(req, res, next) {
User.remove({ _id: req.user.id }, function(err) {
req.logout();
req.flash('info', { msg: 'Sua conta foi foi excluída com sucesso.' });
res.redirect('/');
});
};

/**
* GET /unlink/:provider
*/
exports.unlink = function(req, res, next) {
User.findById(req.user.id, function(err, user) {
switch (req.params.provider) {
case 'facebook':
user.facebook = undefined;
break;
case 'google':
user.google = undefined;
break;
case 'twitter':
user.twitter = undefined;
break;
case 'vk':
user.vk = undefined;
break;
case 'github':
user.github = undefined;
break;
default:
req.flash('error', { msg: 'Invalid OAuth Provider' });
return res.redirect('/account');
}
user.save(function(err) {
req.flash('success', { msg: 'Your account has been unlinked.' });
res.redirect('/account');
});
});
};

/**
* GET /forgot
*/
exports.forgotGet = function(req, res) {
if (req.isAuthenticated()) {
return res.redirect('/');
}
res.render('account/forgot', {
title: 'Forgot Password'
});
};

/**
* POST /forgot
*/
exports.forgotPost = function(req, res, next) {
req.assert('email', 'O e-mail não é válido').isEmail();
req.assert('email', ' e-mail não pode ficar em branco').notEmpty();
req.sanitize('email').normalizeEmail({ remove_dots: false });

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('/forgot');
}

async.waterfall([
function(done) {
crypto.randomBytes(16, function(err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function(token, done) {
User.findOne({ email: req.body.email }, function(err, user) {
if (!user) {
req.flash('error', { msg: 'O endereço de e-mail ' + req.body.email + ' não está associado com nenhuma conta.' });
return res.redirect('/forgot');
}
user.passwordResetToken = token;
user.passwordResetExpires = Date.now() + 3600000; // expire in 1 hour
user.save(function(err) {
done(err, token, user);
});
});
},
function(token, user, done) {
var transporter = nodemailer.createTransport({
service: 'Mailgun',
auth: {
user: process.env.MAILGUN_USERNAME,
pass: process.env.MAILGUN_PASSWORD
}
});
var mailOptions = {
to: user.email,
from: 'suporte@acredito.me',
subject: 'Redefinir sua senha no Acredito.me',
text: 'Você está recebendo isso porque você (ou alguma outra pessoa) pediu para redefenir a senha da sua conta.\n\n' +
'Por favor, clieque no link a seguir, ou cole no seu navegador para completar esse processo:\n\n' +
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
'Se você não pediu essa redefinição, por favor ignore este e-mail e a sua senha não sofrerá nenhuma alteração.\n' +
'Obrigado por salvar vidas com o acredito.me\n'
};
transporter.sendMail(mailOptions, function(err) {
req.flash('info', { msg: 'Um e-mail foi enviado para ' + user.email + ' com mais informações.' });
res.redirect('/forgot');
});
}
]);
};

/**
* GET /reset
*/
exports.resetGet = function(req, res) {
if (req.isAuthenticated()) {
return res.redirect('/');
}
User.findOne({ passwordResetToken: req.params.token })
.where('passwordResetExpires').gt(Date.now())
.exec(function(err, user) {
if (!user) {
req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
return res.redirect('/forgot');
}
res.render('account/reset', {
title: 'Redefinir Senha'
});
});
};

/**
* POST /reset
*/
exports.resetPost = function(req, res, next) {
req.assert('password', 'A senha precisa ter ao menos 4 caracteres').len(4);
req.assert('confirm', 'A senhas não são iguais').equals(req.body.password);

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.redirect('back');
}

async.waterfall([
function(done) {
User.findOne({ passwordResetToken: req.params.token })
.where('passwordResetExpires').gt(Date.now())
.exec(function(err, user) {
if (!user) {
req.flash('error', { msg: 'Password reset token is invalid or has expired.' });
return res.redirect('back');
}
user.password = req.body.password;
user.passwordResetToken = undefined;
user.passwordResetExpires = undefined;
user.save(function(err) {
req.logIn(user, function(err) {
done(err, user);
});
});
});
},
function(user, done) {
var transporter = nodemailer.createTransport({
service: 'Mailgun',
auth: {
user: process.env.MAILGUN_USERNAME,
pass: process.env.MAILGUN_PASSWORD
}
});
var mailOptions = {
from: 'suporte@acredito.me',
to: user.email,
subject: 'Sua senha no acredito.me foi alterada',
text: 'Hello,\n\n' +
'Este e-mail é uma confirmação que a senha da sua conta no acredito.me (' + user.email + ') foi alterada recentemente.\n'
};
transporter.sendMail(mailOptions, function(err) {
req.flash('success', { msg: 'Sua senha foi alterada com sucesso.' });
res.redirect('/account');
});
}
]);
};

+ 107
- 0
controllers/watch.js View File

@@ -0,0 +1,107 @@
var Watch = require('../models/Watch');
var mongoose = require('mongoose');
const bodyParser = require('body-parser');


// Get Movie or Series
exports.watchGet = function(req, res){
Watch.findOne({ 'permalink': req.params.permalink }, function(err, w){

if (!w) {
return res.redirect('/404');
}
else{
res.render('watch', {
title: w.title,
layout: w.layout,
subtitle: w.subtitle,
sinopse: w.sinopse,
year: w.year,
imgbg: w.imgbg,
video: w.video,
thumb480: w.thumb480,
thumb130: w.thumb130,
runtime: w.runtime,
eps: w.eps
});
}
});
};


// GET New Production

exports.newWatchGet = function(req, res) {
if (!req.user) {
return res.redirect('/login');
}
res.render('novo', {
title: 'Criar Nova Produção'
});
};

// POST New Production
exports.newWatchPost = function(req, res, next) {


var body = req.body;

// para retornar depois do erro
var form = {
};

var errors = req.validationErrors();

if (errors) {
req.flash('error', errors);
return res.render('novo', {form: form});
}

Watch.findOne({ permalink: req.body.permalink }, function(err, watch) {
if (watch) {
req.flash('error', { msg: 'O permalink inserido já existe. Tente outro.' });
return res.redirect('/novo');
}
// Para salvar no BD
watch = new Watch({
criador: req.user.id,
permalink: req.body.permalink,
layout: 'filme',
featured : true,
title: req.body.title,
subtitle: req.body.subtitle,
sinopse: req.body.sinopse,
year: req.body.year,
classind: req.body.classind,
duration: req.body.duration,
video: req.body.video,
thumb480: req.body.thumb480,
imgbg: req.body.imgbg,
tags: req.body.tags
});
watch.save(function(err) {
//req.logIn(campanha, function(err) {
res.redirect('/');
//});
});
});

};


// GET Tags
exports.tagsGet = function(req, res){
Watch.find({ 'tags': req.params.tags }, null, {sort: '-year'}, function(err, w){

if (!w) {
return res.redirect('/404');
}
else{
res.render('home', {
title: 'Tag',
tag: req.params.tags,
watch: w
});
}
});
};

BIN
imgs/ico-next.png View File

Before After
Width: 28  |  Height: 28  |  Size: 661B

BIN
imgs/ico-play-next.png View File

Before After
Width: 53  |  Height: 55  |  Size: 1.7KB

+ 62
- 0
models/User.js View File

@@ -0,0 +1,62 @@
var crypto = require('crypto');
var bcrypt = require('bcrypt-nodejs');
var mongoose = require('mongoose');

var schemaOptions = {
timestamps: true,
toJSON: {
virtuals: true
}
};

var userSchema = new mongoose.Schema({
username: {type: String, unique: true},
email: {type: String, unique: true},
name: String,
password: String,
passwordResetToken: String,
passwordResetExpires: Date,
gender: String,
location: String,
website: String,
picture: String,
facebook: String,
twitter: String
}, schemaOptions);

userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) { return next(); }
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(user.password, salt, null, function(err, hash) {
user.password = hash;
next();
});
});
});

userSchema.methods.comparePassword = function(password, cb) {
bcrypt.compare(password, this.password, function(err, isMatch) {
cb(err, isMatch);
});
};

userSchema.virtual('gravatar').get(function() {
if (!this.get('email')) {
return 'https://gravatar.com/avatar/?s=200&d=retro';
}
var md5 = crypto.createHash('md5').update(this.get('email')).digest('hex');
return 'https://gravatar.com/avatar/' + md5 + '?s=200&d=retro';
});

userSchema.options.toJSON = {
transform: function(doc, ret, options) {
delete ret.password;
delete ret.passwordResetToken;
delete ret.passwordResetExpires;
}
};

var User = mongoose.model('User', userSchema);

module.exports = User;

+ 41
- 0
models/Watch.js View File

@@ -0,0 +1,41 @@
var mongoose = require('mongoose');

var schemaOptions = {
timestamps: true,
toJSON: {
virtuals: true
}
};

const getTags = tags => tags.join(', ');
const setTags = tags => tags.split(', ');

var watchSchema = new mongoose.Schema({
permalink: {type: String, unique: true},
criador: { type : mongoose.Schema.ObjectId, ref : 'User' },
layout: String,
title: String,
subtitle: String,
sinopse: String,
year: Number,
classind: String,
duration: String,
imgbg: String,
video: String,
thumb480: String,
thumb130: String,
runtime: String,
tags: { type: [], get: getTags, set: setTags },
featured: Boolean,
n_eps: Number,
eps: [{ last: Boolean,
subtitle : String,
video : String,
thumb480 : String,
thumb130 : String}]
}, schemaOptions);


var Watch = mongoose.model('Watch', watchSchema);

module.exports = Watch;

+ 34
- 0
package.json View File

@@ -0,0 +1,34 @@
{
"name": "acredito.me",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"async": "^1.5.2",
"bcrypt-nodejs": "^0.0.3",
"body-parser": "^1.15.1",
"compression": "^1.6.2",
"dotenv": "^2.0.0",
"express": "^4.13.4",
"express-flash": "0.0.2",
"express-session": "^1.2.1",
"express-validator": "^2.20.4",
"method-override": "^2.3.5",
"mongoose": "^4.4.8",
"morgan": "^1.7.0",
"nodemailer": "^2.3.0",
"nunjucks": "^2.4.1",
"passport": "^0.3.2",
"passport-facebook": "^2.1.0",
"passport-github": "^1.1.0",
"passport-local": "^1.0.0",
"passport-twitter": "^1.0.4",
"formidable": "^1.0.17"
},
"devDependencies": {},
"engines": {
"node": "6.1.0"
}
}

+ 41
- 0
public/css/blog_focus.css View File

@@ -0,0 +1,41 @@

.image-wrap {
position: relative;
min-height: 600px;
overflow: hidden;
}

.header-img {
position: absolute;
width: 100%;
min-height: 600px;
-webkit-transform: translate3d(0, 0, 0);
}
.title-etc {
margin: 0 auto;
margin-top: 20%;
max-width: 750px;
color: #6D6A6A;
}
.focus-post-date{
font-style: italic;
}
body {
font-size: 1.2em;
color: rgba(0, 0, 0, 0.8);
font-family: Georgia, Cambria, 'Times New Roman', Times, serif;
line-height: 1.8em;
}
body h1, body h2, body h3, body h4 {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Geneva, Verdana, sans-serif;
letter-spacing: -0.04em;
line-height: 1.15em;
}

.menu {
background-color: #fff;
font-family: helvetica, sans-serif;
line-height: 1.5;
font-size: 17px;
margin: 0 auto;
}

+ 496
- 0
public/css/custom.css View File

@@ -0,0 +1,496 @@
/* styles */
.videoWrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.videoWrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

.titlePlayer{
color: #DCDCDC !important;
text-shadow: 2px 2px #000 !important;
}

.exitTimes{
color: #fff;
}

.fadeCatalogo{
border-bottom: 0px solid;
opacity:0;
-moz-transition: opacity 2s;
-webkit-transition: opacity 2s;
-o-transition: opacity 2s;
transition: opacity 2s;
}
#lb-logo {opacity:0;
-moz-transition: opacity 2s; /* Firefox 4 */
-webkit-transition: opacity 2s; /* Safari and Chrome */
-o-transition: opacity 2s;
transition: opacity 2s;
}
.login-container {
max-width: 655px;
}

*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
background-color: #000 !important;
font-family: helvetica, sans-serif!important;
line-height: 1.5!important;
font-size: 17px!important;
margin: 0 auto !important;
color: #A9A9A9 !important;
}
img {
max-width: 100%;
}
a {
color: gray !important;
text-decoration: none !important;
}
a:hover {
opacity: .7 !important;
}
nav a {
border-bottom: none;
}
nav a:hover, nav a.active {
border-bottom: 1px solid;
opacity: 1;
}
.header {
padding-top: 0px;
}
.logo a, .main-nav a {
text-decoration: none;
color: #222;
}
.logo p {
font-size: 42px;
margin-top: 0;
}
.main-nav {
text-align: right;
}
.main-nav a {
font-size: 28px;
margin-right: 30px;
}
.main-nav .navlink-contact {
margin-right: 0;
}
.tagline {
font-size: 20px;
}
.single-project .grid {
padding-top: 40px;
}
.skills img {
width: 48%;
padding-bottom: 30px;
}
section {
padding: 0px 0;
}
h2{
color: #A9A9A9 !important;
}
.tag {
background-color: rgba(0, 0, 0, 0.05);
border-radius: 4px;
margin-right: 4px;
padding: 4px 6px;
text-transform: capitalize;
}
.entries {
padding-left: 0;
position: relative;
overflow:auto;
text-align:
}
.entries ul {
padding-left: 0;
}
.entries li {
list-style: none;h2
}
.work [class*='col-'] img {
width: 100%;
margin-top: 30px;
}
.work .col-1-2 {
padding-bottom: 20px;
}
.work h2, .contact h2 {
font-weight: normal;
}
.container.about {
padding-top: 20px;
}
/* make a grid */

[class*='col-'] {
float: left;
}
.grid:after {
content: "";
display: table;
clear: both;
}
.grid {
margin-left: -10px;
margin-right: -10px;
}
[class*='col-'] {
padding-left: 10px;
padding-right: 10px;
}
.col-1-2 {
width: 50%;
}
.col-1-3 {
width: 33.33%;
margin-bottom: 25px;
}
.col-2-3 {
width: 66.66%;
}
.col-1-4 {
width: 23%;
margin-bottom: 25px;
}

.container {
width: 90% !important;
margin: 0 auto;
padding-top: 30px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
position: relative;
}

/* single project */
.single-project .tagline {
padding-top: 10px;
}
.work-img {
max-width: 100%;
padding-bottom: 30px;
}
.single-project .grid {
text-align: center;
}
.centerBlock {
text-align: center;
}

@media all and (max-width: 760px) {
.work-img {
width: 100%;
}
}

@media all and (max-width: 560px) {
[class*='col-'] {
width: 100%;
}
.main-nav a {
font-size: 23px;
margin-right: 18px;
}
.tagline {
font-size: 19px;
}
.main-nav {
text-align: left;
}
.header {
padding-top: 22px;
}
.logo p {
margin-bottom: 12px;
}
.main-nav > img {
padding-bottom: 12px;
}
section {
padding: 0px 0;
}
}

.text-center {
text-align: center
}
.byline {
font-style: italic;
}

.contact-links {
color: gray;
}
.contact-links ul li {
display: inline;
text-align:right;
}

.contact-links a {
border-bottom: none;
color:#000;
opacity: .8;
}
.contact-links a:hover, nav a.active {
border-bottom: 1px solid;
opacity: .8;
}

.contact ul li {
list-style-type: none;
}
.bio {
font-size:26px;
}

.lead-in {
font-size:20px;
}

.single-blog-post img, .single-blog-post video {
width: 100%;
padding: 0% 5% 0% 5%;
}
.single-blog-post .caption {
padding: 0 5% 2% 5%;
font-style: italic;
}

.hide {
display: none !important;
}
.show {
display: block !important;
}



/* Buttons */
button.list-group-item-success {
color: #3c763d;
}
a.list-group-item-success .list-group-item-heading,
button.list-group-item-success .list-group-item-heading {
color: inherit;
}
a.list-group-item-success:hover,
button.list-group-item-success:hover,
a.list-group-item-success:focus,
button.list-group-item-success:focus {
color: #3c763d;
background-color: #d0e9c6;
}
a.list-group-item-success.active,
button.list-group-item-success.active,
a.list-group-item-success.active:hover,
button.list-group-item-success.active:hover,
a.list-group-item-success.active:focus,
button.list-group-item-success.active:focus {
color: #fff;
background-color: #3c763d;
border-color: #3c763d;
}
.list-group-item-info {
color: #31708f;
background-color: #d9edf7;
}
a.list-group-item-info,
button.list-group-item-info {
color: #31708f;
}
a.list-group-item-info .list-group-item-heading,
button.list-group-item-info .list-group-item-heading {
color: inherit;
}
a.list-group-item-info:hover,
button.list-group-item-info:hover,
a.list-group-item-info:focus,
button.list-group-item-info:focus {
color: #31708f;
background-color: #c4e3f3;
}
a.list-group-item-info.active,
button.list-group-item-info.active,
a.list-group-item-info.active:hover,
button.list-group-item-info.active:hover,
a.list-group-item-info.active:focus,
button.list-group-item-info.active:focus {
color: #fff;
background-color: #31708f;
border-color: #31708f;
}
.list-group-item-warning {
color: #8a6d3b;
background-color: #fcf8e3;
}
a.list-group-item-warning,
button.list-group-item-warning {
color: #8a6d3b;
}
a.list-group-item-warning .list-group-item-heading,
button.list-group-item-warning .list-group-item-heading {
color: inherit;
}
a.list-group-item-warning:hover,
button.list-group-item-warning:hover,
a.list-group-item-warning:focus,
button.list-group-item-warning:focus {
color: #8a6d3b;
background-color: #faf2cc;
}
a.list-group-item-warning.active,
button.list-group-item-warning.active,
a.list-group-item-warning.active:hover,
button.list-group-item-warning.active:hover,
a.list-group-item-warning.active:focus,
button.list-group-item-warning.active:focus {
color: #fff;
background-color: #8a6d3b;
border-color: #8a6d3b;
}
.list-group-item-danger {
color: #a94442;
background-color: #f2dede;
}
a.list-group-item-danger,
button.list-group-item-danger {
color: #a94442;
}
a.list-group-item-danger .list-group-item-heading,
button.list-group-item-danger .list-group-item-heading {
color: inherit;
}
a.list-group-item-danger:hover,
button.list-group-item-danger:hover,
a.list-group-item-danger:focus,
button.list-group-item-danger:focus {
color: #a94442;
background-color: #ebcccc;
}
a.list-group-item-danger.active,
button.list-group-item-danger.active,
a.list-group-item-danger.active:hover,
button.list-group-item-danger.active:hover,
a.list-group-item-danger.active:focus,
button.list-group-item-danger.active:focus {
color: #fff;
background-color: #a94442;
border-color: #a94442;
}
button.close {
-webkit-appearance: none;
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
}
button,
input,
optgroup,
select,
textarea {
margin: 0;
font: inherit;
color: inherit;
}
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 {
padding: 0;
border: 0;
}
input {
line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
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-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
-webkit-appearance: textfield;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}

.sinopse{
font-size: 10.1pt;
}
.splash{
height: 173px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.splash-play{
float: left;
background: transparent;
-webkit-appearance: none;
border: 0px;
padding-left: 45%;
padding-top: 56.5px;
opacity: 0.6;
outline:none;
}
.splash-play:hover,
.splash-play:focus {
opacity: 1;
}

.classind{
text-transform: uppercase;
border: 1px solid #333;
padding: 0 5px;
}

.panel-novo{
max-width: 900px;
}

+ 4
- 0
public/css/font-awesome.min.css
File diff suppressed because it is too large
View File


+ 7
- 0
public/css/jquery.tagsinput.css View File

@@ -0,0 +1,7 @@
div.tagsinput { border:1px solid #CCC; background: #FFF; padding:5px; width:300px; height:100px; overflow-y: auto;}
div.tagsinput span.tag { border: 1px solid #a5d24a; -moz-border-radius:2px; -webkit-border-radius:2px; display: block; float: left; padding: 5px; text-decoration:none; background: #cde69c; color: #638421; margin-right: 5px; margin-bottom:5px;font-family: helvetica; font-size:13px;}
div.tagsinput span.tag a { font-weight: bold; color: #82ad2b; text-decoration:none; font-size: 11px; }
div.tagsinput input { width:80px; margin:0px; font-family: helvetica; font-size: 13px; border:1px solid transparent; padding:5px; background: transparent; color: #000; outline:0px; margin-right:5px; margin-bottom:5px; }
div.tagsinput div { display:block; float: left; }
.tags_clear { clear: both; width: 100%; height: 0px; }
.not_valid {background: #FBD8DB !important; color: #90111A !important;}

+ 311
- 0
public/css/main.css View File

@@ -0,0 +1,311 @@
/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */

/*
* What follows is the result of much research on cross-browser styling.
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
* Kroc Camen, and the H5BP dev community and team.
*/

/* ==========================================================================
Base styles: opinionated defaults
========================================================================== */

html,
button,
input,
select,
textarea {
color: #d6d6d6;
}

html {
font-size: 1em;
line-height: 1.4;
}

#lb-logo {opacity:0;
-moz-transition: opacity 2s; /* Firefox 4 */
-webkit-transition: opacity 2s; /* Safari and Chrome */
-o-transition: opacity 2s;
transition: opacity 2s;
}

/*
* Remove text-shadow in selection highlight: h5bp.com/i
* These selection rule sets have to be separate.
* Customize the background color to match your design.
*/

::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}

::selection {
background: #b3d4fc;
text-shadow: none;
}

/*
* A better looking default horizontal rule
*/

hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}

/*
* Remove the gap between images, videos, audio and canvas and the bottom of
* their containers: h5bp.com/i/440
*/

audio,
canvas,
img,
video {
vertical-align: middle;
}

/*
* Remove default fieldset styles.
*/

fieldset {
border: 0;
margin: 0;
padding: 0;
}

/*
* Allow only vertical resizing of textareas.
*/

textarea {
resize: vertical;
}

/* ==========================================================================
Browse Happy prompt
========================================================================== */

.browsehappy {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}

/* ==========================================================================
Author's custom styles
========================================================================== */

















/* ==========================================================================
Helper classes
========================================================================== */

/*
* Image replacement
*/

.ir {
background-color: transparent;
border: 0;
overflow: hidden;
/* IE 6/7 fallback */
*text-indent: -9999px;
}

.ir:before {
content: "";
display: block;
width: 0;
height: 150%;
}

/*
* Hide from both screenreaders and browsers: h5bp.com/u
*/

.hidden {
display: none !important;
visibility: hidden;
}

/*
* Hide only visually, but have it available for screenreaders: h5bp.com/v
*/

.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}

/*
* Extends the .visuallyhidden class to allow the element to be focusable
* when navigated to via the keyboard: h5bp.com/p
*/

.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto;
}

/*
* Hide visually and from screenreaders, but maintain layout
*/

.invisible {
visibility: hidden;
}

/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/

.clearfix:before,
.clearfix:after {
content: " "; /* 1 */
display: table; /* 2 */
}

.clearfix:after {
clear: both;
}

/*
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/

.clearfix {
*zoom: 1;
}

/* ==========================================================================
EXAMPLE Media Queries for Responsive Design.
These examples override the primary ('mobile first') styles.
Modify as content requires.
========================================================================== */

@media only screen and (min-width: 35em) {
/* Style adjustments for viewports that meet the condition */
}

@media print,
(-o-min-device-pixel-ratio: 5/4),
(-webkit-min-device-pixel-ratio: 1.25),
(min-resolution: 120dpi) {
/* Style adjustments for high resolution devices */
}

/* ==========================================================================
Print styles.
Inlined to avoid required HTTP connection: h5bp.com/r
========================================================================== */

@media print {
* {
background: transparent !important;
color: #000 !important; /* Black prints faster: h5bp.com/s */
box-shadow: none !important;
text-shadow: none !important;
}

a,
a:visited {
text-decoration: underline;
}

a[href]:after {
content: " (" attr(href) ")";
}

abbr[title]:after {
content: " (" attr(title) ")";
}

/*
* Don't show links for images, or javascript/internal links
*/

.ir a:after,
a[href^="javascript:"]:after,
a[href^="#"]:after {
content: "";
}

pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}

thead {
display: table-header-group; /* h5bp.com/t */
}

tr,
img {
page-break-inside: avoid;
}

img {
max-width: 100% !important;
}

@page {
margin: 0.5cm;
}

p,
h2,
h3 {
orphans: 3;
widows: 3;
}

h2,
h3 {
page-break-after: avoid;
}
}

+ 527
- 0
public/css/normalize.css View File

@@ -0,0 +1,527 @@
/*! normalize.css v1.1.3 | MIT License | git.io/normalize */

/* ==========================================================================
HTML5 display definitions
========================================================================== */

/**
* Correct `block` display not defined in IE 6/7/8/9 and Firefox 3.
*/

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
display: block;
}

/**
* Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
*/

audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}

/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/

audio:not([controls]) {
display: none;
height: 0;
}

/**
* Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.
* Known issue: no IE 6 support.
*/

[hidden] {
display: none;
}

/* ==========================================================================
Base
========================================================================== */

/**
* 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using
* `em` units.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
*/

html {
font-size: 100%; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}

/**
* Address `font-family` inconsistency between `textarea` and other form
* elements.
*/

html,
button,
input,
select,
textarea {
font-family: sans-serif;
}

/**
* Address margins handled incorrectly in IE 6/7.
*/

body {
margin: 0;
}

/* ==========================================================================
Links
========================================================================== */

/**
* Address `outline` inconsistency between Chrome and other browsers.
*/

a:focus {
outline: thin dotted;
}

/**
* Improve readability when focused and also mouse hovered in all browsers.
*/

a:active,
a:hover {
outline: 0;
}

/* ==========================================================================
Typography
========================================================================== */

/**
* Address font sizes and margins set differently in IE 6/7.
* Address font sizes within `section` and `article` in Firefox 4+, Safari 5,
* and Chrome.
*/

h1 {
font-size: 2em;
margin: 0.67em 0;
}

h2 {
font-size: 1.5em;
margin: 0.83em 0;
}

h3 {
font-size: 1.17em;
margin: 1em 0;
}

h4 {
font-size: 1em;
margin: 1.33em 0;
}

h5 {
font-size: 0.83em;
margin: 1.67em 0;
}

h6 {
font-size: 0.67em;
margin: 2.33em 0;
}

/**
* Address styling not present in IE 7/8/9, Safari 5, and Chrome.
*/

abbr[title] {
border-bottom: 1px dotted;
}

/**
* Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
*/

b,
strong {
font-weight: bold;
}

blockquote {
margin: 1em 40px;
}

/**
* Address styling not present in Safari 5 and Chrome.
*/

dfn {
font-style: italic;
}

/**
* Address differences between Firefox and other browsers.
* Known issue: no IE 6/7 normalization.
*/

hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}

/**
* Address styling not present in IE 6/7/8/9.
*/

mark {
background: #ff0;
color: #000;
}

/**
* Address margins set differently in IE 6/7.
*/

p,
pre {
margin: 1em 0;
}

/**
* Correct font family set oddly in IE 6, Safari 4/5, and Chrome.
*/

code,
kbd,
pre,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}

/**
* Improve readability of pre-formatted text in all browsers.
*/

pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}

/**
* Address CSS quotes not supported in IE 6/7.
*/

q {
quotes: none;
}

/**
* Address `quotes` property not supported in Safari 4.
*/

q:before,
q:after {
content: '';
content: none;
}

/**
* Address inconsistent and variable font size in all browsers.
*/

small {
font-size: 80%;
}

/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
*/

sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}

sup {
top: -0.5em;
}

sub {
bottom: -0.25em;
}

/* ==========================================================================
Lists
========================================================================== */

/**
* Address margins set differently in IE 6/7.
*/

dl,
menu,
ol,
ul {
margin: 1em 0;
}

dd {
margin: 0 0 0 40px;
}

/**
* Address paddings set differently in IE 6/7.
*/

menu,
ol,
ul {
padding: 0 0 0 40px;
}

/**
* Correct list images handled incorrectly in IE 7.
*/

nav ul,
nav ol {
list-style: none;
list-style-image: none;
}

/* ==========================================================================
Embedded content
========================================================================== */

/**
* 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.
* 2. Improve image quality when scaled in IE 7.
*/

img {
border: 0; /* 1 */
-ms-interpolation-mode: bicubic; /* 2 */
}

/**
* Correct overflow displayed oddly in IE 9.