119
app.js
119
app.js
@ -208,16 +208,26 @@ app.get('/deploy-a-website', resourcesController.deployAWebsite);
|
|||||||
app.get('/gmail-shortcuts', resourcesController.gmailShortcuts);
|
app.get('/gmail-shortcuts', resourcesController.gmailShortcuts);
|
||||||
app.get('/control-shortcuts', resourcesController.controlShortcuts);
|
app.get('/control-shortcuts', resourcesController.controlShortcuts);
|
||||||
app.get('/control-shortcuts', resourcesController.deployAWebsite);
|
app.get('/control-shortcuts', resourcesController.deployAWebsite);
|
||||||
app.get('/stats', resourcesController.stats);
|
app.get('/stats', function(req, res) {
|
||||||
|
res.redirect(301, '/learn-to-code');
|
||||||
|
});
|
||||||
app.get(
|
app.get(
|
||||||
'/pair-program-with-team-viewer',
|
'/pair-program-with-team-viewer',
|
||||||
resourcesController.pairProgramWithTeamViewer
|
resourcesController.pairProgramWithTeamViewer
|
||||||
);
|
);
|
||||||
app.get('/learn-to-code', resourcesController.about);
|
app.get('/learn-to-code', resourcesController.about);
|
||||||
app.get('/about', resourcesController.about);
|
app.get('/about', function(req, res) {
|
||||||
app.get('/login', userController.getLogin);
|
res.redirect(301, '/learn-to-code');
|
||||||
app.post('/login', userController.postLogin);
|
});
|
||||||
app.get('/logout', userController.logout);
|
app.get('/signin', userController.getSignin);
|
||||||
|
app.get('/login', function(req, res) {
|
||||||
|
res.redirect(301, '/signin');
|
||||||
|
});
|
||||||
|
app.post('/signin', userController.postSignin);
|
||||||
|
app.get('/signout', userController.signout);
|
||||||
|
app.get('/logout', function(req, res) {
|
||||||
|
res.redirect(301, '/signout');
|
||||||
|
});
|
||||||
app.get('/forgot', userController.getForgot);
|
app.get('/forgot', userController.getForgot);
|
||||||
app.post('/forgot', userController.postForgot);
|
app.post('/forgot', userController.postForgot);
|
||||||
app.get('/reset/:token', userController.getReset);
|
app.get('/reset/:token', userController.getReset);
|
||||||
@ -225,7 +235,7 @@ app.post('/reset/:token', userController.postReset);
|
|||||||
app.get('/email-signup', userController.getEmailSignup);
|
app.get('/email-signup', userController.getEmailSignup);
|
||||||
app.get('/email-signin', userController.getEmailSignin);
|
app.get('/email-signin', userController.getEmailSignin);
|
||||||
app.post('/email-signup', userController.postEmailSignup);
|
app.post('/email-signup', userController.postEmailSignup);
|
||||||
app.post('/email-signin', userController.postLogin);
|
app.post('/email-signin', userController.postSignin);
|
||||||
app.get('/nonprofits', contactController.getNonprofitsForm);
|
app.get('/nonprofits', contactController.getNonprofitsForm);
|
||||||
app.post('/nonprofits', contactController.postNonprofitsForm);
|
app.post('/nonprofits', contactController.postNonprofitsForm);
|
||||||
|
|
||||||
@ -255,14 +265,93 @@ app.get(
|
|||||||
);
|
);
|
||||||
app.all('/account', passportConf.isAuthenticated);
|
app.all('/account', passportConf.isAuthenticated);
|
||||||
app.get('/account/api', userController.getAccountAngular);
|
app.get('/account/api', userController.getAccountAngular);
|
||||||
app.get('/bonfire', bonfireController.index);
|
|
||||||
|
/**
|
||||||
|
* Bonfire related routes
|
||||||
|
*/
|
||||||
|
app.get('/playground', bonfireController.index);
|
||||||
|
app.get('/bonfires', bonfireController.returnNextBonfire);
|
||||||
|
app.get('/bonfire-json-generator', bonfireController.returnGenerator);
|
||||||
|
app.post('/bonfire-json-generator', bonfireController.generateChallenge);
|
||||||
|
app.get('/bonfire-challenge-generator', bonfireController.publicGenerator);
|
||||||
|
app.post('/bonfire-challenge-generator', bonfireController.testBonfire)
|
||||||
app.get(
|
app.get(
|
||||||
'/bonfire/:bonfireNumber',
|
'/bonfires/:bonfireName',
|
||||||
bonfireController.returnBonfire
|
bonfireController.returnIndividualBonfire
|
||||||
);
|
);
|
||||||
|
app.get('/bonfire', function(req, res) {
|
||||||
|
res.redirect(301, '/playground');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/completed-bonfire/', function (req, res) {
|
||||||
|
var isCompletedWith = req.body.bonfireInfo.completedWith || undefined;
|
||||||
|
var isCompletedDate = Math.round(+new Date() / 1000);
|
||||||
|
var bonfireHash = req.body.bonfireInfo.bonfireHash;
|
||||||
|
var isSolution = req.body.bonfireInfo.solution;
|
||||||
|
// TODO
|
||||||
|
debug(isCompletedWith, 'Is completed with');
|
||||||
|
|
||||||
|
if (isCompletedWith) {
|
||||||
|
var paired = User.find({"profile.username": isCompletedWith}).limit(1);
|
||||||
|
paired.exec(function(err, pairedWith) {
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
var index = req.user.uncompletedBonfires.indexOf(bonfireHash);
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
req.user.uncompletedBonfires.splice(index,1)
|
||||||
|
}
|
||||||
|
pairedWith = pairedWith.pop();
|
||||||
|
|
||||||
|
//debug('This is paired with', Object.keys(pairedWith));
|
||||||
|
debug('This is paired with\'s uncompleted bonfires array', pairedWith.uncompletedBonfires);
|
||||||
|
index = pairedWith.uncompletedBonfires.indexOf(bonfireHash);
|
||||||
|
if (index > -1) {
|
||||||
|
pairedWith.uncompletedBonfires.splice(index,1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pairedWith.completedBonfires.push({
|
||||||
|
_id: bonfireHash,
|
||||||
|
completedWith: req.user._id,
|
||||||
|
completedDate: isCompletedDate,
|
||||||
|
solution: isSolution
|
||||||
|
})
|
||||||
|
|
||||||
|
req.user.completedBonfires.push({
|
||||||
|
_id: bonfireHash,
|
||||||
|
completedWith: pairedWith._id,
|
||||||
|
completedDate: isCompletedDate,
|
||||||
|
solution: isSolution
|
||||||
|
})
|
||||||
|
|
||||||
|
req.user.save();
|
||||||
|
pairedWith.save();
|
||||||
|
res.redirect('/bonfires');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
req.user.completedBonfires.push({
|
||||||
|
_id: bonfireHash,
|
||||||
|
completedWith: null,
|
||||||
|
completedDate: isCompletedDate,
|
||||||
|
solution: isSolution
|
||||||
|
})
|
||||||
|
|
||||||
|
var index = req.user.uncompletedBonfires.indexOf(bonfireHash);
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
req.user.uncompletedBonfires.splice(index,1)
|
||||||
|
}
|
||||||
|
req.user.save();
|
||||||
|
res.redirect('/bonfires');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// Unique Check API route
|
// Unique Check API route
|
||||||
app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername);
|
app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername);
|
||||||
|
app.get('/api/checkExistingUsername/:username', userController.checkExistingUsername);
|
||||||
app.get('/api/checkUniqueEmail/:email', userController.checkUniqueEmail);
|
app.get('/api/checkUniqueEmail/:email', userController.checkUniqueEmail);
|
||||||
app.get('/account', userController.getAccount);
|
app.get('/account', userController.getAccount);
|
||||||
app.post('/account/profile', userController.postUpdateProfile);
|
app.post('/account/profile', userController.postUpdateProfile);
|
||||||
@ -280,14 +369,14 @@ app.get('/account/unlink/:provider', userController.getOauthUnlink);
|
|||||||
app.post('/completed-challenge', function (req, res) {
|
app.post('/completed-challenge', function (req, res) {
|
||||||
req.user.challengesHash[parseInt(req.body.challengeNumber)] =
|
req.user.challengesHash[parseInt(req.body.challengeNumber)] =
|
||||||
Math.round(+new Date() / 1000);
|
Math.round(+new Date() / 1000);
|
||||||
var ch = req.user.challengesHash;
|
var timestamp = req.user.challengesHash;
|
||||||
var p = 0;
|
var points = 0;
|
||||||
for (var k in ch) {
|
for (var key in timestamp) {
|
||||||
if (ch[k] > 0) {
|
if (timestamp[key] > 0) {
|
||||||
p += 1;
|
points += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
req.user.points = p;
|
req.user.points = points;
|
||||||
req.user.save();
|
req.user.save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,78 +1,232 @@
|
|||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
debug = require('debug')('freecc:cntr:bonfires'),
|
debug = require('debug')('freecc:cntr:bonfires'),
|
||||||
Bonfire = require('./../models/Bonfire');
|
Bonfire = require('./../models/Bonfire'),
|
||||||
|
User = require('./../models/User'),
|
||||||
|
resources = require('./resources');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bonfire controller
|
* Bonfire controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var highestBonfireNumber = 1;
|
var highestBonfireNumber = resources.numberOfBonfires();
|
||||||
|
|
||||||
exports.index = function(req, res) {
|
exports.index = function(req, res) {
|
||||||
res.render('bonfire/bonfire.jade', {
|
res.render('bonfire/show.jade', {
|
||||||
title: 'Learn to code with Bonfire'
|
completedWith: null,
|
||||||
});
|
title: 'Bonfire Playground',
|
||||||
|
name: 'Bonfire Playground',
|
||||||
|
difficulty: 0,
|
||||||
|
brief: 'Feel free to play around!',
|
||||||
|
details: '',
|
||||||
|
tests: [],
|
||||||
|
challengeSeed: '',
|
||||||
|
challengeEntryPoint: '',
|
||||||
|
cc: req.user ? req.user.bonfiresHash : undefined,
|
||||||
|
points: req.user ? req.user.points : undefined,
|
||||||
|
verb: resources.randomVerb(),
|
||||||
|
phrase: resources.randomPhrase(),
|
||||||
|
compliments: resources.randomCompliment(),
|
||||||
|
bonfires: [],
|
||||||
|
bonfireHash: 'test'
|
||||||
|
|
||||||
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, c) {
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.returnNextBonfire = function(req, res, next) {
|
||||||
|
// TODO
|
||||||
|
//var tempUser = false;
|
||||||
|
if (!req.user) {
|
||||||
|
res.redirect('bonfires/meet-bonfire');
|
||||||
|
//tempUser = true;
|
||||||
|
//req.user = new User();
|
||||||
|
}
|
||||||
|
var currentTime = parseInt(+new Date() / 1000)
|
||||||
|
if (currentTime - req.user.lastContentSync > 86400) {
|
||||||
|
req.user.lastContentSync = currentTime;
|
||||||
|
var completed = req.user.completedBonfires.map(function(elem) {
|
||||||
|
return elem._id;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.user.uncompletedBonfires = resources.allBonfireIds().filter(function(elem) {
|
||||||
|
if (completed.indexOf(elem) === -1) {
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
req.user.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var uncompletedBonfires = req.user.uncompletedBonfires;
|
||||||
|
|
||||||
|
|
||||||
|
var displayedBonfires = Bonfire.find({'_id': uncompletedBonfires[0]});
|
||||||
|
displayedBonfires.exec(function(err, bonfire) {
|
||||||
if (err) {
|
if (err) {
|
||||||
debug('bonfire err: ', err);
|
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nameString = bonfire[0].name.toLowerCase().replace(/\s/g, '-');
|
||||||
|
return res.redirect('/bonfires/' + nameString);
|
||||||
|
//res.render('bonfire/show', {
|
||||||
|
// completedWith: null,
|
||||||
|
// title: bonfire[bonfireNumber].name,
|
||||||
|
// name: bonfire[bonfireNumber].name,
|
||||||
|
// difficulty: +bonfire[bonfireNumber].difficulty,
|
||||||
|
// brief: bonfire[bonfireNumber].description[0],
|
||||||
|
// details: bonfire[bonfireNumber].description.slice(1),
|
||||||
|
// tests: bonfire[bonfireNumber].tests,
|
||||||
|
// challengeSeed: bonfire[bonfireNumber].challengeSeed,
|
||||||
|
// challengeEntryPoint: bonfire[bonfireNumber].challengeEntryPoint,
|
||||||
|
// cc: req.user ? req.user.bonfiresHash : undefined,
|
||||||
|
// points: req.user ? req.user.points : undefined,
|
||||||
|
// verb: resources.randomVerb(),
|
||||||
|
// phrase: resources.randomPhrase(),
|
||||||
|
// compliments: resources.randomCompliment(),
|
||||||
|
// bonfires: bonfire,
|
||||||
|
// bonfireHash: bonfire[bonfireNumber]._id
|
||||||
|
//});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.returnIndividualBonfire = function(req, res, next) {
|
||||||
|
var bonfireName = req.params.bonfireName;
|
||||||
|
|
||||||
|
bonfireName = bonfireName.replace(/\-/g, ' ');
|
||||||
|
var bonfireNumber = 0;
|
||||||
|
|
||||||
|
Bonfire.find({"name" : new RegExp(bonfireName, 'i')}, function(err, bonfire) {
|
||||||
|
if (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
if (bonfire.length < 1) {
|
||||||
|
debug('Full Bonfire', bonfire);
|
||||||
|
req.flash('errors', {
|
||||||
|
msg: "404: We couldn't find a bonfire with that name. Please double check the name."
|
||||||
|
});
|
||||||
|
return res.redirect('/bonfires/meet-bonfire')
|
||||||
|
} else {
|
||||||
|
res.render('bonfire/show', {
|
||||||
|
completedWith: null,
|
||||||
|
title: bonfire[bonfireNumber].name,
|
||||||
|
name: bonfire[bonfireNumber].name,
|
||||||
|
difficulty: +bonfire[bonfireNumber].difficulty,
|
||||||
|
brief: bonfire[bonfireNumber].description[0],
|
||||||
|
details: bonfire[bonfireNumber].description.slice(1),
|
||||||
|
tests: bonfire[bonfireNumber].tests,
|
||||||
|
challengeSeed: bonfire[bonfireNumber].challengeSeed,
|
||||||
|
challengeEntryPoint: bonfire[bonfireNumber].challengeEntryPoint,
|
||||||
|
cc: !!req.user,
|
||||||
|
points: req.user ? req.user.points : undefined,
|
||||||
|
verb: resources.randomVerb(),
|
||||||
|
phrase: resources.randomPhrase(),
|
||||||
|
compliment: resources.randomCompliment(),
|
||||||
|
bonfires: bonfire,
|
||||||
|
bonfireHash: bonfire[bonfireNumber]._id
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.returnBonfire = function(req, res, next) {
|
/**
|
||||||
var bonfireNumber = parseInt(req.params.bonfireNumber) || 0;
|
* Bonfire generator
|
||||||
var verbs = [
|
*/
|
||||||
'ACED',
|
exports.returnGenerator = function(req, res) {
|
||||||
'NAILED',
|
res.render('bonfire/generator', {
|
||||||
'ROCKED',
|
title: null,
|
||||||
'SCORCHED',
|
name: null,
|
||||||
'DEVASTATED',
|
difficulty: null,
|
||||||
'OWNED',
|
brief: null,
|
||||||
'CRUSHED',
|
details: null,
|
||||||
'CONQUERED',
|
tests: null,
|
||||||
'KILLED',
|
challengeSeed: null,
|
||||||
'SHREDDED',
|
challengeEntryPoint: null,
|
||||||
'ANNIHILATED',
|
bonfireHash: randomString()
|
||||||
'NUKED'
|
|
||||||
];
|
|
||||||
var phrases = [
|
|
||||||
"Shout it from on top of a mountain",
|
|
||||||
"Tell everyone and their dogs",
|
|
||||||
"Show them. Show them all!",
|
|
||||||
"Inspire your friends",
|
|
||||||
"Tell the world of your greatness",
|
|
||||||
"Look accomplished on social media",
|
|
||||||
"Share news of your grand endeavor",
|
|
||||||
"Establish your alibi for the past two hours",
|
|
||||||
"Prove to mom that computers aren't just for games"
|
|
||||||
];
|
|
||||||
|
|
||||||
if (bonfireNumber > highestBonfireNumber) { bonfireNumber = 0; }
|
|
||||||
Bonfire.find({}, null, { sort: { bonfireNumber: 1 } }, function(err, bonfire) {
|
|
||||||
debug(bonfire[bonfireNumber].challengeEntryPoint);
|
|
||||||
if (err) {
|
|
||||||
debug('bonfire err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
res.render('bonfire/show', {
|
|
||||||
title: bonfire[bonfireNumber].name,
|
|
||||||
name: bonfire[bonfireNumber].name,
|
|
||||||
number: bonfire[bonfireNumber].bonfireNumber,
|
|
||||||
difficulty: bonfire[bonfireNumber].difficulty,
|
|
||||||
description: bonfire[bonfireNumber].description,
|
|
||||||
publicTests: bonfire[bonfireNumber].publicTests,
|
|
||||||
privateTests: bonfire[bonfireNumber].privateTests,
|
|
||||||
challengeSeed: bonfire[bonfireNumber].challengeSeed,
|
|
||||||
challengeEntryPoint: bonfire[bonfireNumber].challengeEntryPoint,
|
|
||||||
challengeEntryPointNegate: bonfire[bonfireNumber].challengeEntryPointNegate,
|
|
||||||
|
|
||||||
//cc: req.user ? req.user.bonfiresHash : undefined,
|
|
||||||
//points: req.user ? req.user.points : undefined,
|
|
||||||
//verb: verbs[Math.floor(Math.random() * verbs.length)],
|
|
||||||
//phrase: phrases[Math.floor(Math.random() * phrases.length)],
|
|
||||||
bonfires: bonfire
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post for bonfire generation
|
||||||
|
*/
|
||||||
|
|
||||||
|
function randomString() {
|
||||||
|
var chars = "0123456789abcdef";
|
||||||
|
var string_length = 23;
|
||||||
|
var randomstring = 'a';
|
||||||
|
for (var i=0; i<string_length; i++) {
|
||||||
|
var rnum = Math.floor(Math.random() * chars.length);
|
||||||
|
randomstring += chars.substring(rnum,rnum+1);
|
||||||
|
}
|
||||||
|
return randomstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.testBonfire = function(req, res) {
|
||||||
|
var bonfireName = req.body.name,
|
||||||
|
bonfireTests = req.body.tests,
|
||||||
|
bonfireDifficulty = req.body.difficulty,
|
||||||
|
bonfireDescription = req.body.description,
|
||||||
|
bonfireEntryPoint = req.body.challengeEntryPoint,
|
||||||
|
bonfireChallengeSeed = req.body.challengeSeed;
|
||||||
|
bonfireTests = bonfireTests.split('\r\n');
|
||||||
|
bonfireDescription = bonfireDescription.split('\r\n');
|
||||||
|
bonfireTests.filter(getRidOfEmpties);
|
||||||
|
bonfireDescription.filter(getRidOfEmpties);
|
||||||
|
bonfireChallengeSeed = bonfireChallengeSeed.replace('\r', '');
|
||||||
|
res.render('bonfire/show', {
|
||||||
|
completedWith: null,
|
||||||
|
title: bonfireName,
|
||||||
|
difficulty: +bonfireDifficulty,
|
||||||
|
brief: bonfireDescription[0],
|
||||||
|
details: bonfireDescription.slice(1),
|
||||||
|
tests: bonfireTests,
|
||||||
|
challengeSeed: bonfireChallengeSeed,
|
||||||
|
challengeEntryPoint: bonfireEntryPoint,
|
||||||
|
cc: req.user ? req.user.bonfiresHash : undefined,
|
||||||
|
points: req.user ? req.user.points : undefined,
|
||||||
|
verb: resources.randomVerb(),
|
||||||
|
phrase: resources.randomPhrase(),
|
||||||
|
compliment: resources.randomCompliment(),
|
||||||
|
bonfires: [],
|
||||||
|
bonfireHash: "test"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function getRidOfEmpties(elem) {
|
||||||
|
if (elem.length > 0) {
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.publicGenerator = function(req, res) {
|
||||||
|
res.render('bonfire/public-generator');
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.generateChallenge = function(req, res) {
|
||||||
|
var bonfireName = req.body.name,
|
||||||
|
bonfireTests = req.body.tests,
|
||||||
|
bonfireDifficulty = req.body.difficulty,
|
||||||
|
bonfireDescription = req.body.description,
|
||||||
|
bonfireEntryPoint = req.body.challengeEntryPoint,
|
||||||
|
bonfireChallengeSeed = req.body.challengeSeed;
|
||||||
|
bonfireTests = bonfireTests.split('\r\n');
|
||||||
|
bonfireDescription = bonfireDescription.split('\r\n');
|
||||||
|
bonfireTests.filter(getRidOfEmpties);
|
||||||
|
bonfireDescription.filter(getRidOfEmpties);
|
||||||
|
bonfireChallengeSeed = bonfireChallengeSeed.replace('\r', '');
|
||||||
|
|
||||||
|
|
||||||
|
var response = {
|
||||||
|
_id: randomString(),
|
||||||
|
name: bonfireName,
|
||||||
|
difficulty: bonfireDifficulty,
|
||||||
|
description: bonfireDescription,
|
||||||
|
challengeEntryPoint: bonfireEntryPoint,
|
||||||
|
challengeSeed: bonfireChallengeSeed,
|
||||||
|
tests: bonfireTests
|
||||||
|
};
|
||||||
|
res.send(response);
|
||||||
|
}
|
||||||
|
@ -4,56 +4,13 @@
|
|||||||
*/
|
*/
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
debug = require('debug')('freecc:cntr:challenges'),
|
debug = require('debug')('freecc:cntr:challenges'),
|
||||||
Challenge = require('./../models/Challenge');
|
Challenge = require('./../models/Challenge'),
|
||||||
|
resources = require('./resources');
|
||||||
|
|
||||||
var highestChallengeNumber = 53;
|
var highestChallengeNumber = 53;
|
||||||
|
|
||||||
exports.returnChallenge = function(req, res, next) {
|
exports.returnChallenge = function(req, res, next) {
|
||||||
var challengeNumber = parseInt(req.params.challengeNumber) || 0;
|
var challengeNumber = parseInt(req.params.challengeNumber) || 0;
|
||||||
var verbs = [
|
|
||||||
'ACED',
|
|
||||||
'NAILED',
|
|
||||||
'ROCKED',
|
|
||||||
'SCORCHED',
|
|
||||||
'DEVASTATED',
|
|
||||||
'OWNED',
|
|
||||||
'CRUSHED',
|
|
||||||
'CONQUERED',
|
|
||||||
'KILLED',
|
|
||||||
'SHREDDED',
|
|
||||||
'ANNIHILATED',
|
|
||||||
'NUKED'
|
|
||||||
];
|
|
||||||
var compliments = [
|
|
||||||
"You've got the power!",
|
|
||||||
"Nicely done!",
|
|
||||||
"Rock and roll!",
|
|
||||||
"High five!",
|
|
||||||
"Bravo!",
|
|
||||||
"Encore!",
|
|
||||||
"Challenge destroyed!",
|
|
||||||
"Power level 9000!",
|
|
||||||
"Most efficient!",
|
|
||||||
"Party on Wayne!",
|
|
||||||
"You've got the touch!",
|
|
||||||
"You're on fire!",
|
|
||||||
"Don't hurt 'em, Hammer!",
|
|
||||||
"The town is now red",
|
|
||||||
"To the nines!",
|
|
||||||
"Nothing but net!",
|
|
||||||
"Even grumpy cat is impressed"
|
|
||||||
];
|
|
||||||
var phrases = [
|
|
||||||
"Shout it from on top of a mountain",
|
|
||||||
"Tell everyone and their dogs",
|
|
||||||
"Show them. Show them all!",
|
|
||||||
"Inspire your friends",
|
|
||||||
"Tell the world of your greatness",
|
|
||||||
"Look accomplished on social media",
|
|
||||||
"Share news of your grand endeavor",
|
|
||||||
"Establish your alibi for the past two hours",
|
|
||||||
"Prove to mom that computers aren't just for games"
|
|
||||||
];
|
|
||||||
if (challengeNumber > highestChallengeNumber) { challengeNumber = 0; }
|
if (challengeNumber > highestChallengeNumber) { challengeNumber = 0; }
|
||||||
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -69,8 +26,9 @@ exports.returnChallenge = function(req, res, next) {
|
|||||||
number: challengeNumber,
|
number: challengeNumber,
|
||||||
cc: req.user ? req.user.challengesHash : undefined,
|
cc: req.user ? req.user.challengesHash : undefined,
|
||||||
points: req.user ? req.user.points : undefined,
|
points: req.user ? req.user.points : undefined,
|
||||||
verb: verbs[Math.floor(Math.random() * verbs.length)],
|
verb: resources.randomVerb(),
|
||||||
phrase: phrases[Math.floor(Math.random() * phrases.length)],
|
phrase: resources.randomPhrase(),
|
||||||
|
compliment: resources.randomCompliment(),
|
||||||
challenges: c
|
challenges: c
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,8 +4,10 @@ var User = require('../models/User'),
|
|||||||
steps = resources.steps,
|
steps = resources.steps,
|
||||||
secrets = require('./../config/secrets'),
|
secrets = require('./../config/secrets'),
|
||||||
Challenge = require('./../models/Challenge'),
|
Challenge = require('./../models/Challenge'),
|
||||||
|
bonfires = require('../seed_data/bonfires.json');
|
||||||
Client = require('node-rest-client').Client,
|
Client = require('node-rest-client').Client,
|
||||||
client = new Client();
|
client = new Client(),
|
||||||
|
debug = require('debug')('freecc:cntr:bonfires');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /
|
* GET /
|
||||||
@ -13,161 +15,195 @@ var User = require('../models/User'),
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
privacy: function privacy(req, res) {
|
privacy: function privacy(req, res) {
|
||||||
res.render('resources/privacy', {
|
res.render('resources/privacy', {
|
||||||
title: 'Privacy'
|
title: 'Privacy'
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
stats: function stats(req, res) {
|
|
||||||
var date1 = new Date("10/15/2014");
|
|
||||||
var date2 = new Date();
|
|
||||||
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
|
|
||||||
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
|
||||||
client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, response) {
|
|
||||||
var nonprofitProjects = (trello && trello.length) || 15;
|
|
||||||
User.count({'points': {'$gt': 2}}, function(err, c3) { if (err) { debug('User err: ', err); next(err); }
|
|
||||||
User.count({'points': {'$gt': 9}}, function(err, c10) { if (err) { debug('User err: ', err); next(err); }
|
|
||||||
User.count({'points': {'$gt': 29}}, function(err, c30) { if (err) { debug('User err: ', err); next(err); }
|
|
||||||
User.count({'points': {'$gt': 53}}, function(err, all) { if (err) { debug('User err: ', err); next(err); }
|
|
||||||
res.render('resources/stats', {
|
|
||||||
title: 'Free Code Camp Stats:',
|
|
||||||
daysRunning: daysRunning,
|
|
||||||
nonprofitProjects: nonprofitProjects,
|
|
||||||
c3: c3,
|
|
||||||
c10: c10,
|
|
||||||
c30: c30,
|
|
||||||
all: all
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
deployAWebsite: function deployAWebsite(req, res) {
|
stats: function stats(req, res) {
|
||||||
res.render('resources/deploy-a-website', {
|
var date1 = new Date("10/15/2014");
|
||||||
title: 'Deploy a Dynamic Website in 7 Minutes'
|
var date2 = new Date();
|
||||||
});
|
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
|
||||||
},
|
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||||
|
client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, response) {
|
||||||
nonprofitProjectInstructions: function nonprofitProjectInstructions(req, res) {
|
var nonprofitProjects = (trello && trello.length) || 15;
|
||||||
res.render('resources/nonprofit-project-instructions', {
|
User.count({'points': {'$gt': 2}}, function(err, c3) { if (err) { debug('User err: ', err); next(err); }
|
||||||
title: 'Nonprofit Project Instructions'
|
User.count({'points': {'$gt': 9}}, function(err, c10) { if (err) { debug('User err: ', err); next(err); }
|
||||||
});
|
User.count({'points': {'$gt': 29}}, function(err, c30) { if (err) { debug('User err: ', err); next(err); }
|
||||||
},
|
User.count({'points': {'$gt': 53}}, function(err, all) { if (err) { debug('User err: ', err); next(err); }
|
||||||
|
res.render('resources/stats', {
|
||||||
gmailShortcuts: function gmailShortcuts(req, res) {
|
title: 'Free Code Camp Stats:',
|
||||||
res.render('resources/gmail-shortcuts', {
|
daysRunning: daysRunning,
|
||||||
title: 'These Gmail Shortcuts will save you Hours'
|
nonprofitProjects: nonprofitProjects,
|
||||||
});
|
c3: c3,
|
||||||
},
|
c10: c10,
|
||||||
|
c30: c30,
|
||||||
controlShortcuts: function controlShortcuts(req, res) {
|
all: all
|
||||||
res.render('resources/control-shortcuts', {
|
});
|
||||||
title: 'These Control Shortcuts will save you Hours'
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
chromebook: function chromebook(req, res) {
|
|
||||||
res.render('resources/chromebook', {
|
|
||||||
title: 'Win a Chromebook'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
jqueryExercises: function jqueryExercises(req, res) {
|
|
||||||
res.render('resources/jquery-exercises', {
|
|
||||||
title: 'jQuery Exercises'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
livePairProgramming: function(req, res) {
|
|
||||||
res.render('resources/live-pair-programming', {
|
|
||||||
title: 'Live Pair Programming'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
javaScriptInYourInbox: function(req, res) {
|
|
||||||
res.render('resources/javascript-in-your-inbox', {
|
|
||||||
title: 'JavaScript in your Inbox'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
pairProgramWithTeamViewer: function(req, res) {
|
|
||||||
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
|
||||||
if (err) {
|
|
||||||
debug('Challenge err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
res.render('resources/pair-program-with-team-viewer', {
|
|
||||||
title: 'Challenge: Pair Program with Team Viewer',
|
|
||||||
name: 'Pair Program with Team Viewer',
|
|
||||||
video: '',
|
|
||||||
time: 30,
|
|
||||||
steps: steps,
|
|
||||||
cc: req.user ? req.user.challengesHash : undefined,
|
|
||||||
points: req.user ? req.user.points : undefined,
|
|
||||||
challenges: c
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
about: function(req, res) {
|
|
||||||
var date1 = new Date("10/15/2014");
|
|
||||||
var date2 = new Date();
|
|
||||||
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
|
|
||||||
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
|
||||||
client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, res2) {
|
|
||||||
client.get('https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/posts?key=' + secrets.blogger.key, function(blogger, res3) {
|
|
||||||
var nonprofitProjects = trello.length || 15;
|
|
||||||
var blog = JSON.parse(blogger);
|
|
||||||
User.count({'points': {'$gt': 2}}, function (err, c3) {
|
|
||||||
if (err) {
|
|
||||||
debug('User err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
User.count({'points': {'$gt': 9}}, function (err, c10) {
|
|
||||||
if (err) {
|
|
||||||
debug('User err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
User.count({'points': {'$gt': 29}}, function (err, c30) {
|
|
||||||
if (err) {
|
|
||||||
debug('User err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
User.count({'points': {'$gt': 53}}, function (err, all) {
|
|
||||||
if (err) {
|
|
||||||
debug('User err: ', err);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
res.render('resources/about', {
|
|
||||||
title: 'About Free Code Camp and Our Team of Volunteers',
|
|
||||||
daysRunning: daysRunning,
|
|
||||||
nonprofitProjects: nonprofitProjects,
|
|
||||||
c3: c3,
|
|
||||||
c10: c10,
|
|
||||||
c30: c30,
|
|
||||||
all: all,
|
|
||||||
blog1Title: blog["items"][0]["title"],
|
|
||||||
blog1Link: blog["items"][0]["url"],
|
|
||||||
blog2Title: blog["items"][1]["title"],
|
|
||||||
blog2Link: blog["items"][1]["url"],
|
|
||||||
blog3Title: blog["items"][2]["title"],
|
|
||||||
blog3Link: blog["items"][2]["url"],
|
|
||||||
blog4Title: blog["items"][3]["title"],
|
|
||||||
blog4Link: blog["items"][3]["url"],
|
|
||||||
blog5Title: blog["items"][4]["title"],
|
|
||||||
blog5Link: blog["items"][4]["url"]
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
});
|
|
||||||
}
|
deployAWebsite: function deployAWebsite(req, res) {
|
||||||
|
res.render('resources/deploy-a-website', {
|
||||||
|
title: 'Deploy a Dynamic Website in 7 Minutes'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
nonprofitProjectInstructions: function nonprofitProjectInstructions(req, res) {
|
||||||
|
res.render('resources/nonprofit-project-instructions', {
|
||||||
|
title: 'Nonprofit Project Instructions'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
gmailShortcuts: function gmailShortcuts(req, res) {
|
||||||
|
res.render('resources/gmail-shortcuts', {
|
||||||
|
title: 'These Gmail Shortcuts will save you Hours'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
controlShortcuts: function controlShortcuts(req, res) {
|
||||||
|
res.render('resources/control-shortcuts', {
|
||||||
|
title: 'These Control Shortcuts will save you Hours'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
chromebook: function chromebook(req, res) {
|
||||||
|
res.render('resources/chromebook', {
|
||||||
|
title: 'Win a Chromebook'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
jqueryExercises: function jqueryExercises(req, res) {
|
||||||
|
res.render('resources/jquery-exercises', {
|
||||||
|
title: 'jQuery Exercises'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
livePairProgramming: function(req, res) {
|
||||||
|
res.render('resources/live-pair-programming', {
|
||||||
|
title: 'Live Pair Programming'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
javaScriptInYourInbox: function(req, res) {
|
||||||
|
res.render('resources/javascript-in-your-inbox', {
|
||||||
|
title: 'JavaScript in your Inbox'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
pairProgramWithTeamViewer: function(req, res) {
|
||||||
|
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
|
||||||
|
if (err) {
|
||||||
|
debug('Challenge err: ', err);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
res.render('resources/pair-program-with-team-viewer', {
|
||||||
|
title: 'Challenge: Pair Program with Team Viewer',
|
||||||
|
name: 'Pair Program with Team Viewer',
|
||||||
|
video: '',
|
||||||
|
time: 30,
|
||||||
|
steps: steps,
|
||||||
|
cc: req.user ? req.user.challengesHash : undefined,
|
||||||
|
points: req.user ? req.user.points : undefined,
|
||||||
|
challenges: c
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
about: function(req, res) {
|
||||||
|
var date1 = new Date("10/15/2014");
|
||||||
|
var date2 = new Date();
|
||||||
|
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
|
||||||
|
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||||
|
client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, res2) {
|
||||||
|
client.get('https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/posts?key=' + secrets.blogger.key, function(blogger, res3) {
|
||||||
|
var nonprofitProjects = trello.length || 15;
|
||||||
|
var blog = JSON.parse(blogger);
|
||||||
|
User.count({'points': {'$gt': 2}}, function (err, c3) {
|
||||||
|
if (err) {
|
||||||
|
debug('User err: ', err);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
User.count({'points': {'$gt': 9}}, function (err, c10) {
|
||||||
|
if (err) {
|
||||||
|
debug('User err: ', err);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
User.count({'points': {'$gt': 29}}, function (err, c30) {
|
||||||
|
if (err) {
|
||||||
|
debug('User err: ', err);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
User.count({'points': {'$gt': 53}}, function (err, all) {
|
||||||
|
if (err) {
|
||||||
|
debug('User err: ', err);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
res.render('resources/learn-to-code', {
|
||||||
|
title: 'About Free Code Camp and Our Team of Volunteers',
|
||||||
|
daysRunning: daysRunning,
|
||||||
|
nonprofitProjects: nonprofitProjects,
|
||||||
|
c3: c3,
|
||||||
|
c10: c10,
|
||||||
|
c30: c30,
|
||||||
|
all: all,
|
||||||
|
blog1Title: blog["items"][0]["title"],
|
||||||
|
blog1Link: blog["items"][0]["url"],
|
||||||
|
blog2Title: blog["items"][1]["title"],
|
||||||
|
blog2Link: blog["items"][1]["url"],
|
||||||
|
blog3Title: blog["items"][2]["title"],
|
||||||
|
blog3Link: blog["items"][2]["url"],
|
||||||
|
blog4Title: blog["items"][3]["title"],
|
||||||
|
blog4Link: blog["items"][3]["url"],
|
||||||
|
blog5Title: blog["items"][4]["title"],
|
||||||
|
blog5Link: blog["items"][4]["url"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
randomPhrase: function() {
|
||||||
|
var phrases = resources.phrases;
|
||||||
|
return phrases[Math.floor(Math.random() * phrases.length)];
|
||||||
|
},
|
||||||
|
|
||||||
|
randomVerb: function() {
|
||||||
|
var verbs = resources.verbs;
|
||||||
|
return verbs[Math.floor(Math.random() * verbs.length)];
|
||||||
|
},
|
||||||
|
|
||||||
|
randomCompliment: function() {
|
||||||
|
var compliments = resources.compliments;
|
||||||
|
return compliments[Math.floor(Math.random() * compliments.length)];
|
||||||
|
},
|
||||||
|
|
||||||
|
numberOfBonfires: function() {
|
||||||
|
return bonfires.length - 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
allBonfireIds: function() {
|
||||||
|
return bonfires.map(function(elem) {
|
||||||
|
return {
|
||||||
|
_id: elem._id,
|
||||||
|
difficulty: elem.difficulty
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sort(function(a, b) {
|
||||||
|
return a.difficulty - b.difficulty;
|
||||||
|
})
|
||||||
|
.map(function(elem) {
|
||||||
|
return elem._id;
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,5 +144,101 @@
|
|||||||
"You can complete CoderByte problems while you continue to work through Free Code Camp's challenges.",
|
"You can complete CoderByte problems while you continue to work through Free Code Camp's challenges.",
|
||||||
"Be sure to pair program on these challenges, and remember to apply the RSAP methodology.",
|
"Be sure to pair program on these challenges, and remember to apply the RSAP methodology.",
|
||||||
"Click the button below to return to the Pair Programming challenge, then mark it complete."
|
"Click the button below to return to the Pair Programming challenge, then mark it complete."
|
||||||
|
],
|
||||||
|
"verbs": [
|
||||||
|
"aced",
|
||||||
|
"nailed",
|
||||||
|
"rocked",
|
||||||
|
"scorched",
|
||||||
|
"devastated",
|
||||||
|
"destroyed",
|
||||||
|
"owned",
|
||||||
|
"crushed",
|
||||||
|
"conquered",
|
||||||
|
"killed",
|
||||||
|
"shredded",
|
||||||
|
"annihilated",
|
||||||
|
"nuked",
|
||||||
|
"smashed",
|
||||||
|
"decimated",
|
||||||
|
"demolished",
|
||||||
|
"devoured",
|
||||||
|
"pulvarized",
|
||||||
|
"banished",
|
||||||
|
"throttled",
|
||||||
|
"blew away",
|
||||||
|
"roundhoused",
|
||||||
|
"tangoed",
|
||||||
|
"wrangled",
|
||||||
|
"shot down",
|
||||||
|
"scarfed",
|
||||||
|
"grappled",
|
||||||
|
"incinerated"
|
||||||
|
],
|
||||||
|
"compliments": [
|
||||||
|
"You've got the power!",
|
||||||
|
"Nicely done!",
|
||||||
|
"Rock and roll!",
|
||||||
|
"High five!",
|
||||||
|
"Bravo!",
|
||||||
|
"Yes!",
|
||||||
|
"Swoosh!",
|
||||||
|
"There is no try",
|
||||||
|
"Done and done!",
|
||||||
|
"You make this look easy",
|
||||||
|
"Terminated",
|
||||||
|
"We have liftoff!",
|
||||||
|
"To infinity and beyond!",
|
||||||
|
"Encore!",
|
||||||
|
"Challenge destroyed!",
|
||||||
|
"Power level 9000!",
|
||||||
|
"Most efficient!",
|
||||||
|
"Party on, Wayne!",
|
||||||
|
"You've got the touch!",
|
||||||
|
"You're on fire!",
|
||||||
|
"Don't hurt 'em, Hammer!",
|
||||||
|
"The town is now red",
|
||||||
|
"To the nines!",
|
||||||
|
"Nothing but net!",
|
||||||
|
"Grumpy cat approves",
|
||||||
|
"The world rejoices",
|
||||||
|
"That's the way it's done!",
|
||||||
|
"You rock!",
|
||||||
|
"Woo-hoo!",
|
||||||
|
"We knew you could do it",
|
||||||
|
"Hyper Combo Finish!",
|
||||||
|
"Nothing but net!",
|
||||||
|
"Boom-shakalaka!",
|
||||||
|
"You're a shooting star!",
|
||||||
|
"You're unstoppable!",
|
||||||
|
"Way cool!",
|
||||||
|
"You're king of the world!",
|
||||||
|
"Walk on that sunshine!",
|
||||||
|
"Keep on trucking!",
|
||||||
|
"Off the charts!",
|
||||||
|
"There is no spoon",
|
||||||
|
"Cranked it up to 11!",
|
||||||
|
"Escape velocity reached!",
|
||||||
|
"You make this look easy!",
|
||||||
|
"Passed with flying colors!",
|
||||||
|
"One step closer...",
|
||||||
|
"You've got this!",
|
||||||
|
"Happy happy joy joy!",
|
||||||
|
"Tomorrow, the world!",
|
||||||
|
"Here's looking at you, Code!",
|
||||||
|
"It's alive. It's alive!"
|
||||||
|
],
|
||||||
|
"phrases": [
|
||||||
|
"Shout it from on top of a mountain",
|
||||||
|
"Tell everyone and their dogs",
|
||||||
|
"Show them. Show them all!",
|
||||||
|
"Inspire your friends",
|
||||||
|
"Tell the world of your greatness",
|
||||||
|
"Look accomplished on social media",
|
||||||
|
"Share news of your grand endeavor",
|
||||||
|
"Establish your alibi for the past two hours",
|
||||||
|
"Prove to mom that computers aren't just for games",
|
||||||
|
"With coding power comes sharing responsibility",
|
||||||
|
"Have you told your friends of your coding powers?"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -12,23 +12,23 @@ var _ = require('lodash'),
|
|||||||
//TODO(Berks): Refactor to use module.exports = {} pattern.
|
//TODO(Berks): Refactor to use module.exports = {} pattern.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /login
|
* GET /signin
|
||||||
* Login page.
|
* Siginin page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.getLogin = function(req, res) {
|
exports.getSignin = function(req, res) {
|
||||||
if (req.user) return res.redirect('/');
|
if (req.user) return res.redirect('/');
|
||||||
res.render('account/login', {
|
res.render('account/signin', {
|
||||||
title: 'Free Code Camp Login'
|
title: 'Free Code Camp Login'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST /login
|
* POST /signin
|
||||||
* Sign in using email and password.
|
* Sign in using email and password.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.postLogin = function(req, res, next) {
|
exports.postSignin = function(req, res, next) {
|
||||||
req.assert('email', 'Email is not valid').isEmail();
|
req.assert('email', 'Email is not valid').isEmail();
|
||||||
req.assert('password', 'Password cannot be blank').notEmpty();
|
req.assert('password', 'Password cannot be blank').notEmpty();
|
||||||
|
|
||||||
@ -36,14 +36,14 @@ exports.postLogin = function(req, res, next) {
|
|||||||
|
|
||||||
if (errors) {
|
if (errors) {
|
||||||
req.flash('errors', errors);
|
req.flash('errors', errors);
|
||||||
return res.redirect('/login');
|
return res.redirect('/signin');
|
||||||
}
|
}
|
||||||
|
|
||||||
passport.authenticate('local', function(err, user, info) {
|
passport.authenticate('local', function(err, user, info) {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
req.flash('errors', { msg: info.message });
|
req.flash('errors', { msg: info.message });
|
||||||
return res.redirect('/login');
|
return res.redirect('/signin');
|
||||||
}
|
}
|
||||||
req.logIn(user, function(err) {
|
req.logIn(user, function(err) {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
@ -54,11 +54,11 @@ exports.postLogin = function(req, res, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /logout
|
* GET /signout
|
||||||
* Log out.
|
* Log out.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.logout = function(req, res) {
|
exports.signout = function(req, res) {
|
||||||
req.logout();
|
req.logout();
|
||||||
res.redirect('/');
|
res.redirect('/');
|
||||||
};
|
};
|
||||||
@ -76,7 +76,7 @@ exports.getEmailSignin = function(req, res) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /email-signin
|
* GET /signin
|
||||||
* Signup page.
|
* Signup page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ exports.getAccount = function(req, res) {
|
|||||||
console.error('Challenge err: ', err);
|
console.error('Challenge err: ', err);
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
res.render('account/profile', {
|
res.render('account/account', {
|
||||||
title: 'Manage your Free Code Camp Account',
|
title: 'Manage your Free Code Camp Account',
|
||||||
challenges: c,
|
challenges: c,
|
||||||
ch: req.user.challengesHash,
|
ch: req.user.challengesHash,
|
||||||
@ -184,6 +184,22 @@ exports.checkUniqueUsername = function(req, res) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Existing username check
|
||||||
|
*/
|
||||||
|
exports.checkExistingUsername = function(req, res) {
|
||||||
|
User.count({'profile.username': req.params.username.toLowerCase()}, function (err, data) {
|
||||||
|
if (data == 1) {
|
||||||
|
debug('sending false back')
|
||||||
|
return res.send(true);
|
||||||
|
} else {
|
||||||
|
debug('sending true back')
|
||||||
|
return res.send(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unique email check API Call
|
* Unique email check API Call
|
||||||
*/
|
*/
|
||||||
|
@ -5,7 +5,7 @@ var gulp = require('gulp'),
|
|||||||
sync = require('browser-sync'),
|
sync = require('browser-sync'),
|
||||||
reload = sync.reload,
|
reload = sync.reload,
|
||||||
inject = require('gulp-inject'),
|
inject = require('gulp-inject'),
|
||||||
reloadDelay = 3000;
|
reloadDelay = 1000;
|
||||||
|
|
||||||
var paths = {
|
var paths = {
|
||||||
server: './app.js',
|
server: './app.js',
|
||||||
|
@ -8,20 +8,16 @@ var secrets = require('../config/secrets');
|
|||||||
|
|
||||||
|
|
||||||
var bonfireSchema = new mongoose.Schema({
|
var bonfireSchema = new mongoose.Schema({
|
||||||
|
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
difficulty: Number,
|
difficulty: String,
|
||||||
description: Array,
|
description: Array,
|
||||||
publicTests: Array,
|
tests: Array,
|
||||||
privateTests: Array,
|
|
||||||
challengeSeed: String,
|
challengeSeed: String,
|
||||||
bonfireNumber: Number,
|
|
||||||
challengeEntryPoint: String,
|
challengeEntryPoint: String,
|
||||||
challengeEntryPointNegate: String
|
challengeEntryPointNegate: String
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = mongoose.model('Bonfire', bonfireSchema);
|
module.exports = mongoose.model('Bonfire', bonfireSchema);
|
||||||
|
@ -3,11 +3,8 @@ var secrets = require('../config/secrets');
|
|||||||
|
|
||||||
var bonfireCompletionSchema = new mongoose.Schema({
|
var bonfireCompletionSchema = new mongoose.Schema({
|
||||||
dateCompleted: Number,
|
dateCompleted: Number,
|
||||||
completedWith: String,
|
completedWith: ObjectId,
|
||||||
bonfireNumber: {
|
bonfireHash: ObjectId,
|
||||||
bonfireNumber: Number,
|
|
||||||
bonfireId: String
|
|
||||||
},
|
|
||||||
solution: String
|
solution: String
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -353,7 +353,12 @@ var userSchema = new mongoose.Schema({
|
|||||||
},
|
},
|
||||||
resetPasswordToken: String,
|
resetPasswordToken: String,
|
||||||
resetPasswordExpires: Date,
|
resetPasswordExpires: Date,
|
||||||
bonfires: Array
|
uncompletedBonfires: Array,
|
||||||
|
completedBonfires: Array,
|
||||||
|
lastContentSync: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
@import "lib/bootstrap-social/bootstrap-social";
|
@import "lib/bootstrap-social/bootstrap-social";
|
||||||
@import "lib/ionicons/ionicons";
|
@import "lib/ionicons/ionicons";
|
||||||
@import "lib/animate.min.less";
|
@import "lib/animate.min.less";
|
||||||
|
@import "lib/bootstrap/variables";
|
||||||
|
|
||||||
@import url(http://fonts.googleapis.com/css?family=Lato:300);
|
//fonts.googleapis.com/css?family=Lato:300);
|
||||||
@import url(http://fonts.googleapis.com/css?family=Lato:400);
|
@import url(http://fonts.googleapis.com/css?family=Lato:400);
|
||||||
@import url(http://fonts.googleapis.com/css?family=Inconsolata);
|
@import url(http://fonts.googleapis.com/css?family=Inconsolata);
|
||||||
|
|
||||||
@ -28,11 +29,19 @@ html {
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body.full-screen-body-background {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.top-and-bottom-margins {
|
||||||
padding-top: 80px;
|
padding-top: 80px;
|
||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.no-top-and-bottom-margins {
|
||||||
|
margin: 70px 20px 50px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
h1, h2 {
|
h1, h2 {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
@ -205,6 +214,11 @@ ul {
|
|||||||
animation-duration: 0.5s;
|
animation-duration: 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slow-animation {
|
||||||
|
-webkit-animation-duration: 1.5s;
|
||||||
|
animation-duration: 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
.disabled {
|
.disabled {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -247,6 +261,10 @@ ul {
|
|||||||
.navbar {
|
.navbar {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border: none;
|
border: none;
|
||||||
|
@media (min-width: 767px) {
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-body {
|
.panel-body {
|
||||||
@ -505,6 +523,7 @@ thead {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: -30px;
|
margin-bottom: -30px;
|
||||||
border-radius: 5px 5px 0px 0px;
|
border-radius: 5px 5px 0px 0px;
|
||||||
|
padding-left: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.closing-x {
|
.closing-x {
|
||||||
@ -531,22 +550,6 @@ thead {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form.code span {
|
|
||||||
font-size: 14px;
|
|
||||||
font-family: "Ubuntu Mono";
|
|
||||||
padding-bottom: 0px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mainEditorPanel .panel-body {
|
|
||||||
padding-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.CodeMirror-scroll {
|
|
||||||
padding-bottom: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.embed-responsive-twitch-chat {
|
.embed-responsive-twitch-chat {
|
||||||
padding-bottom: 117%;
|
padding-bottom: 117%;
|
||||||
}
|
}
|
||||||
@ -569,13 +572,78 @@ div.CodeMirror-scroll {
|
|||||||
text-size: 250px;
|
text-size: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bonfire-instructions p {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.bonfire-instructions {
|
.bonfire-instructions {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bonfire styling
|
||||||
|
*/
|
||||||
|
|
||||||
|
form.code span {
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: "Ubuntu Mono";
|
||||||
|
padding-bottom: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-linenumber {
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: "Ubuntu Mono";
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainEditorPanel {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big-error-icon {
|
||||||
|
font-size: 40px;
|
||||||
|
color: @brand-danger;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big-success-icon {
|
||||||
|
font-size: 40px;
|
||||||
|
color: @brand-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-output {
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: "Ubuntu Mono";
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainEditorPanel .panel-body {
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-bonfire {
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
div.CodeMirror-scroll {
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-vertical-center {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-monokai.CodeMirror {
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.bonfire-flames {
|
||||||
|
margin-top: -20px;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonfire-top {
|
||||||
|
margin-top: -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//uncomment this to see the dimensions of all elements outlined in red
|
//uncomment this to see the dimensions of all elements outlined in red
|
||||||
//* {
|
//* {
|
||||||
// border-color: red;
|
// border-color: red;
|
||||||
|
@ -7,7 +7,6 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor")
|
|||||||
lint: true,
|
lint: true,
|
||||||
matchBrackets: true,
|
matchBrackets: true,
|
||||||
autoCloseBrackets: true,
|
autoCloseBrackets: true,
|
||||||
cursorHeight: 1,
|
|
||||||
scrollbarStyle: 'null',
|
scrollbarStyle: 'null',
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
gutters: ["CodeMirror-lint-markers"],
|
gutters: ["CodeMirror-lint-markers"],
|
||||||
@ -20,13 +19,13 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor")
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
var editor = myCodeMirror;
|
var editor = myCodeMirror;
|
||||||
|
editor.setSize("100%", "auto");
|
||||||
|
|
||||||
|
|
||||||
// Default value for editor if one isn't provided in (i.e. a challenge)
|
// Default value for editor if one isn't provided in (i.e. a challenge)
|
||||||
var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByte replacement.\n' +
|
var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByte replacement.\n' +
|
||||||
'Please feel free to use Bonfire as an in-browser playground and linting tool.\n' +
|
'Please feel free to use Bonfire as an in-browser playground and linting tool.\n' +
|
||||||
'Note that you can also write tests using Chai.js\n' +
|
'Note that you can also write tests using Chai.js by using the keywords assert and expect */\n\n' +
|
||||||
' by using the keywords assert and expect */\n\n' +
|
|
||||||
'function test() {\n' +
|
'function test() {\n' +
|
||||||
' assert(2 !== 3, "2 is not equal to 3");\n' +
|
' assert(2 !== 3, "2 is not equal to 3");\n' +
|
||||||
' return [1,2,3].map(function(elem) {\n' +
|
' return [1,2,3].map(function(elem) {\n' +
|
||||||
@ -35,7 +34,9 @@ var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByt
|
|||||||
'}\n' +
|
'}\n' +
|
||||||
'expect(test()).to.be.a("array");\n\n' +
|
'expect(test()).to.be.a("array");\n\n' +
|
||||||
'assert.deepEqual(test(), [1,4,9]);\n\n' +
|
'assert.deepEqual(test(), [1,4,9]);\n\n' +
|
||||||
'test();';
|
'var foo = test();\n' +
|
||||||
|
'foo.should.be.a("array");\n\n' +
|
||||||
|
'test();\n';
|
||||||
|
|
||||||
var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
|
var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
|
||||||
lineNumbers: false,
|
lineNumbers: false,
|
||||||
@ -45,9 +46,9 @@ var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"),
|
|||||||
lineWrapping: true
|
lineWrapping: true
|
||||||
});
|
});
|
||||||
codeOutput.setValue('/**\n' +
|
codeOutput.setValue('/**\n' +
|
||||||
' * Your output will go here. Console.log() -type statements\n' +
|
' * Your output will go here.\n' + ' * Console.log() -type statements\n' +
|
||||||
' * will appear in your browser\'s javascript console.\n' +
|
' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' +
|
||||||
' */');
|
' */');
|
||||||
codeOutput.setSize("100%", "100%");
|
codeOutput.setSize("100%", "100%");
|
||||||
var info = editor.getScrollInfo();
|
var info = editor.getScrollInfo();
|
||||||
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
|
||||||
@ -58,10 +59,8 @@ var editorValue;
|
|||||||
|
|
||||||
|
|
||||||
var challengeSeed = challengeSeed || null;
|
var challengeSeed = challengeSeed || null;
|
||||||
var publicTests = publicTests || [];
|
var tests = tests || [];
|
||||||
var privateTests = privateTests || [];
|
|
||||||
var challengeEntryPoint = challengeEntryPoint || null;
|
var challengeEntryPoint = challengeEntryPoint || null;
|
||||||
var challengeEntryPointNegate = challengeEntryPointNegate || null;
|
|
||||||
|
|
||||||
|
|
||||||
if (challengeSeed !== null) {
|
if (challengeSeed !== null) {
|
||||||
@ -101,11 +100,15 @@ $('#submitButton').on('click', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function bonfireExecute() {
|
function bonfireExecute() {
|
||||||
tests = null;
|
userTests= null;
|
||||||
$('#codeOutput').empty();
|
$('#codeOutput').empty();
|
||||||
var userJavaScript = myCodeMirror.getValue();
|
var userJavaScript = myCodeMirror.getValue();
|
||||||
userJavaScript = removeComments(userJavaScript);
|
userJavaScript = removeComments(userJavaScript);
|
||||||
userJavaScript = scrapeTests(userJavaScript);
|
userJavaScript = scrapeTests(userJavaScript);
|
||||||
|
// simple fix in case the user forgets to invoke their function
|
||||||
|
if (challengeEntryPoint) {
|
||||||
|
userJavaScript = challengeEntryPoint + ' ' + userJavaScript;
|
||||||
|
}
|
||||||
submit(userJavaScript, function(cls, message) {
|
submit(userJavaScript, function(cls, message) {
|
||||||
if (cls) {
|
if (cls) {
|
||||||
codeOutput.setValue(message.error);
|
codeOutput.setValue(message.error);
|
||||||
@ -118,24 +121,16 @@ function bonfireExecute() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var replaceQuotesInTests = function() {
|
|
||||||
tests.forEach(function(elt, ix, arr) {
|
|
||||||
arr[ix].text = arr[ix].text.replace(/\"/g,'\'');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var tests;
|
var userTests;
|
||||||
var testSalt = Math.random();
|
var testSalt = Math.random();
|
||||||
|
|
||||||
|
|
||||||
var scrapeTests = function(userJavaScript) {
|
var scrapeTests = function(userJavaScript) {
|
||||||
|
|
||||||
for (var i = 0; i < publicTests.length; i++) {
|
// insert tests from mongo
|
||||||
userJavaScript += '\n' + publicTests[i];
|
for (var i = 0; i < tests.length; i++) {
|
||||||
}
|
userJavaScript += '\n' + tests[i];
|
||||||
|
|
||||||
for (var i = 0; i < privateTests.length; i++) {
|
|
||||||
userJavaScript += '\n' + privateTests[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
@ -143,17 +138,16 @@ var scrapeTests = function(userJavaScript) {
|
|||||||
var match = regex.exec(userJavaScript);
|
var match = regex.exec(userJavaScript);
|
||||||
while (match != null) {
|
while (match != null) {
|
||||||
var replacement = '//' + counter + testSalt;
|
var replacement = '//' + counter + testSalt;
|
||||||
userJavaScript = userJavaScript.substring(0, match.index)
|
userJavaScript = userJavaScript.substring(0, match.index) + replacement + userJavaScript.substring(match.index + match[0].length);
|
||||||
+ replacement
|
|
||||||
+ userJavaScript.substring(match.index + match[0].length);
|
|
||||||
|
|
||||||
if (!tests) tests = [];
|
if (!userTests) {
|
||||||
tests.push({"text": match[0], "line": counter, "err": null});
|
userTests= [];
|
||||||
|
}
|
||||||
|
userTests.push({"text": match[0], "line": counter, "err": null});
|
||||||
counter++;
|
counter++;
|
||||||
match = regex.exec(userJavaScript);
|
match = regex.exec(userJavaScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tests) replaceQuotesInTests();
|
|
||||||
return userJavaScript;
|
return userJavaScript;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,30 +158,23 @@ function removeComments(userJavaScript) {
|
|||||||
|
|
||||||
function removeLogs(userJavaScript) {
|
function removeLogs(userJavaScript) {
|
||||||
return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
|
return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
|
||||||
return userJavaScript;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var pushed = false;
|
var pushed = false;
|
||||||
var createTestDisplay = function() {
|
var createTestDisplay = function() {
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
tests.pop();
|
userTests.pop();
|
||||||
}
|
}
|
||||||
for (var i = 0; i < tests.length;i++) {
|
for (var i = 0; i < userTests.length;i++) {
|
||||||
var test = tests[i];
|
var test = userTests[i];
|
||||||
var testDoc = document.createElement("li");
|
var testDoc = document.createElement("div");
|
||||||
$(testDoc)
|
|
||||||
.addClass('list-group-item')
|
|
||||||
.addClass('well img-rounded')
|
|
||||||
.addClass('well-sm')
|
|
||||||
if (test.err != null) {
|
if (test.err != null) {
|
||||||
$(testDoc)
|
$(testDoc)
|
||||||
.html(test.text + "\n" + test.err)
|
.html("<div class='row'><div class='col-xs-1 text-center'><i class='ion-close-circled big-error-icon'></i></div><div class='col-xs-11 test-output wrappable'>" + test.text + "</div><div class='col-xs-11 test-output wrappable'>" + test.err + "</div></div><div class='ten-pixel-break'/>")
|
||||||
.css("background-color", 'rgba(255,0,0,.2)')
|
.prependTo($('#testSuite'))
|
||||||
.prependTo($('#testSuite'));
|
|
||||||
} else {
|
} else {
|
||||||
$(testDoc)
|
$(testDoc)
|
||||||
.html(test.text)
|
.html("<div class='row'><div class='col-xs-1 text-center'><i class='ion-checkmark-circled big-success-icon'></i></div><div class='col-xs-11 test-output test-vertical-center wrappable'>" + test.text + "</div></div><div class='ten-pixel-break'/>")
|
||||||
.css('background-color', 'rgba(0,255,0,.2)')
|
|
||||||
.appendTo($('#testSuite'));
|
.appendTo($('#testSuite'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -201,28 +188,39 @@ var reassembleTest = function(test, data) {
|
|||||||
var regexp = new RegExp("\/\/" + lineNum + testSalt);
|
var regexp = new RegExp("\/\/" + lineNum + testSalt);
|
||||||
return data.input.replace(regexp, test.text);
|
return data.input.replace(regexp, test.text);
|
||||||
};
|
};
|
||||||
|
|
||||||
var runTests = function(err, data) {
|
var runTests = function(err, data) {
|
||||||
|
var allTestsPassed = true;
|
||||||
pushed = false;
|
pushed = false;
|
||||||
$('#testSuite').children().remove();
|
$('#testSuite').children().remove();
|
||||||
if (err && tests.length > 0) {
|
if (err && userTests.length > 0) {
|
||||||
tests = [{text:"Program Execution Failure", err: "No tests were run."}];
|
userTests= [{text:"Program Execution Failure", err: "No user tests were run."}];
|
||||||
createTestDisplay();
|
createTestDisplay();
|
||||||
} else if (tests) {
|
} else if (userTests) {
|
||||||
tests.push(false);
|
userTests.push(false);
|
||||||
pushed = true;
|
pushed = true;
|
||||||
tests.forEach(function(test, ix, arr){
|
userTests.forEach(function(test, ix, arr){
|
||||||
try {
|
try {
|
||||||
if (test) {
|
if (test) {
|
||||||
|
console.log();
|
||||||
var output = eval(reassembleTest(test, data));
|
var output = eval(reassembleTest(test, data));
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
|
allTestsPassed = false;
|
||||||
arr[ix].err = error.name + ":" + error.message;
|
arr[ix].err = error.name + ":" + error.message;
|
||||||
} finally {
|
} finally {
|
||||||
if (!test) {
|
if (!test) {
|
||||||
createTestDisplay();
|
createTestDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
if (allTestsPassed) {
|
||||||
|
allTestsPassed = false;
|
||||||
|
showCompletion();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function showCompletion() {
|
||||||
|
$('#complete-bonfire-dialog').modal('show');
|
||||||
|
}
|
2
public/js/lib/codemirror/theme/monokai.css
vendored
2
public/js/lib/codemirror/theme/monokai.css
vendored
@ -1,6 +1,6 @@
|
|||||||
/* Based on Sublime Text's Monokai theme */
|
/* Based on Sublime Text's Monokai theme */
|
||||||
|
|
||||||
.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2; border-radius: 5px; height: auto;}
|
.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2; height: auto;}
|
||||||
.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
|
.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
|
||||||
.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;}
|
.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;}
|
||||||
.cm-s-monokai .CodeMirror-guttermarker { color: white; }
|
.cm-s-monokai .CodeMirror-guttermarker { color: white; }
|
||||||
|
@ -1,46 +1,96 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
var CSRF_HEADER = 'X-CSRF-Token';
|
var CSRF_HEADER = 'X-CSRF-Token';
|
||||||
|
|
||||||
var setCSRFToken = function(securityToken) {
|
var setCSRFToken = function(securityToken) {
|
||||||
jQuery.ajaxPrefilter(function(options, _, xhr) {
|
jQuery.ajaxPrefilter(function(options, _, xhr) {
|
||||||
if (!xhr.crossDomain) {
|
if (!xhr.crossDomain) {
|
||||||
xhr.setRequestHeader(CSRF_HEADER, securityToken);
|
xhr.setRequestHeader(CSRF_HEADER, securityToken);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
setCSRFToken($('meta[name="csrf-token"]').attr('content'));
|
||||||
|
|
||||||
|
$('.start-challenge').on('click', function() {
|
||||||
|
$(this).parent().remove();
|
||||||
|
$('.challenge-content')
|
||||||
|
.removeClass('hidden-element')
|
||||||
|
.addClass('animated fadeInDown');
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
setCSRFToken($('meta[name="csrf-token"]').attr('content'));
|
$('.completed-challenge').on('click', function() {
|
||||||
|
$('#complete-challenge-dialog').modal('show');
|
||||||
|
// Only post to server if there is an authenticated user
|
||||||
|
if ($('.signup-btn-nav').length < 1) {
|
||||||
|
l = location.pathname.split('/');
|
||||||
|
cn = l[l.length - 1];
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
data: {challengeNumber: cn},
|
||||||
|
url: '/completed-challenge/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('.start-challenge').on('click', function() {
|
|
||||||
$(this).parent().remove();
|
|
||||||
$('.challenge-content')
|
|
||||||
.removeClass('hidden-element')
|
|
||||||
.addClass('animated fadeInDown');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.completed-challenge').on('click', function() {
|
|
||||||
$('#complete-dialog').modal('show');
|
|
||||||
// Only post to server if there is an authenticated user
|
|
||||||
if ($('.signup-btn-nav').length < 1) {
|
|
||||||
l = location.pathname.split('/');
|
|
||||||
cn = l[l.length - 1];
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
data: {challengeNumber: cn},
|
|
||||||
url: '/completed-challenge/'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.all-challenges').on('click', function() {
|
function completedBonfire(didCompleteWith, bonfireSolution, thisBonfireHash) {
|
||||||
$('#all-challenges-dialog').modal('show');
|
$('#complete-bonfire-dialog').modal('show');
|
||||||
});
|
// Only post to server if there is an authenticated user
|
||||||
|
if ($('.signup-btn-nav').length < 1) {
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
bonfireInfo: {
|
||||||
|
completedWith : didCompleteWith,
|
||||||
|
solution: bonfireSolution,
|
||||||
|
bonfireHash: thisBonfireHash
|
||||||
|
}
|
||||||
|
},
|
||||||
|
url: '/completed-bonfire/'
|
||||||
|
|
||||||
$('.next-button').on('click', function() {
|
});
|
||||||
l = location.pathname.split('/');
|
|
||||||
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
//$.post( '/completed-bonfire', function( data ) {
|
||||||
});
|
// window.location = '/bonfires';
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.all-challenges').on('click', function() {
|
||||||
|
$('#all-challenges-dialog').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.all-bonfires').on('click', function() {
|
||||||
|
$('#all-bonfires-dialog').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.next-challenge-button').on('click', function() {
|
||||||
|
l = location.pathname.split('/');
|
||||||
|
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.next-bonfire-button').on('click', function() {
|
||||||
|
var bonfireSolution = myCodeMirror.getValue();
|
||||||
|
var thisBonfireHash = passedBonfireHash || null;
|
||||||
|
var didCompleteWith = $('#completed-with').val() || null;
|
||||||
|
|
||||||
|
completedBonfire(didCompleteWith, bonfireSolution, thisBonfireHash);
|
||||||
|
window.location = '/bonfires';
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bonfire instructions functions
|
||||||
|
$('#more-info').on('click', function() {
|
||||||
|
$('#brief-instructions').hide();
|
||||||
|
$('#long-instructions').show().removeClass('hide');
|
||||||
|
|
||||||
|
});
|
||||||
|
$('#less-info').on('click', function() {
|
||||||
|
$('#brief-instructions').show();
|
||||||
|
$('#long-instructions').hide();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var profileValidation = angular.module('profileValidation',['ui.bootstrap']);
|
var profileValidation = angular.module('profileValidation',['ui.bootstrap']);
|
||||||
@ -58,6 +108,12 @@ profileValidation.controller('profileValidationController', ['$scope', '$http',
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
profileValidation.controller('pairedWithController', ['$scope',
|
||||||
|
function($scope) {
|
||||||
|
$scope.existingUser = null;
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
profileValidation.controller('emailSignUpController', ['$scope',
|
profileValidation.controller('emailSignUpController', ['$scope',
|
||||||
function($scope) {
|
function($scope) {
|
||||||
|
|
||||||
@ -102,6 +158,31 @@ profileValidation.directive('uniqueUsername', function($http) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// TODO: FIX THIS
|
||||||
|
profileValidation.directive('existingUsername', function($http) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
require: 'ngModel',
|
||||||
|
link: function (scope, element, attrs, ngModel) {
|
||||||
|
element.bind("keyup", function (event) {
|
||||||
|
if (element.val().length > 0) {
|
||||||
|
ngModel.$setValidity('exists', false);
|
||||||
|
} else {
|
||||||
|
ngModel.$setPristine();
|
||||||
|
}
|
||||||
|
if (element.val()) {
|
||||||
|
$http.get("/api/checkExistingUsername/" + element.val() + ' ').success(function (data) {
|
||||||
|
if (element.val() == scope.existingUsername) {
|
||||||
|
ngModel.$setValidity('exists', false);
|
||||||
|
} else if (data) {
|
||||||
|
ngModel.$setValidity('exists', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
profileValidation.directive('uniqueEmail', function($http) {
|
profileValidation.directive('uniqueEmail', function($http) {
|
||||||
return {
|
return {
|
||||||
|
@ -1,44 +1,66 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "Palindrome Tester",
|
"_id" : "ad7123c8c441eddfaeb5bdef",
|
||||||
"difficulty": 1,
|
"name": "Meet Bonfire",
|
||||||
|
"difficulty": "0",
|
||||||
"description": [
|
"description": [
|
||||||
"Your job is to determine if a provided string is a palindrome.",
|
"Click the button below for further instructions.",
|
||||||
"The definition of a palindrome can be found at http://en.wikipedia.org/wiki/Palindrome.",
|
"Your goal is to fix the failing test.",
|
||||||
"Strings will be passed in with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others.",
|
"First, run all the tests by clickin \"Run code\" or by pressing Control + Enter",
|
||||||
"Return true if the string is a palindrome, otherwise false"
|
"The failing test is in red. Fix the code so that all tests pass. Then you can move on to the next Bonfire."
|
||||||
],
|
],
|
||||||
"publicTests": [
|
"tests": [
|
||||||
|
"expect(meetBonfire(\"test\")).to.be.a(\"boolean\");",
|
||||||
|
"expect(meetBonfire(\"test\")).to.be.true;"
|
||||||
|
],
|
||||||
|
"challengeSeed": "function meetBonfire(argument) {\n // Good luck!\n console.log(\"you can read this function's argument in the developer tools\", argument);\n\nreturn false;\n}\n\n",
|
||||||
|
"challengeEntryPoint": "meetBonfire(\"You can do this!\");"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id" : "aaa48de84e1ecc7c742e1124",
|
||||||
|
"name": "Check for Palindromes",
|
||||||
|
"difficulty": "1",
|
||||||
|
"description": [
|
||||||
|
"Return 'true' if a given string is a palindrome.",
|
||||||
|
"A palindrome is a word or sentence that's spelled the same way both forward and backward, ignoring punctuation and case.",
|
||||||
|
"You'll need to remove punctuation and turn everything lower case in order to check for palindromes.",
|
||||||
|
"We'll pass strings with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others.",
|
||||||
|
"Return true if the string is a palindrome. Otherwise, return false."
|
||||||
|
],
|
||||||
|
"tests": [
|
||||||
"expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
|
"expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
|
||||||
"assert.deepEqual(palindrome(\"eye\"), true);",
|
"assert.deepEqual(palindrome(\"eye\"), true);",
|
||||||
"assert.deepEqual(palindrome(\"race car\"), true);",
|
"assert.deepEqual(palindrome(\"race car\"), true);",
|
||||||
"assert.deepEqual(palindrome(\"not a palindrome\"), false);"
|
"assert.deepEqual(palindrome(\"not a palindrome\"), false);",
|
||||||
],
|
|
||||||
"privateTests": [
|
|
||||||
"assert.deepEqual(palindrome(\"A man, a plan, a canal. Panama\"), true);",
|
"assert.deepEqual(palindrome(\"A man, a plan, a canal. Panama\"), true);",
|
||||||
"assert.deepEqual(palindrome(\"never odd or even\"), true);",
|
"assert.deepEqual(palindrome(\"never odd or even\"), true);",
|
||||||
"assert.deepEqual(palindrome(\"nope\"), false);"
|
"assert.deepEqual(palindrome(\"nope\"), false);"
|
||||||
],
|
],
|
||||||
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n",
|
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n",
|
||||||
"challengeEntryPoint": "palindrome(\"eye\");",
|
"challengeEntryPoint": "palindrome(\"eye\");"
|
||||||
"bonfireNumber": 1,
|
|
||||||
"challengeEntryPointNegate" : "palindrome\\([^str].*\\;"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"_id" : "aff0395860f5d3034dc0bfc9",
|
||||||
"name": "Validate US Telephone Numbers",
|
"name": "Validate US Telephone Numbers",
|
||||||
"difficulty": 3,
|
"difficulty": "3",
|
||||||
"description": [
|
"description": [
|
||||||
|
"Return true if the passed string is a valid US phone number",
|
||||||
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
|
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
|
||||||
"555-555-5555, (555)555-5555, (555) 555-5555, 555 555 5555, 5555555555, 1 555 555 5555",
|
"555-555-5555, (555)555-5555, (555) 555-5555, 555 555 5555, 5555555555, 1 555 555 5555",
|
||||||
"For this challenge you will be presented with a string such as \"800-692-7753\" or \"8oo-six427676;laskdjf\". Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code code is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
|
"For this challenge you will be presented with a string such as \"800-692-7753\" or \"8oo-six427676;laskdjf\". Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code code is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
|
||||||
],
|
],
|
||||||
"publicTests": [
|
"tests": [
|
||||||
"expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
|
"expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"1 555-555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"1 (555) 555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"5555555555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"(555)555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"1(555)555-5555\"), true);",
|
||||||
|
"assert.deepEqual(telephoneCheck(\"1 555 555 5555\"), true);",
|
||||||
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
|
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
|
||||||
"assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
|
"assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
|
||||||
"assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);"
|
"assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);",
|
||||||
],
|
|
||||||
"privateTests": [
|
|
||||||
"assert.deepEqual(telephoneCheck(\"55555555\"), false);",
|
"assert.deepEqual(telephoneCheck(\"55555555\"), false);",
|
||||||
"assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
|
"assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
|
||||||
"assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
|
"assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
|
||||||
@ -52,9 +74,97 @@
|
|||||||
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
|
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
|
||||||
],
|
],
|
||||||
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
|
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
|
||||||
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");",
|
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");"
|
||||||
"bonfireNumber": 2,
|
},
|
||||||
"challengeEntryPointNegate" : "palindrome\\([^str].*\\;"
|
{
|
||||||
|
"_id": "a202eed8fc186c8434cb6d61",
|
||||||
|
"name": "Reverse a String",
|
||||||
|
"difficulty": "1",
|
||||||
|
"tests": [
|
||||||
|
"expect(reverseString('hello')).to.be.a('String');",
|
||||||
|
"expect(reverseString('hello')).to.equal('olleh');",
|
||||||
|
"expect(reverseString('Howdy')).to.equal('ydwoH');",
|
||||||
|
"expect(reverseString('Greetings from Earth')).to.equal('htraE morf sgniteerG');"
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
"Reverse the provided string.",
|
||||||
|
"You may need to turn the string into an array before you can reverse it.",
|
||||||
|
"Your result must be a string."
|
||||||
|
],
|
||||||
|
"challengeEntryPoint": "reverseString('hello');",
|
||||||
|
"challengeSeed": "function reverseString(str) {\n return str;\r\n}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "a302f7aae1aa3152a5b413bc",
|
||||||
|
"name": "Factorialize a Number",
|
||||||
|
"tests": [
|
||||||
|
"expect(factorialize(5)).to.be.a(\"Number\");",
|
||||||
|
"expect(factorialize(5)).to.equal(120);",
|
||||||
|
"expect(factorialize(10)).to.equal(3628800);",
|
||||||
|
"expect(factorialize(20)).to.equal(2432902008176640000);"
|
||||||
|
],
|
||||||
|
"difficulty": "1",
|
||||||
|
"description": [
|
||||||
|
"Return the factorial of the provided integer.",
|
||||||
|
"If the integer is represented with the letter n, a factorial is the product of all positive integers less than or equal to n.",
|
||||||
|
"Factorials are often represented with the shorthand notation n!",
|
||||||
|
"For example: 5! = 1 * 2 * 3 * 4 * 5 = 120f"
|
||||||
|
],
|
||||||
|
"challengeSeed": "function factorialize(num) {\n return num;\r\n}",
|
||||||
|
"challengeEntryPoint": "factorialize(5);"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "a26cbbe9ad8655a977e1ceb5",
|
||||||
|
"name": "Find the Longest Word in a String",
|
||||||
|
"difficulty": "1",
|
||||||
|
"description": [
|
||||||
|
"Return the length of the longest word in the provided sentence.",
|
||||||
|
"Your response should be a number."
|
||||||
|
],
|
||||||
|
"challengeEntryPoint": "findLongestWord('The quick brown fox jumped over the lazy dog');",
|
||||||
|
"challengeSeed": "function findLongestWord(str) {\n return str.length;\r\n}",
|
||||||
|
"tests": [
|
||||||
|
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.be.a('Number');",
|
||||||
|
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);",
|
||||||
|
"expect(findLongestWord('May the force be with you')).to.equal(5);",
|
||||||
|
"expect(findLongestWord('Google do a barrel roll')).to.equal(6);",
|
||||||
|
"expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "a3566b1109230028080c9345",
|
||||||
|
"name": "Sum All Numbers in a Range",
|
||||||
|
"difficulty": "2",
|
||||||
|
"description": [
|
||||||
|
"We'll pass you an array of two numbers. Return the sum those two numbers and all numbers between them.",
|
||||||
|
"The lowest number will not always come first."
|
||||||
|
],
|
||||||
|
"challengeEntryPoint": "sumAll([1, 4]);",
|
||||||
|
"challengeSeed": "function sumAll(arr) {\n return(1);\r\n}",
|
||||||
|
"tests": [
|
||||||
|
"expect(sumAll([1, 4])).to.be.a('Number');",
|
||||||
|
"expect(sumAll([1, 4])).to.equal(10);",
|
||||||
|
"expect(sumAll([4, 1])).to.equal(10);",
|
||||||
|
"expect(sumAll([5, 10])).to.equal(45);",
|
||||||
|
"expect(sumAll([10, 5])).to.equal(45);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "ab6137d4e35944e21037b769",
|
||||||
|
"name": "Title Case a Sentence",
|
||||||
|
"difficulty": "1",
|
||||||
|
"description": [
|
||||||
|
"Return the provided string with the first letter of each word capitalized.",
|
||||||
|
"For the purpose of this exercise, you should also capitalize connecting words like 'the' and 'of'."
|
||||||
|
],
|
||||||
|
"challengeEntryPoint": "titleCase(\"I'm a little tea pot\")",
|
||||||
|
"challengeSeed": "function titleCase(str) {\n return str;\r\n}",
|
||||||
|
"tests": [
|
||||||
|
"expect(titleCase(\"I'm a little tea pot\")).to.be.a('String');",
|
||||||
|
"expect(titleCase(\"I'm a little tea pot\")).to.equal(\"I'm A Little Tea Pot\");",
|
||||||
|
"expect(titleCase(\"sHoRt AnD sToUt\")).to.equal(\"Short And Stout\");",
|
||||||
|
"expect(titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\")).to.equal(\"Here Is My Handle Here Is My Spout\");"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
"aaa48de84e1ecc7c742e1124"
|
|
||||||
"ff0395860f5d3034dc0bfc94"
|
|
||||||
"7123c8c441eddfaeb5bdef0d"
|
|
||||||
"c3a4d278b9e760a0ffe8321f"
|
|
||||||
"aceca143b92049a4392a859e"
|
"aceca143b92049a4392a859e"
|
||||||
"ce9394f67d413734758e27e4"
|
"ce9394f67d413734758e27e4"
|
||||||
"1369953ef6f03098cb60e2f7"
|
"1369953ef6f03098cb60e2f7"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
extends ../layout
|
extends ../layout-wide
|
||||||
block content
|
block content
|
||||||
script(src='/js/lib/codemirror/lib/codemirror.js')
|
script(src='/js/lib/codemirror/lib/codemirror.js')
|
||||||
script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
|
script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
|
||||||
@ -15,9 +15,15 @@ block content
|
|||||||
script(src='/js/lib/jailed/jailed.js')
|
script(src='/js/lib/jailed/jailed.js')
|
||||||
script(src='/js/lib/bonfire/bonfireInit.js')
|
script(src='/js/lib/bonfire/bonfireInit.js')
|
||||||
.row
|
.row
|
||||||
|
script(type="text/javascript").
|
||||||
|
var tests = !{JSON.stringify(tests)};
|
||||||
|
var challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||||
|
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
|
||||||
|
var title = !{JSON.stringify(title)};
|
||||||
|
|
||||||
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
||||||
.panel.panel-primary.panel-bonfire
|
.panel.panel-primary.panel-bonfire
|
||||||
.panel-heading.text-center Bonfire Playground
|
.panel-heading.text-center Playground
|
||||||
.panel.panel-body
|
.panel.panel-body
|
||||||
form.code
|
form.code
|
||||||
.form-group.codeMirrorView
|
.form-group.codeMirrorView
|
||||||
|
45
views/bonfire/generator.jade
Normal file
45
views/bonfire/generator.jade
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
extends ../layout
|
||||||
|
block content
|
||||||
|
.row
|
||||||
|
.col-md-offset-2.col-md-8.col-lg-offset-2.col-lg-8.text-center
|
||||||
|
|
||||||
|
h1 JSON generator for bonfire challenges - just fill the form out and get the correct format back
|
||||||
|
.col-xs-12.col-sm-12.col-md-offset-1.col-md-10.col-lg-offset-1-col-lg-10
|
||||||
|
.panel
|
||||||
|
form.form-horizontal(method="POST", action="/bonfire-json-generator", name="bonfireInfo")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label(for='name') name:
|
||||||
|
.col-sm-10
|
||||||
|
input#name.form-control(type='text', placeholder='name', name="name")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label(for='difficultyField') difficulty:
|
||||||
|
.col-sm-10
|
||||||
|
label.radio-inline 1
|
||||||
|
input#inlineRadio1(type='radio', name='difficulty', value='1')
|
||||||
|
label.radio-inline 2
|
||||||
|
input#inlineRadio2(type='radio', name='difficulty', value='2')
|
||||||
|
label.radio-inline 3
|
||||||
|
input#inlineRadio3(type='radio', name='difficulty', value='3')
|
||||||
|
label.radio-inline 4
|
||||||
|
input#inlineRadio4(type='radio', name='difficulty', value='4')
|
||||||
|
label.radio-inline 5
|
||||||
|
input#inlineRadio5(type='radio', name='difficulty', value='5')
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='description') description:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#description.form-control(name="description", placeholder="Separate sentences by exactly one space only. Do not add in line breaks.")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='challengeSeed') challengeSeed:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#challengeSeed.form-control(name="challengeSeed", rows=5)
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='challengeEntryPoint') challenge entrypoint:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#name.form-control(name="challengeEntryPoint", rows=1, type='text', placeholder="palindrome(\"eye\");")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='tests') tests:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#tests.form-control(name="tests", rows=5, placeholder="Separate tests by a newline.")
|
||||||
|
.form-group
|
||||||
|
.col-sm-offset-2.col-sm-10
|
||||||
|
input.btn.btn-default(type='submit', value="submit")
|
44
views/bonfire/public-generator.jade
Normal file
44
views/bonfire/public-generator.jade
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
extends ../layout
|
||||||
|
block content
|
||||||
|
.row
|
||||||
|
.col-md-offset-2.col-md-8.col-lg-offset-2.col-lg-8.text-center
|
||||||
|
h1 Welcome to the challenge generator. Test your ideas out and see them live in bonfire!
|
||||||
|
.col-xs-12.col-sm-12.col-md-offset-1.col-md-10.col-lg-offset-1-col-lg-10
|
||||||
|
.panel
|
||||||
|
form.form-horizontal(method="POST", action="/bonfire-challenge-generator", name="bonfireInfo")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label(for='name') name:
|
||||||
|
.col-sm-10
|
||||||
|
input#name.form-control(type='text', placeholder='name', name="name")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label(for='difficultyField') difficulty:
|
||||||
|
.col-sm-10
|
||||||
|
label.radio-inline 1
|
||||||
|
input#inlineRadio1(type='radio', name='difficulty', value='1')
|
||||||
|
label.radio-inline 2
|
||||||
|
input#inlineRadio2(type='radio', name='difficulty', value='2')
|
||||||
|
label.radio-inline 3
|
||||||
|
input#inlineRadio3(type='radio', name='difficulty', value='3')
|
||||||
|
label.radio-inline 4
|
||||||
|
input#inlineRadio4(type='radio', name='difficulty', value='4')
|
||||||
|
label.radio-inline 5
|
||||||
|
input#inlineRadio5(type='radio', name='difficulty', value='5')
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='description') description:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#description.form-control(name="description", placeholder="Separate sentences by exactly one space only. Do not add in line breaks.")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='challengeSeed') challengeSeed:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#challengeSeed.form-control(name="challengeSeed", rows=5)
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='challengeEntryPoint') challenge entrypoint:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#name.form-control(name="challengeEntryPoint", rows=1, type='text', placeholder="palindrome(\"eye\");")
|
||||||
|
.form-group
|
||||||
|
label.col-sm-2.control-label.wrappable(for='tests') tests:
|
||||||
|
.col-sm-10
|
||||||
|
textarea#tests.form-control(name="tests", rows=5, placeholder="Separate tests by a newline.")
|
||||||
|
.form-group
|
||||||
|
.col-sm-offset-2.col-sm-10
|
||||||
|
input.btn.btn-default(type='submit', value="submit")
|
@ -1,4 +1,4 @@
|
|||||||
extends ../layout
|
extends ../layout-wide
|
||||||
block content
|
block content
|
||||||
|
|
||||||
script(src='/js/lib/codemirror/lib/codemirror.js')
|
script(src='/js/lib/codemirror/lib/codemirror.js')
|
||||||
@ -18,33 +18,123 @@ block content
|
|||||||
|
|
||||||
|
|
||||||
.row
|
.row
|
||||||
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
|
.col-xs-12.col-sm-12.col-md-4.bonfire-top
|
||||||
.panel.panel-primary.panel-bonfire
|
#testCreatePanel
|
||||||
.panel-heading.text-center #{name} (Level #{difficulty} bonfire)
|
|
||||||
.panel.panel-body
|
h2.text-center= name
|
||||||
.well
|
h2.text-center.bonfire-flames
|
||||||
.text-justify.bonfire-instructions
|
if (difficulty == "0")
|
||||||
for sentence in description
|
i.ion-ios-flame-outline
|
||||||
p.bonfire-instructions!= sentence
|
i.ion-ios-flame-outline
|
||||||
form.code
|
i.ion-ios-flame-outline
|
||||||
.form-group.codeMirrorView
|
i.ion-ios-flame-outline
|
||||||
textarea#codeEditor(autofocus=true)
|
i.ion-ios-flame-outline
|
||||||
#testCreatePanel.col-sm-12.col-md-5.col-xs-12
|
if (difficulty == "1")
|
||||||
.panel.panel-primary.panel-bonfire
|
i.ion-ios-flame
|
||||||
.panel-heading.text-center Output
|
i.ion-ios-flame-outline
|
||||||
.panel.panel-body
|
i.ion-ios-flame-outline
|
||||||
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
|
i.ion-ios-flame-outline
|
||||||
br
|
i.ion-ios-flame-outline
|
||||||
form.code
|
if (difficulty == "2")
|
||||||
.form-group.codeMirrorView
|
i.ion-ios-flame
|
||||||
textarea#codeOutput
|
i.ion-ios-flame
|
||||||
br
|
i.ion-ios-flame-outline
|
||||||
ul#testSuite.list-group
|
i.ion-ios-flame-outline
|
||||||
br
|
i.ion-ios-flame-outline
|
||||||
script(type="text/javascript").
|
if (difficulty == "3")
|
||||||
var publicTests = !{JSON.stringify(publicTests)};
|
i.ion-ios-flame
|
||||||
var privateTests = !{JSON.stringify(privateTests)};
|
i.ion-ios-flame
|
||||||
var challengeSeed = !{JSON.stringify(challengeSeed)};
|
i.ion-ios-flame
|
||||||
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
|
i.ion-ios-flame-outline
|
||||||
var challengeEntryPointNegate = !{JSON.stringify(challengeEntryPointNegate)};
|
i.ion-ios-flame-outline
|
||||||
script(src='/js/lib/bonfire/bonfireFramework.js')
|
if (difficulty == "4")
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame-outline
|
||||||
|
if (difficulty == "5")
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
i.ion-ios-flame
|
||||||
|
.well
|
||||||
|
.row.text-center
|
||||||
|
row.text-center
|
||||||
|
.col-xs-12
|
||||||
|
.bonfire-instructions
|
||||||
|
= brief
|
||||||
|
#brief-instructions.col-xs-12
|
||||||
|
button#more-info.btn.btn-info
|
||||||
|
span.ion-help-circled
|
||||||
|
| More information
|
||||||
|
#long-instructions.row.text-center.hide
|
||||||
|
.col-xs-12
|
||||||
|
.bonfire-instructions
|
||||||
|
for sentence in details
|
||||||
|
p!= sentence
|
||||||
|
button#less-info.btn.btn-info
|
||||||
|
span.ion-help-circled
|
||||||
|
| Less information
|
||||||
|
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
|
||||||
|
br
|
||||||
|
form.code
|
||||||
|
.form-group.codeMirrorView
|
||||||
|
textarea#codeOutput
|
||||||
|
br
|
||||||
|
#testSuite
|
||||||
|
br
|
||||||
|
script(type="text/javascript").
|
||||||
|
var tests = !{JSON.stringify(tests)};
|
||||||
|
var challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||||
|
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
|
||||||
|
var passedBonfireHash = !{JSON.stringify(bonfireHash)};
|
||||||
|
.col-xs-12.col-sm-12.col-md-8
|
||||||
|
#mainEditorPanel
|
||||||
|
form.code
|
||||||
|
.form-group.codeMirrorView
|
||||||
|
textarea#codeEditor(autofocus=true)
|
||||||
|
script(src='/js/lib/bonfire/bonfireFramework.js')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#complete-bonfire-dialog.modal(tabindex='-1')
|
||||||
|
.modal-dialog.animated.zoomIn.fast-animation
|
||||||
|
.modal-content
|
||||||
|
.modal-header.challenge-list-header= compliment
|
||||||
|
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
|
||||||
|
.modal-body(ng-controller="pairedWithController")
|
||||||
|
|
||||||
|
.text-center
|
||||||
|
.animated.zoomInDown.delay-half
|
||||||
|
span.landing-icon.ion-checkmark-circled.text-primary
|
||||||
|
- if (cc)
|
||||||
|
form.form-horizontal(novalidate='novalidate', name='completedWithForm')
|
||||||
|
.form-group.text-center
|
||||||
|
.col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2.animated.fadeIn
|
||||||
|
// extra field to distract password tools like lastpass from injecting css into our username field
|
||||||
|
input.form-control(ng-show="false")
|
||||||
|
input.form-control#completed-with(name="existingUser", placeholder="If you paired, enter your pair's username here", existing-username='', ng-model="existingUser", autofocus)
|
||||||
|
.col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2(ng-show="completedWithForm.$error.exists && !completedWithForm.existingUser.$pristine && existingUser.length > 0")
|
||||||
|
alert(type='danger')
|
||||||
|
span.ion-close-circled
|
||||||
|
| Username not found
|
||||||
|
|
||||||
|
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-bonfire-button(name='_csrf', value=_csrf, aria-hidden='true', ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Take me to my next challenge
|
||||||
|
|
||||||
|
|
||||||
|
- if (points && points > 2)
|
||||||
|
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Challenge%20%23#{number}:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/bonfires/#{number}&hashtags=learntocode, javascript" target="_blank")
|
||||||
|
i.fa.fa-twitter
|
||||||
|
= phrase
|
||||||
|
- else
|
||||||
|
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
|
||||||
|
|
||||||
|
#all-bonfires-dialog.modal(tabindex='-1')
|
||||||
|
.modal-dialog.animated.fadeInUp.fast-animation
|
||||||
|
.modal-content
|
||||||
|
.modal-header.challenge-list-header Bonfires
|
||||||
|
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
|
||||||
|
.modal-body
|
||||||
|
include ../partials/bonfires
|
||||||
|
@ -16,19 +16,19 @@ block content
|
|||||||
.btn.btn-primary.btn-big.btn-block.completed-challenge I've completed this challenge
|
.btn.btn-primary.btn-big.btn-block.completed-challenge I've completed this challenge
|
||||||
.ten-pixel-break
|
.ten-pixel-break
|
||||||
.btn.btn-success.btn-big.btn-block.all-challenges Show me all the challenges
|
.btn.btn-success.btn-big.btn-block.all-challenges Show me all the challenges
|
||||||
#complete-dialog.modal(tabindex='-1')
|
#complete-challenge-dialog.modal(tabindex='-1')
|
||||||
.modal-dialog.animated.zoomIn.fast-animation
|
.modal-dialog.animated.zoomIn.fast-animation
|
||||||
.modal-content
|
.modal-content
|
||||||
.modal-header.challenge-list-header Nicely done!
|
.modal-header.challenge-list-header= compliment
|
||||||
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
|
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
|
||||||
.modal-body
|
.modal-body
|
||||||
.text-center
|
.text-center
|
||||||
.animated.zoomInDown.delay-half
|
.animated.zoomInDown.delay-half
|
||||||
span.landing-icon.ion-checkmark-circled.text-primary
|
span.landing-icon.ion-checkmark-circled.text-primary
|
||||||
- if (cc)
|
- if (cc)
|
||||||
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-button(name='_csrf', value=_csrf, aria-hidden='true') Take me to my next challenge
|
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-challenge-button(name='_csrf', value=_csrf, aria-hidden='true') Take me to my next challenge
|
||||||
- if (points && points > 2)
|
- if (points && points > 2)
|
||||||
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20Free%20Code%20Camp%20Challenge%20%23#{number}:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{number}&hashtags=learntocode, javascript" target="_blank")
|
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Challenge%20%23#{number}:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{number}&hashtags=learntocode, javascript" target="_blank")
|
||||||
i.fa.fa-twitter
|
i.fa.fa-twitter
|
||||||
= phrase
|
= phrase
|
||||||
- else
|
- else
|
||||||
|
33
views/layout-wide.jade
Normal file
33
views/layout-wide.jade
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
doctype html
|
||||||
|
html(ng-app='profileValidation', lang='en')
|
||||||
|
head
|
||||||
|
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
|
||||||
|
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js")
|
||||||
|
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
|
||||||
|
link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicon.ico')
|
||||||
|
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css')
|
||||||
|
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css')
|
||||||
|
link(rel='stylesheet', href='//code.ionicframework.com/ionicons/2.0.0/css/ionicons.min.css')
|
||||||
|
include partials/meta
|
||||||
|
title #{title} | Free Code Camp
|
||||||
|
meta(charset='utf-8')
|
||||||
|
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||||
|
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
||||||
|
meta(name='csrf-token', content=_csrf)
|
||||||
|
!= css('main')
|
||||||
|
|
||||||
|
body.no-top-and-bottom-margins.full-screen-body-background
|
||||||
|
include partials/navbar-wide
|
||||||
|
include partials/flash
|
||||||
|
block content
|
||||||
|
include partials/footer
|
||||||
|
!= js('application')
|
||||||
|
script.
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
ga('create', 'UA-55446531-1', 'auto');
|
||||||
|
ga('require', 'displayfeatures');
|
||||||
|
ga('send', 'pageview');
|
||||||
|
script(src="//cdn.optimizely.com/js/999692993.js")
|
@ -16,14 +16,13 @@ html(ng-app='profileValidation', lang='en')
|
|||||||
meta(name='csrf-token', content=_csrf)
|
meta(name='csrf-token', content=_csrf)
|
||||||
!= css('main')
|
!= css('main')
|
||||||
|
|
||||||
body
|
body.top-and-bottom-margins
|
||||||
include partials/navbar
|
include partials/navbar-narrow
|
||||||
|
|
||||||
.container
|
.container
|
||||||
include partials/flash
|
include partials/flash
|
||||||
block content
|
block content
|
||||||
include partials/footer
|
include partials/footer
|
||||||
!= js('application')
|
!= js('application')
|
||||||
script.
|
script.
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
@ -1 +1,7 @@
|
|||||||
//TODO: STUFF
|
h3
|
||||||
|
ol(start='0')
|
||||||
|
for bonfire in bonfires
|
||||||
|
li
|
||||||
|
a(href="/bonfires/#{bonfire.bonfireNumber}", class="#{ (cc && cc[bonfire.bonfireNumber] > 0) ? 'strikethrough' : '' }") #{bonfire.name}
|
||||||
|
| (Level #{bonfire.difficulty})
|
||||||
|
a.btn.btn-lg.btn-primary.btn-block(href="/done-with-first-100-hours", class="#{ ((cc && cc[53] === 0) || (!cc)) ? 'disabled' : '' }") I'm done with all the challenges!
|
@ -15,4 +15,6 @@
|
|||||||
|
|
|
|
||||||
a.ion-information-circled(title="About Free Code Camp", href="/learn-to-code")
|
a.ion-information-circled(title="About Free Code Camp", href="/learn-to-code")
|
||||||
|
|
|
|
||||||
a.ion-locked(title="Free Code Camp's Privacy Policy", href="/privacy")
|
a.ion-locked(title="Free Code Camp's Privacy Policy", href="/privacy")
|
||||||
|
|
|
||||||
|
a.ion-code-working(title="Bonfire Coding Playground", href="/playground")
|
3
views/partials/navbar-narrow.jade
Normal file
3
views/partials/navbar-narrow.jade
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
nav.navbar.navbar-default.navbar-fixed-top.nav-height
|
||||||
|
.container
|
||||||
|
include ./navbar
|
2
views/partials/navbar-wide.jade
Normal file
2
views/partials/navbar-wide.jade
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
nav.navbar.navbar-default.navbar-fixed-top.nav-height
|
||||||
|
include ./navbar
|
@ -1,46 +1,44 @@
|
|||||||
nav.navbar.navbar-default.navbar-fixed-top.nav-height
|
.navbar-header
|
||||||
.container
|
button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
|
||||||
.navbar-header
|
|
||||||
button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
|
|
||||||
span.sr-only Toggle navigation
|
span.sr-only Toggle navigation
|
||||||
span.icon-bar
|
span.icon-bar
|
||||||
span.icon-bar
|
span.icon-bar
|
||||||
span.icon-bar
|
span.icon-bar
|
||||||
a.navbar-brand(href='/')
|
a.navbar-brand(href='/')
|
||||||
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
|
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
|
||||||
.collapse.navbar-collapse
|
.collapse.navbar-collapse
|
||||||
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
||||||
- if (!cc)
|
- if (!cc)
|
||||||
li
|
li
|
||||||
a(href='/challenges/0') Challenges
|
a(href='/challenges/0') Challenges
|
||||||
- else
|
- else
|
||||||
li
|
li
|
||||||
a(href='/') Challenges
|
a(href='/') Challenges
|
||||||
- if (!cc || (cc && cc[1] < 1))
|
- if (!cc || (cc && cc[1] < 1))
|
||||||
li
|
li
|
||||||
a(href='/challenges/1') Chat
|
a(href='/challenges/1') Chat
|
||||||
- else
|
- else
|
||||||
li
|
li
|
||||||
a(href='http://chat.freecodecamp.com' target='_blank') Chat
|
a(href='http://chat.freecodecamp.com' target='_blank') Chat
|
||||||
- if (!cc || (cc && cc[2] < 1))
|
- if (!cc || (cc && cc[2] < 1))
|
||||||
li
|
li
|
||||||
a(href='/challenges/2') Forum
|
a(href='/challenges/2') Forum
|
||||||
- else
|
- else
|
||||||
li
|
li
|
||||||
a(href='http://forum.freecodecamp.com' target='_blank') Forum
|
a(href='http://forum.freecodecamp.com' target='_blank') Forum
|
||||||
li
|
li
|
||||||
a(href='/bonfire') Bonfire
|
a(href='/bonfires') Bonfires
|
||||||
li
|
|
||||||
if !user
|
if !user
|
||||||
li
|
li
|
||||||
a.btn.signup-btn.signup-btn-nav(href='/login') Sign in
|
li
|
||||||
|
a.btn.signup-btn.signup-btn-nav(href='/login') Sign in
|
||||||
else
|
else
|
||||||
li
|
li
|
||||||
a(href='/account') [ #{user.points} ]
|
a(href='/account') [ #{user.points} ]
|
||||||
.hidden-xs
|
.hidden-xs
|
||||||
if user.profile.picture
|
if user.profile.picture
|
||||||
a(href='/account')
|
a(href='/account')
|
||||||
img.profile-picture.float-right(src='#{user.profile.picture}')
|
img.profile-picture.float-right(src='#{user.profile.picture}')
|
||||||
else
|
else
|
||||||
a(href='/account')
|
a(href='/account')
|
||||||
img.profile-picture.float-right(src='#{user.gravatar(60)}')
|
img.profile-picture.float-right(src='#{user.gravatar(60)}')
|
@ -1,91 +1,50 @@
|
|||||||
doctype html
|
extends ../layout-wide
|
||||||
html(ng-app='profileValidation', lang='en')
|
block content
|
||||||
head
|
include ../partials/navbar-wide
|
||||||
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
|
.panel
|
||||||
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js")
|
.panel-body
|
||||||
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
|
.landing-panel-body.text-center
|
||||||
link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicon.ico')
|
h1 Live Pair Programming
|
||||||
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css')
|
h2 We live pair program every Tuesday from 9 pm to 10 pm EST (Eastern Standard Time).
|
||||||
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css')
|
h2 Our next session will be January 27th, 2015 at 9 p.m. EST!
|
||||||
link(rel='stylesheet', href='//code.ionicframework.com/ionicons/2.0.0/css/ionicons.min.css')
|
h2 Watch the live stream below or on our
|
||||||
include ../partials/meta
|
a(href="http://twitch.tv/freecodecamp", target='_blank') Twitch.tv channel
|
||||||
title #{title} | Free Code Camp
|
| .
|
||||||
meta(charset='utf-8')
|
.row
|
||||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
.col-md-8.col-xs-12
|
||||||
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
.embed-responsive.embed-responsive-16by9
|
||||||
meta(name='csrf-token', content=_csrf)
|
iframe(src='http://www.twitch.tv/freecodecamp/embed', frameborder='0', scrolling='no')
|
||||||
!= css('main')
|
.col-md-4.col-xs-12
|
||||||
body
|
.visible-sm.visible-xs
|
||||||
block content
|
.embed-responsive.embed-responsive-16by9
|
||||||
include ../partials/navbar
|
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
|
||||||
.panel.panel-primary
|
.visible-md.visible-lg
|
||||||
.panel-heading.landing-panel-heading.text-center Live Pair Programming
|
.embed-responsive.embed-responsive-twitch-chat
|
||||||
.panel-body
|
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
|
||||||
.landing-panel-body.text-center
|
|
||||||
h2 We live pair program every Tuesday from 9 pm to 10 pm EST (Eastern Standard Time).
|
|
||||||
h2 Our next session will be January 27th, 2015 at 9 p.m. EST!
|
|
||||||
h2 Join the discussion in our
|
|
||||||
a(href="chat.freecodecamp.com", target="_blank") FreeCodeCamp chat room.
|
|
||||||
h2 Watch the live stream below or on our
|
|
||||||
a(href="http://twitch.tv/freecodecamp", target='_blank') Twitch.tv channel
|
|
||||||
| .
|
|
||||||
.row
|
|
||||||
.col-md-8.col-xs-12
|
|
||||||
.embed-responsive.embed-responsive-16by9
|
|
||||||
iframe(src='http://www.twitch.tv/freecodecamp/embed', frameborder='0', scrolling='no')
|
|
||||||
.col-md-4.col-xs-12
|
|
||||||
.visible-sm.visible-xs
|
|
||||||
.embed-responsive.embed-responsive-16by9
|
|
||||||
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
|
|
||||||
.visible-md.visible-lg
|
|
||||||
.embed-responsive.embed-responsive-twitch-chat
|
|
||||||
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
|
|
||||||
|
|
||||||
br
|
h1 Previous Live Pair Programming Sessions
|
||||||
.panel.panel-primary
|
.col-xs-12
|
||||||
.panel-heading.landing-panel-heading.text-center Previous Live Pair Programming Sessions
|
.embed-responsive.embed-responsive-16by9.big-break
|
||||||
.panel-body
|
iframe.embed-responsive-item(src='//www.youtube.com/embed/_BErpDdmBOw')
|
||||||
.landing-panel-body.text-center
|
h3.wrappable link:
|
||||||
.col-xs-12
|
a(href="http://www.youtube.com/watch/_BErpDdmBOw") http://www.youtube.com/watch/_BErpDdmBOw
|
||||||
.embed-responsive.embed-responsive-16by9.big-break
|
.embed-responsive.embed-responsive-16by9.big-break
|
||||||
iframe.embed-responsive-item(src='//www.youtube.com/embed/_BErpDdmBOw')
|
iframe.embed-responsive-item(src='//www.youtube.com/embed/Fn9HMn79KH0')
|
||||||
h3.wrappable link:
|
h3.wrappable link:
|
||||||
a(href="http://www.youtube.com/watch/_BErpDdmBOw") http://www.youtube.com/watch/_BErpDdmBOw
|
a(href="http://www.youtube.com/watch/Fn9HMn79KH0") http://www.youtube.com/watch/Fn9HMn79KH0
|
||||||
.embed-responsive.embed-responsive-16by9.big-break
|
.embed-responsive.embed-responsive-16by9.big-break
|
||||||
iframe.embed-responsive-item(src='//www.youtube.com/embed/Fn9HMn79KH0')
|
iframe.embed-responsive-item(src='//www.youtube.com/embed/S7iRBZJwOAs')
|
||||||
h3.wrappable link:
|
h3.wrappable link:
|
||||||
a(href="http://www.youtube.com/watch/Fn9HMn79KH0") http://www.youtube.com/watch/Fn9HMn79KH0
|
a(href="http://www.youtube.com/watch/S7iRBZJwOAs") http://www.youtube.com/watch/S7iRBZJwOAs
|
||||||
.embed-responsive.embed-responsive-16by9.big-break
|
.embed-responsive.embed-responsive-16by9.big-break
|
||||||
iframe.embed-responsive-item(src='//www.youtube.com/embed/S7iRBZJwOAs')
|
iframe.embed-responsive-item(src='//www.youtube.com/embed/BHNRg39ZblE')
|
||||||
h3.wrappable link:
|
h3.wrappable link:
|
||||||
a(href="http://www.youtube.com/watch/S7iRBZJwOAs") http://www.youtube.com/watch/S7iRBZJwOAs
|
a(href="http://www.youtube.com/watch/BHNRg39ZblE") http://www.youtube.com/watch/BHNRg39ZblE
|
||||||
.embed-responsive.embed-responsive-16by9.big-break
|
.embed-responsive.embed-responsive-16by9.big-break
|
||||||
iframe.embed-responsive-item(src='//www.youtube.com/embed/BHNRg39ZblE')
|
iframe.embed-responsive-item(src='//www.youtube.com/embed/YDfkHlDmehA')
|
||||||
h3.wrappable link:
|
h3.wrappable link:
|
||||||
a(href="http://www.youtube.com/watch/BHNRg39ZblE") http://www.youtube.com/watch/BHNRg39ZblE
|
a(href="http://www.youtube.com/watch/YDfkHlDmehA") http://www.youtube.com/watch/YDfkHlDmehA
|
||||||
.embed-responsive.embed-responsive-16by9.big-break
|
h3 Got 3 minutes? Learn to code with us!
|
||||||
iframe.embed-responsive-item(src='//www.youtube.com/embed/YDfkHlDmehA')
|
a.btn.btn-cta.signup-btn.btn-primary(href="/login") Start learning to code (it's free)
|
||||||
h3.wrappable link:
|
br
|
||||||
a(href="http://www.youtube.com/watch/YDfkHlDmehA") http://www.youtube.com/watch/YDfkHlDmehA
|
br
|
||||||
h3 Got 3 minutes? Learn to code with us!
|
|
||||||
a.btn.btn-cta.signup-btn.btn-primary(href="/login") Start learning to code (it's free)
|
|
||||||
br
|
|
||||||
br
|
|
||||||
include ../partials/footer
|
|
||||||
!= js('application')
|
|
||||||
script.
|
|
||||||
(function (i, s, o, g, r, a, m) {
|
|
||||||
i['GoogleAnalyticsObject'] = r;
|
|
||||||
i[r] = i[r] || function () {
|
|
||||||
(i[r].q = i[r].q || []).push(arguments)
|
|
||||||
}, i[r].l = 1 * new Date();
|
|
||||||
a = s.createElement(o),
|
|
||||||
m = s.getElementsByTagName(o)[0];
|
|
||||||
a.async = 1;
|
|
||||||
a.src = g;
|
|
||||||
m.parentNode.insertBefore(a, m)
|
|
||||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
|
||||||
ga('create', 'UA-55446531-1', 'auto');
|
|
||||||
ga('require', 'displayfeatures');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
script(src="//cdn.optimizely.com/js/999692993.js")
|
|
Reference in New Issue
Block a user