diff --git a/controllers/bonfire.js b/controllers/bonfire.js
index 514d473130..49b143fd43 100644
--- a/controllers/bonfire.js
+++ b/controllers/bonfire.js
@@ -24,7 +24,6 @@ exports.index = function(req, res) {
details: '',
tests: [],
challengeSeed: '',
- challengeEntryPoint: '',
cc: req.user ? req.user.bonfiresHash : undefined,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
@@ -105,7 +104,6 @@ exports.returnIndividualBonfire = function(req, res, next) {
details: bonfire.description.slice(1),
tests: bonfire.tests,
challengeSeed: bonfire.challengeSeed,
- challengeEntryPoint: bonfire.challengeEntryPoint,
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
@@ -131,7 +129,6 @@ exports.returnGenerator = function(req, res) {
details: null,
tests: null,
challengeSeed: null,
- challengeEntryPoint: null,
bonfireHash: randomString()
});
};
@@ -160,7 +157,6 @@ exports.testBonfire = function(req, res) {
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');
@@ -176,7 +172,6 @@ exports.testBonfire = function(req, res) {
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(),
@@ -202,7 +197,6 @@ exports.generateChallenge = function(req, res) {
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');
@@ -216,7 +210,6 @@ exports.generateChallenge = function(req, res) {
name: bonfireName,
difficulty: bonfireDifficulty,
description: bonfireDescription,
- challengeEntryPoint: bonfireEntryPoint,
challengeSeed: bonfireChallengeSeed,
tests: bonfireTests
};
diff --git a/controllers/courseware.js b/controllers/courseware.js
index fe48720a35..eca76fd68a 100644
--- a/controllers/courseware.js
+++ b/controllers/courseware.js
@@ -72,23 +72,84 @@ exports.returnIndividualCourseware = function(req, res, next) {
return res.redirect('../coursewares/' + dashedNameFull);
}
- // Render the view for the user
- res.render('coursewares/show', {
- title: courseware.name,
- dashedName: dashedName,
- name: courseware.name,
- brief: courseware.description[0],
- details: courseware.description.slice(1),
- tests: courseware.tests,
- challengeSeed: courseware.challengeSeed,
- cc: !!req.user,
- points: req.user ? req.user.points : undefined,
- verb: resources.randomVerb(),
- phrase: resources.randomPhrase(),
- compliment: resources.randomCompliment(),
- coursewareHash: courseware._id,
- environment: resources.whichEnvironment()
- });
+ var challengeType = {
+ 0 : function() {
+ res.render('coursewares/show', {
+ title: courseware.name,
+ dashedName: dashedName,
+ name: courseware.name,
+ brief: courseware.description[0],
+ details: courseware.description.slice(1),
+ tests: courseware.tests,
+ challengeSeed: courseware.challengeSeed,
+ cc: !!req.user,
+ points: req.user ? req.user.points : undefined,
+ verb: resources.randomVerb(),
+ phrase: resources.randomPhrase(),
+ compliment: resources.randomCompliment(),
+ coursewareHash: courseware._id,
+ environment: resources.whichEnvironment()
+ });
+ },
+
+ 1 : function() {
+ res.render('coursewares/showJS', {
+ title: courseware.name,
+ dashedName: dashedName,
+ name: courseware.name,
+ brief: courseware.description[0],
+ details: courseware.description.slice(1),
+ tests: courseware.tests,
+ challengeSeed: courseware.challengeSeed,
+ cc: !!req.user,
+ points: req.user ? req.user.points : undefined,
+ verb: resources.randomVerb(),
+ phrase: resources.randomPhrase(),
+ compliment: resources.randomCompliment(),
+ coursewareHash: courseware._id,
+ environment: resources.whichEnvironment(),
+
+ });
+ },
+
+ 2: function() {
+ res.render('coursewares/showVideo', {
+ title: courseware.name,
+ dashedName: dashedName,
+ name: courseware.name,
+ details: courseware.description,
+ tests: courseware.tests,
+ video: courseware.challengeSeed[0],
+ cc: !!req.user,
+ points: req.user ? req.user.points : undefined,
+ verb: resources.randomVerb(),
+ phrase: resources.randomPhrase(),
+ compliment: resources.randomCompliment(),
+ coursewareHash: courseware._id,
+ environment: resources.whichEnvironment()
+ });
+ }
+ };
+
+ return challengeType[courseware.challengeType]();
+
+ //// Render the view for the user
+ //res.render('coursewares/show', {
+ // title: courseware.name,
+ // dashedName: dashedName,
+ // name: courseware.name,
+ // brief: courseware.description[0],
+ // details: courseware.description.slice(1),
+ // tests: courseware.tests,
+ // challengeSeed: courseware.challengeSeed,
+ // cc: !!req.user,
+ // points: req.user ? req.user.points : undefined,
+ // verb: resources.randomVerb(),
+ // phrase: resources.randomPhrase(),
+ // compliment: resources.randomCompliment(),
+ // coursewareHash: courseware._id,
+ // environment: resources.whichEnvironment()
+ //});
});
};
diff --git a/models/Bonfire.js b/models/Bonfire.js
index d8785f7196..cee4c8413a 100644
--- a/models/Bonfire.js
+++ b/models/Bonfire.js
@@ -15,8 +15,7 @@ var bonfireSchema = new mongoose.Schema({
difficulty: String,
description: Array,
tests: Array,
- challengeSeed: String,
- challengeEntryPoint: String,
+ challengeSeed: String
});
module.exports = mongoose.model('Bonfire', bonfireSchema);
diff --git a/public/js/lib/bonfire/bonfireFramework_v0.1.1.js b/public/js/lib/bonfire/bonfireFramework_v0.1.2.js
similarity index 96%
rename from public/js/lib/bonfire/bonfireFramework_v0.1.1.js
rename to public/js/lib/bonfire/bonfireFramework_v0.1.2.js
index 03d531a5a0..4b2edebb0e 100644
--- a/public/js/lib/bonfire/bonfireFramework_v0.1.1.js
+++ b/public/js/lib/bonfire/bonfireFramework_v0.1.2.js
@@ -73,11 +73,10 @@ var editorValue;
var challengeSeed = challengeSeed || null;
var tests = tests || [];
-var challengeEntryPoint = challengeEntryPoint || null;
if (challengeSeed !== null) {
- editorValue = challengeSeed + '\n\n' + challengeEntryPoint;
+ editorValue = challengeSeed;
} else {
editorValue = nonChallengeValue;
}
@@ -121,9 +120,7 @@ function bonfireExecute() {
userJavaScript = removeComments(userJavaScript);
userJavaScript = scrapeTests(userJavaScript);
// simple fix in case the user forgets to invoke their function
- if (challengeEntryPoint && challengeSeed) {
- //userJavaScript = challengeEntryPoint + ' ' + userJavaScript;
- }
+
submit(userJavaScript, function(cls, message) {
if (cls) {
codeOutput.setValue(message.error);
diff --git a/public/js/lib/coursewares/coursewaresFramework_v0.1.1.js b/public/js/lib/coursewares/coursewaresHCJQFramework_v0.1.1.js
similarity index 100%
rename from public/js/lib/coursewares/coursewaresFramework_v0.1.1.js
rename to public/js/lib/coursewares/coursewaresHCJQFramework_v0.1.1.js
diff --git a/public/js/lib/coursewares/coursewaresJSFramework.js b/public/js/lib/coursewares/coursewaresJSFramework.js
new file mode 100644
index 0000000000..72a24eff4d
--- /dev/null
+++ b/public/js/lib/coursewares/coursewaresJSFramework.js
@@ -0,0 +1,245 @@
+var widgets = [];
+var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), {
+ lineNumbers: true,
+ mode: "javascript",
+ theme: 'monokai',
+ runnable: true,
+ lint: true,
+ matchBrackets: true,
+ autoCloseBrackets: true,
+ scrollbarStyle: 'null',
+ lineWrapping: true,
+ gutters: ["CodeMirror-lint-markers"],
+ onKeyEvent: doLinting
+});
+var editor = myCodeMirror;
+editor.setSize("100%", "auto");
+
+// Hijack tab key to enter two spaces intead
+editor.setOption("extraKeys", {
+ Tab: function(cm) {
+ var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
+ cm.replaceSelection(spaces);
+ },
+ "Ctrl-Enter": function() {
+ bonfireExecute();
+ return false;
+ }
+});
+
+
+
+var attempts = 0;
+if (attempts) {
+ attempts = 0;
+}
+
+// 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' +
+ '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 by using the keywords assert and expect */\n\n' +
+ 'function test() {\n' +
+ ' assert(2 !== 3, "2 is not equal to 3");\n' +
+ ' return [1,2,3].map(function(elem) {\n' +
+ ' return elem * elem;\n' +
+ ' });\n' +
+ '}\n' +
+ 'expect(test()).to.be.a("array");\n\n' +
+ 'assert.deepEqual(test(), [1,4,9]);\n\n' +
+ 'var foo = test();\n' +
+ 'foo.should.be.a("array");\n\n' +
+ 'test();\n';
+
+var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
+ lineNumbers: false,
+ mode: "text",
+ theme: 'monokai',
+ readOnly: 'nocursor',
+ lineWrapping: true
+});
+
+codeOutput.setValue('/**\n' +
+' * Your output will go here.\n' + ' * Console.log() -type statements\n' +
+' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' +
+' */');
+codeOutput.setSize("100%", "100%");
+var info = editor.getScrollInfo();
+var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
+if (info.top + info.clientHeight < after)
+ editor.scrollTo(null, after - info.clientHeight + 3);
+
+var editorValue;
+
+
+var challengeSeed = challengeSeed || null;
+var tests = tests || [];
+
+var allSeeds = '';
+(function() {
+ challengeSeed.forEach(function(elem) {
+ allSeeds += elem + '\n';
+ });
+})();
+
+editorValue = allSeeds;
+
+
+myCodeMirror.setValue(editorValue);
+
+function doLinting () {
+ editor.operation(function () {
+ for (var i = 0; i < widgets.length; ++i)
+ editor.removeLineWidget(widgets[i]);
+ widgets.length = 0;
+ JSHINT(editor.getValue());
+ for (var i = 0; i < JSHINT.errors.length; ++i) {
+ var err = JSHINT.errors[i];
+ if (!err) continue;
+ var msg = document.createElement("div");
+ var icon = msg.appendChild(document.createElement("span"));
+ icon.innerHTML = "!!";
+ icon.className = "lint-error-icon";
+ msg.appendChild(document.createTextNode(err.reason));
+ msg.className = "lint-error";
+ widgets.push(editor.addLineWidget(err.line - 1, msg, {
+ coverGutter: false,
+ noHScroll: true
+ }));
+ }
+ });
+};
+
+$('#submitButton').on('click', function () {
+ bonfireExecute();
+});
+
+function bonfireExecute() {
+ attempts++;
+ ga('send', 'event', 'Challenge', 'ran-code', challengeName);
+ userTests= null;
+ $('#codeOutput').empty();
+ var userJavaScript = myCodeMirror.getValue();
+ userJavaScript = removeComments(userJavaScript);
+ userJavaScript = scrapeTests(userJavaScript);
+ // simple fix in case the user forgets to invoke their function
+
+ submit(userJavaScript, function(cls, message) {
+ if (cls) {
+ codeOutput.setValue(message.error);
+ runTests('Error', null);
+ } else {
+ codeOutput.setValue(message.output);
+ message.input = removeLogs(message.input);
+ runTests(null, message);
+ }
+ });
+}
+
+
+var userTests;
+var testSalt = Math.random();
+
+
+var scrapeTests = function(userJavaScript) {
+
+ // insert tests from mongo
+ for (var i = 0; i < tests.length; i++) {
+ userJavaScript += '\n' + tests[i];
+ }
+
+ var counter = 0;
+ var regex = new RegExp(/(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)|(.*\.should\..*\;)/);
+ var match = regex.exec(userJavaScript);
+ while (match != null) {
+ var replacement = '//' + counter + testSalt;
+ userJavaScript = userJavaScript.substring(0, match.index) + replacement + userJavaScript.substring(match.index + match[0].length);
+
+ if (!userTests) {
+ userTests= [];
+ }
+ userTests.push({"text": match[0], "line": counter, "err": null});
+ counter++;
+ match = regex.exec(userJavaScript);
+ }
+
+ return userJavaScript;
+};
+
+function removeComments(userJavaScript) {
+ var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g);
+ return userJavaScript.replace(regex, '');
+}
+
+function removeLogs(userJavaScript) {
+ return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
+}
+
+var pushed = false;
+var createTestDisplay = function() {
+ if (pushed) {
+ userTests.pop();
+ }
+ for (var i = 0; i < userTests.length;i++) {
+ var test = userTests[i];
+ var testDoc = document.createElement("div");
+ if (test.err != null) {
+ $(testDoc)
+ .html("
" + test.text + "
" + test.err + "
")
+ .prependTo($('#testSuite'))
+ } else {
+ $(testDoc)
+ .html("")
+ .appendTo($('#testSuite'));
+ }
+ };
+};
+
+var expect = chai.expect;
+
+
+var reassembleTest = function(test, data) {
+ var lineNum = test.line;
+ var regexp = new RegExp("\/\/" + lineNum + testSalt);
+ return data.input.replace(regexp, test.text);
+};
+
+var runTests = function(err, data) {
+ var allTestsPassed = true;
+ pushed = false;
+ $('#testSuite').children().remove();
+ if (err && userTests.length > 0) {
+ userTests= [{text:"Program Execution Failure", err: "No user tests were run."}];
+ createTestDisplay();
+ } else if (userTests) {
+ userTests.push(false);
+ pushed = true;
+ userTests.forEach(function(test, ix, arr){
+ try {
+ if (test) {
+ var output = eval(reassembleTest(test, data));
+ }
+ } catch(error) {
+ allTestsPassed = false;
+ console.log(error);
+ arr[ix].err = error.name + ":" + error.message;
+ }
+ });
+
+ if (allTestsPassed) {
+ allTestsPassed = false;
+ showCompletion();
+ }
+
+ }
+};
+
+function showCompletion() {
+ var time = Math.floor(Date.now() / 1000) - started;
+ ga('send', 'event', 'Challenge', 'solved', challengeName + ', Time: ' + time +', Attempts: ' + attempts);
+ $('#complete-courseware-dialog').modal('show');
+ $('#complete-courseware-dialog').keydown(function(e) {
+ if (e.ctrlKey && e.keyCode == 13) {
+ $('.next-bonfire-button').click();
+ }
+ });
+}
\ No newline at end of file
diff --git a/public/js/main.js b/public/js/main.js
index 2d8d85b29e..f3af637d3f 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -66,6 +66,9 @@ $(document).ready(function() {
completedBonfire(didCompleteWith, bonfireSolution, thisBonfireHash);
});
+ $('#completed-courseware').on('click', function() {
+ $('#complete-courseware-dialog').modal('show');
+ });
$('#complete-bonfire-dialog').on('hidden.bs.modal', function() {
editor.focus();
diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json
index 3fd930d072..0991b56c7e 100644
--- a/seed_data/bonfires.json
+++ b/seed_data/bonfires.json
@@ -157,9 +157,7 @@
"Truncate a string (first argument) if it is longer than the given maximum string length (second argument). Return the truncated string with a '...' ending.",
"Note that the three dots at the end add to the string length."
],
-
- "challengeEntryPoint":"truncate('A-tisket a-tasket A green and yellow basket', 11);",
- "challengeSeed":"function truncate(str, num) {\n // Clear out that junk in your trunk\r\n return str;\r\n}",
+ "challengeSeed":"function truncate(str, num) {\n // Clear out that junk in your trunk\r\n return str;\r\n}\n\ntruncate('A-tisket a-tasket A green and yellow basket', 11);",
"tests": [
"expect(truncate('A-tisket a-tasket A green and yellow basket', 11)).to.eqls('A-tisket...');",
"assert(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length) === 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is = length');",
@@ -209,19 +207,6 @@
"assert.deepEqual(bouncer([false, null, 0]), [], 'should return empty array if all elements are falsey');"
]
},
- {
- "_id": "a8e512fbe388ac2f9198f0fa",
- "name": "Where art thou",
- "difficulty": "1.55",
- "description": [
- "Maketh a function that looks through a list (first argument) and returns an array of all objects that have equivalent property values (second argument)."
- ],
- "challengeSeed": "function where(collection, source) {\n var arr = [];\r\n // What's in a name?\r\n return arr;\r\n}\n\nwhere([{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }], { last: 'Capulet' });",
- "tests": [
- "assert.deepEqual(where([{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }], { last: 'Capulet' }), [{ first: 'Tybalt', last: 'Capulet' }], 'should return an array of objects');",
- "assert.deepEqual(where([{ 'a': 1 }, { 'a': 1 }, { 'a': 1, 'b': 2 }], { 'a': 1 }), [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }], 'should return with multiples');"
- ]
- },
{
"_id": "a39963a4c10bc8b4d4f06d7e",
"name": "Seek and Destroy",
@@ -231,13 +216,13 @@
],
"challengeSeed": "function destroyer(arr) {\n // Remove all the values\r\n return arr;\r\n}\n\ndestroyer([1, 2, 3, 1, 2, 3], 2, 3);",
"tests": [
- "assert.strictEqual(destroyer([1, 2, 3, 1, 2, 3], 2, 3), [1, 1], 'should remove correct values from an array');",
- "assert.strictEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');"
+ "assert.deepEqual(destroyer([1, 2, 3, 1, 2, 3], 2, 3), [1, 1], 'should remove correct values from an array');",
+ "assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');"
]
},
{
"_id": "a24c1a4622e3c05097f71d67",
- "name": "Where do I belong?",
+ "name": "Where do I belong",
"difficulty": "1.61",
"description": [
"Return the lowest index at which a value (second argument) should be inserted into a sorted array (first argument)."
@@ -479,8 +464,7 @@
"Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(), setLastName(), and setFullName().",
"These methods must be the only available means for interacting with the object."
],
- "challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};\n\nvar bob = new Person('Bob Ross');",
- "challengeEntryPoint": "var bob = new Person('Bob Ross');\nbob.getFullName();",
+ "challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};\n\nvar bob = new Person('Bob Ross');\n\nvar bob = new Person('Bob Ross');\nbob.getFullName();",
"tests": [
"expect(Object.keys(bob).length).to.eql(6);",
"expect(bob instanceof Person).to.be.true;",
diff --git a/seed_data/coursewares.json b/seed_data/coursewares.json
index f675d0e52c..90d97633cc 100644
--- a/seed_data/coursewares.json
+++ b/seed_data/coursewares.json
@@ -1,8 +1,51 @@
[
+ {
+ "_id" : "bbbbbbbbbbbbbbbbbbbbbbbb",
+ "name": "Learn how Free Code Camp Works",
+ "difficulty": 0.00,
+ "description": [
+ "Watch this 1-minute video, or simply read this summary:",
+ "Welcome to Free Code Camp. We're a community of busy people learning to code.",
+ "We built this community because learning to code is hard. But anyone who can stay motivated can learn to code. And the best way to stay motivated is to code with friends.",
+ "To maximize accessibility, all our challenges are self-paced, browser-based, and free.",
+ "All of us start with the same 100 hours of interactive coding challenges. These cover Computer Science and databases. They also cover in-demand JavaScript tools like jQuery, Node.js and MongoDB.",
+ "Once we have a basic understanding of web development, we'll spend another 900 hours putting that theory into practice. We'll build full stack solutions for nonprofits.",
+ "By the end of this process, we'll be good at coding. We'll have a portfolio of apps with happy users to prove it. We'll also have an alumni network of fellow coders and nonprofits ready to serve as references.",
+ "If you make it through Free Code Camp, you will be able to get a coding job. There are far more job openings out there than there are qualified coders to fill them.",
+ "Also, for every pure coding job, there are at least 5 additional jobs that require some coding skills. So even if you decide not to pursue coding as a career, you'll still walk away with a valuable job skill.",
+ "There are 3 keys to succeeding in our community: do the challenges, make friends, and find a routine.",
+ "Now it's time to join our chatroom. Click the \"I've completed this challenge\" button to move on to your next challenge."
+ ],
+ "tests": [
+ ""
+ ],
+ "challengeSeed": [
+ "114486344"
+ ],
+ "challengeType" : 2,
+ "completionMessage": ""
+ },
+ {
+ "_id": "bd7123c8c441eddfaeb5bdef",
+ "name": "Meet Booleans",
+ "difficulty": "0.001",
+ "description": [
+ "Return true"
+ ],
+ "tests": [
+ "expect(welcomeToBooleans()).to.be.a(\"boolean\");",
+ "expect(welcomeToBooleans()).to.be.true;"
+ ],
+ "challengeSeed": [
+ "function welcomeToBooleans() {\n // Good luck!\n return false;\n}\n\nwelcomeToBooleans();"
+ ],
+ "challengeType": 1,
+ "completionMessage": ""
+ },
{
"_id" : "bd7123c8c441eddfaeb5bdef",
"name": "Start our Challenges",
- "difficulty": "0.00",
+ "difficulty": "0.002",
"description": [
"Welcome to Free Code Camp's first challenge! Click on the button below for further instructions.",
"Awesome. Now you can read the rest of this challenge's instructions.",
diff --git a/views/bonfire/bonfire.jade b/views/bonfire/bonfire.jade
index 87399bac70..a5fdabf7ca 100644
--- a/views/bonfire/bonfire.jade
+++ b/views/bonfire/bonfire.jade
@@ -42,4 +42,4 @@ block content
br
ul#testSuite.list-group
br
- script(src='/js/lib/bonfire/bonfireFramework_v0.1.1.js')
\ No newline at end of file
+ script(src='/js/lib/bonfire/bonfireFramework_v0.1.2.js')
\ No newline at end of file
diff --git a/views/bonfire/show.jade b/views/bonfire/show.jade
index d92ec50300..f90390c61e 100644
--- a/views/bonfire/show.jade
+++ b/views/bonfire/show.jade
@@ -87,7 +87,6 @@ block content
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
- var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
var passedBonfireHash = !{JSON.stringify(bonfireHash)};
var challengeName = !{JSON.stringify(name)};
var started = Math.floor(Date.now() / 1000);
@@ -96,7 +95,7 @@ block content
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
- script(src='/js/lib/bonfire/bonfireFramework_v0.1.1.js')
+ script(src='/js/lib/bonfire/bonfireFramework_v0.1.2.js')
diff --git a/views/coursewares/show.jade b/views/coursewares/show.jade
index 17e3d9d905..3b4f1ab158 100644
--- a/views/coursewares/show.jade
+++ b/views/coursewares/show.jade
@@ -40,7 +40,10 @@ block content
span.ion-help-circled
| Less information
- if (cc)
- a.btn.btn-primary.btn-lg.btn-block#next-courseware-button Go to my next challenge (ctrl + enter)
+ a.btn.btn-primary.btn-lg.btn-block#next-courseware-button
+ | Go to my next challenge
+ br
+ | (ctrl + enter)
script.
var userLoggedIn = true;
@@ -70,7 +73,7 @@ block content
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
- script(src='/js/lib/coursewares/coursewaresFramework_v0.1.1.js')
+ script(src='/js/lib/coursewares/coursewaresHCJQFramework_v0.1.1.js')
.col-md-4.col-lg-3
.hidden-xs.hidden-sm
img.iphone-position(src="https://s3.amazonaws.com/freecodecamp/iphone6-frame.png")
diff --git a/views/coursewares/showJS.jade b/views/coursewares/showJS.jade
new file mode 100644
index 0000000000..30df71c717
--- /dev/null
+++ b/views/coursewares/showJS.jade
@@ -0,0 +1,83 @@
+extends ../layout-wide
+block content
+ script(src='/js/lib/codemirror/lib/codemirror.js')
+ script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
+ script(src='/js/lib/codemirror/addon/edit/matchbrackets.js')
+ script(src='/js/lib/codemirror/addon/lint/lint.js')
+ script(src='/js/lib/codemirror/addon/lint/javascript-lint.js')
+ script(src='//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js')
+ script(src='/js/lib/chai/chai.js')
+ link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
+ link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
+ link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
+ link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
+ script(src='/js/lib/codemirror/mode/javascript/javascript.js')
+ script(src='/js/lib/jailed/jailed.js')
+ script(src='/js/lib/bonfire/bonfireInit.js')
+ .row
+ .col-xs-12.col-sm-12.col-md-4.bonfire-top
+ #testCreatePanel
+ h1.text-center= name
+ .well
+ .row
+ .col-xs-12
+ .bonfire-instructions
+ p= brief
+ #brief-instructions
+ .text-center
+ button#more-info.btn.btn-info
+ span.ion-help-circled
+ | More information
+ #long-instructions.row.hide
+ .col-xs-12
+ for sentence in details
+ p!= sentence
+ .text-center
+ 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.hidden
+ br
+ script(type="text/javascript").
+ var tests = !{JSON.stringify(tests)};
+ var challengeSeed = !{JSON.stringify(challengeSeed)};
+ var passedBonfireHash = !{JSON.stringify(coursewareHash)};
+ var challengeName = !{JSON.stringify(name)};
+ var started = Math.floor(Date.now() / 1000);
+ .col-xs-12.col-sm-12.col-md-8
+ #mainEditorPanel
+ form.code
+ .form-group.codeMirrorView
+ textarea#codeEditor(autofocus=true)
+ script(src='/js/lib/coursewares/coursewaresJSFramework.js')
+ #complete-courseware-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.completion-icon.ion-checkmark-circled.text-primary
+ - if (cc)
+
+ a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Go to my next challenge (ctrl + enter)
+ - 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%20Bonfire:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/bonfires/#{dashedName}&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
diff --git a/views/coursewares/showVideo.jade b/views/coursewares/showVideo.jade
new file mode 100644
index 0000000000..e0e72b5fd2
--- /dev/null
+++ b/views/coursewares/showVideo.jade
@@ -0,0 +1,47 @@
+
+extends ../layout
+block content
+ .row
+ .col-sm-12.col-md-12.col-xs-12
+ .panel.panel-primary
+ .panel-heading.text-center
+ h1 #{name}
+ script.
+ var challengeName = !{JSON.stringify(name)};
+ var passedCoursewareHash = !{JSON.stringify(coursewareHash)};
+
+ .panel.panel-body
+ .embed-responsive.embed-responsive-16by9
+ iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2
+ h3 Steps:
+ h4
+ ol
+ for step in details
+ li!= step
+ .btn.btn-primary.btn-big.btn-block#completed-courseware I've completed this challenge
+ .ten-pixel-break
+ .btn.btn-success.btn-big.btn-block.all-challenges Show me all the challenges
+ #complete-courseware-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
+ .text-center
+ .animated.zoomInDown.delay-half
+ span.completion-icon.ion-checkmark-circled.text-primary
+ - if (cc)
+ a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf, aria-hidden='true') 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/challenges/#{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-challenges-dialog.modal(tabindex='-1')
+ .modal-dialog.animated.fadeInUp.fast-animation
+ .modal-content
+ .modal-header.challenge-list-header Challenges
+ a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
+ .modal-body