diff --git a/models/Bonfire.js b/models/Bonfire.js
index 8c0c4599ed..fdfebb3291 100644
--- a/models/Bonfire.js
+++ b/models/Bonfire.js
@@ -15,7 +15,7 @@ var bonfireSchema = new mongoose.Schema({
difficulty: String,
description: Array,
tests: Array,
- challengeSeed: String,
+ challengeSeed: Array,
MDNlinks: [String]
});
diff --git a/models/Courseware.js b/models/Courseware.js
index 64309a6540..d760acdfd3 100644
--- a/models/Courseware.js
+++ b/models/Courseware.js
@@ -15,7 +15,6 @@ var coursewareSchema = new mongoose.Schema({
description: Array,
tests: Array,
challengeSeed: Array,
- completionMessage: String, // Congratulations! You've finished our HTML and CSS track!
challengeType: Number // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
});
diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json
index 5ac7923de5..7b0f310987 100644
--- a/seed_data/bonfires.json
+++ b/seed_data/bonfires.json
@@ -14,7 +14,18 @@
"expect(meetBonfire()).to.be.a(\"boolean\");",
"expect(meetBonfire()).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\n return false;\n}\n\n\n\nmeetBonfire(\"You can do this!\");"
+ "challengeSeed": [
+ "function meetBonfire(argument) {",
+ " // Good luck!",
+ " console.log(\"you can read this function's argument in the developer tools\", argument);",
+ "",
+ " return false;",
+ "}",
+ "",
+ "",
+ "",
+ "meetBonfire(\"You can do this!\");"
+ ]
},
{
"_id": "a202eed8fc186c8434cb6d61",
@@ -31,8 +42,14 @@
"You may need to turn the string into an array before you can reverse it.",
"Your result must be a string."
],
- "challengeSeed": "function reverseString(str) {\n return str;\n}\n\nreverseString('hello');",
- "MDNlinks" : ["Global String Object", "String.split()", "Array.reverse()", "Array.join()"]
+ "challengeSeed": [
+ "function reverseString(str) {",
+ " return str;",
+ "}",
+ "",
+ "reverseString('hello');"
+ ],
+ "MDNlinks": ["Global String Object", "String.split()", "Array.reverse()", "Array.join()"]
},
{
"_id": "a302f7aae1aa3152a5b413bc",
@@ -50,8 +67,14 @@
"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;\n}\n\nfactorialize(5);",
- "MDNlinks" : ["Arithmetic Operators"]
+ "challengeSeed": [
+ "function factorialize(num) {",
+ " return num;",
+ "}",
+ "",
+ "factorialize(5);"
+ ],
+ "MDNlinks": ["Arithmetic Operators"]
},
{
"_id": "aaa48de84e1ecc7c742e1124",
@@ -72,8 +95,17 @@
"assert.deepEqual(palindrome(\"never odd or even\"), true);",
"assert.deepEqual(palindrome(\"nope\"), false);"
],
- "challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n\n\npalindrome(\"eye\");",
- "MDNlinks" : ["String.replace()", "String.toLowerCase()"]
+ "challengeSeed": [
+ "function palindrome(str) {",
+ " // Good luck!",
+ " return true;",
+ "}",
+ "",
+ "",
+ "",
+ "palindrome(\"eye\");"
+ ],
+ "MDNlinks": ["String.replace()", "String.toLowerCase()"]
},
{
"_id": "a26cbbe9ad8655a977e1ceb5",
@@ -83,7 +115,13 @@
"Return the length of the longest word in the provided sentence.",
"Your response should be a number."
],
- "challengeSeed": "function findLongestWord(str) {\n return str.length;\n}\n\nfindLongestWord('The quick brown fox jumped over the lazy dog');",
+ "challengeSeed": [
+ "function findLongestWord(str) {",
+ " return str.length;",
+ "}",
+ "",
+ "findLongestWord('The quick brown fox jumped over the lazy dog');"
+ ],
"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);",
@@ -91,7 +129,7 @@
"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);"
],
- "MDNlinks" : ["String.split()", "String.length"]
+ "MDNlinks": ["String.split()", "String.length"]
},
{
"_id": "ab6137d4e35944e21037b769",
@@ -101,14 +139,20 @@
"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'."
],
- "challengeSeed": "function titleCase(str) {\n return str;\n}\n\ntitleCase(\"I'm a little tea pot\");",
+ "challengeSeed": [
+ "function titleCase(str) {",
+ " return str;",
+ "}",
+ "",
+ "titleCase(\"I'm a little tea pot\");"
+ ],
"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\");"
],
- "MDNlinks" : ["String.charAt()"]
+ "MDNlinks": ["String.charAt()"]
},
{
"_id": "a789b3483989747d63b0e427",
@@ -119,13 +163,20 @@
"Remember, you can iterate through an array with a simple for loop, and access each member with array syntax arr[i] .",
"If you are writing your own Chai.js tests, be sure to use a deep equal statement instead of an equal statement when comparing arrays."
],
- "challengeSeed": "function largestOfFour(arr) {\n // You can do this!\n return arr;\n}\n\nlargestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);",
+ "challengeSeed": [
+ "function largestOfFour(arr) {",
+ " // You can do this!",
+ " return arr;",
+ "}",
+ "",
+ "largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);"
+ ],
"tests": [
"expect(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).to.be.a('array');",
"(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).should.eql([5,27,39,1001]);",
"assert(largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]).should.eql([9,35,97,1000000]));"
],
- "MDNlinks" : ["Comparison Operators"]
+ "MDNlinks": ["Comparison Operators"]
},
{
"_id": "acda2fb1324d9b0fa741e6b5",
@@ -135,13 +186,21 @@
"Check if a string (first argument) ends with the given target string (second argument)."
],
- "challengeSeed": "function end(str, target) {\n // \"Never give up and good luck will find you.\"\n // -- Falcor\n return str;\n}\n\nend('Bastian', 'n');",
+ "challengeSeed": [
+ "function end(str, target) {",
+ " // \"Never give up and good luck will find you.\"",
+ " // -- Falcor",
+ " return str;",
+ "}",
+ "",
+ "end('Bastian', 'n');"
+ ],
"tests": [
"assert.strictEqual(end('Bastian', 'n'), true, 'should equal true if target equals end of string');",
"assert.strictEqual(end('He has to give me a new name', 'name'), true, 'should equal true if target equals end of string');",
"assert.strictEqual(end('If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing', 'mountain'), false, 'should equal false if target does not equal end of string');"
],
- "MDNlinks" : ["String.substr()"]
+ "MDNlinks": ["String.substr()"]
},
{
"_id": "afcc8d540bea9ea2669306b6",
@@ -150,13 +209,20 @@
"description": [
"Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number."
],
- "challengeSeed": "function repeat(str, num) {\n // repeat after me\n return str;\n}\n\nrepeat('abc', 3);",
+ "challengeSeed": [
+ "function repeat(str, num) {",
+ " // repeat after me",
+ " return str;",
+ "}",
+ "",
+ "repeat('abc', 3);"
+ ],
"tests": [
"assert.strictEqual(repeat('*', 3), '***', 'should repeat a string n times');",
"assert.strictEqual(repeat('abc', 3), 'abcabcabc', 'should repeat a string n times');",
"assert.strictEqual(repeat('abc', -2), '', 'should return an empty string for negative numbers');"
],
- "MDNlinks" : ["Global String Object"]
+ "MDNlinks": ["Global String Object"]
},
{
"_id": "ac6993d51946422351508a41",
@@ -166,13 +232,20 @@
"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."
],
- "challengeSeed":"function truncate(str, num) {\n // Clear out that junk in your trunk\n return str;\n}\n\ntruncate('A-tisket a-tasket A green and yellow basket', 11);",
+ "challengeSeed": [
+ "function truncate(str, num) {",
+ " // Clear out that junk in your trunk",
+ " return str;",
+ "}",
+ "",
+ "truncate('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');",
"assert.strictEqual(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2), 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is < length');"
],
- "MDNlinks" : ["String.slice()"]
+ "MDNlinks": ["String.slice()"]
},
{
"_id": "a9bd25c716030ec90084d8a1",
@@ -181,13 +254,20 @@
"description": [
"Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a multidimensional array."
],
- "challengeSeed": "function chunk(arr, size) {\n // Break it up.\n return arr;\n}\n\nchunk(['a', 'b', 'c', 'd'], 2);",
+ "challengeSeed": [
+ "function chunk(arr, size) {",
+ " // Break it up.",
+ " return arr;",
+ "}",
+ "",
+ "chunk(['a', 'b', 'c', 'd'], 2);"
+ ],
"tests": [
"assert.deepEqual(chunk(['a', 'b', 'c', 'd'], 2), [['a', 'b'], ['c', 'd']], 'should return chunked arrays');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]], 'should return chunked arrays');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'should return the last chunk as remaining elements');"
],
- "MDNlinks" : ["Array.push()"]
+ "MDNlinks": ["Array.push()"]
},
{
"_id": "ab31c21b530c0dafa9e241ee",
@@ -196,13 +276,20 @@
"description": [
"Return the remaining elements of an array after chopping off n elements from the head."
],
- "challengeSeed": "function slasher(arr, howMany) {\n // it doesn't always pay to be first\n return arr;\n}\n\nslasher([1, 2, 3], 2);",
+ "challengeSeed": [
+ "function slasher(arr, howMany) {",
+ " // it doesn't always pay to be first",
+ " return arr;",
+ "}",
+ "",
+ "slasher([1, 2, 3], 2);"
+ ],
"tests": [
"assert.deepEqual(slasher([1, 2, 3], 2), [3], 'should drop the first two elements');",
"assert.deepEqual(slasher([1, 2, 3], 0), [1, 2, 3], 'should return all elements when n < 1');",
"assert.deepEqual(slasher([1, 2, 3], 9), [], 'should return an empty array when n >= array.length');"
],
- "MDNlinks" : ["Array.slice()", "Array.splice()"]
+ "MDNlinks": ["Array.slice()", "Array.splice()"]
},
{
"_id": "af2170cad53daa0770fabdea",
@@ -214,7 +301,13 @@
"The arguments ['hello', 'hey'] should return false because the string 'hello' does not contain a 'y'.",
"Another example, ['Alien', 'line'], should return true because all of the letters in 'line' are present in 'Alien'."
],
- "challengeSeed": "function mutation(arr) {\n return arr;\n}\n\nmutation(['hello', 'hey']);",
+ "challengeSeed": [
+ "function mutation(arr) {",
+ " return arr;",
+ "}",
+ "",
+ "mutation(['hello', 'hey']);"
+ ],
"tests": [
"expect(mutation(['hello', 'hey'])).to.be.false;",
"expect(mutation(['hello', 'Hello'])).to.be.true;",
@@ -222,7 +315,7 @@
"expect(mutation(['Mary', 'Army'])).to.be.true;",
"expect(mutation(['Alien', 'line'])).to.be.true;"
],
- "MDNlinks" : ["Array.sort()"]
+ "MDNlinks": ["Array.sort()"]
},
{
"_id": "adf08ec01beb4f99fc7a68f2",
@@ -232,13 +325,20 @@
"Remove all falsey values from an array.",
"Falsey values in javascript are false, null, 0, \"\", undefined, and NaN."
],
- "challengeSeed": "function bouncer(arr) {\n // Don't show a false ID to this bouncer.\n return arr;\n}\n\nbouncer([7, 'ate', '', false, 9]);",
+ "challengeSeed": [
+ "function bouncer(arr) {",
+ " // Don't show a false ID to this bouncer.",
+ " return arr;",
+ "}",
+ "",
+ "bouncer([7, 'ate', '', false, 9]);"
+ ],
"tests": [
"assert.deepEqual(bouncer([7, 'ate', '', false, 9]), [7, 'ate', 9], 'should remove falsey values');",
"assert.deepEqual(bouncer(['a', 'b', 'c']), ['a', 'b', 'c'], 'should return full array if no falsey elements');",
"assert.deepEqual(bouncer([false, null, 0]), [], 'should return empty array if all elements are falsey');"
],
- "MDNlinks" : ["Boolean Objects", "Array.filter()"]
+ "MDNlinks": ["Boolean Objects", "Array.filter()"]
},
{
"_id":"a8e512fbe388ac2f9198f0fa",
@@ -247,12 +347,20 @@
"description":[
"Make 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 = [];\n // What's in a name?\n return arr;\n}\n\nwhere([{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }], { last: 'Capulet' });",
+ "challengeSeed": [
+ "function where(collection, source) {",
+ " var arr = [];",
+ " // What's in a name?",
+ " return arr;",
+ "}",
+ "",
+ "where([{ 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, 'b': 2 }], 'should return with multiples');"
],
- "MDNlinks" : ["Global Object", "Object.hasOwnProperty()", "Object.keys()"]
+ "MDNlinks": ["Global Object", "Object.hasOwnProperty()", "Object.keys()"]
},
{
"_id":"a39963a4c10bc8b4d4f06d7e",
@@ -261,12 +369,19 @@
"description":[
"You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments."
],
- "challengeSeed": "function destroyer(arr) {\n // Remove all the values\n return arr;\n}\n\ndestroyer([1, 2, 3, 1, 2, 3], 2, 3);",
+ "challengeSeed": [
+ "function destroyer(arr) {",
+ " // Remove all the values",
+ " return arr;",
+ "}",
+ "",
+ "destroyer([1, 2, 3, 1, 2, 3], 2, 3);"
+ ],
"tests": [
"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');"
],
- "MDNlinks" : ["Arguments object","Array.filter()"]
+ "MDNlinks": ["Arguments object","Array.filter()"]
},
{
"_id": "a24c1a4622e3c05097f71d67",
@@ -276,7 +391,14 @@
"Return the lowest index at which a value (second argument) should be inserted into a sorted array (first argument).",
"For example, where([1,2,3,4], 1.5) should return 1 because it is greater than 1 (0th index), but less than 2 (1st index)."
],
- "challengeSeed": "function where(arr, num) {\n // Find my place in this sorted array.\n return num;\n}\n\nwhere([40, 60], 50);",
+ "challengeSeed": [
+ "function where(arr, num) {",
+ " // Find my place in this sorted array.",
+ " return num;",
+ "}",
+ "",
+ "where([40, 60], 50);"
+ ],
"tests": [
"expect(where([10, 20, 30, 40, 50], 35)).to.equal(3);",
"expect(where([10, 20, 30, 40, 50], 30)).to.equal(2);"
@@ -290,7 +412,13 @@
"We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
"The lowest number will not always come first."
],
- "challengeSeed": "function sumAll(arr) {\n return(1);\n}\n\nsumAll([1, 4]);",
+ "challengeSeed": [
+ "function sumAll(arr) {",
+ " return(1);",
+ "}",
+ "",
+ "sumAll([1, 4]);"
+ ],
"tests": [
"expect(sumAll([1, 4])).to.be.a('Number');",
"expect(sumAll([1, 4])).to.equal(10);",
@@ -298,7 +426,7 @@
"expect(sumAll([5, 10])).to.equal(45);",
"expect(sumAll([10, 5])).to.equal(45);"
],
- "MDNlinks" : ["Math.max()", "Math.min()", "Array.reduce()"]
+ "MDNlinks": ["Math.max()", "Math.min()", "Array.reduce()"]
},
{
"_id": "a5de63ebea8dbee56860f4f2",
@@ -307,7 +435,15 @@
"description": [
"Compare two arrays and return a new array with any items not found in both of the original arrays."
],
- "challengeSeed": "function diff(arr1, arr2) {\n var newArr = [];\n // Same, same; but different.\n return newArr;\n}\n\ndiff([1, 2, 3, 5], [1, 2, 3, 4, 5]);",
+ "challengeSeed": [
+ "function diff(arr1, arr2) {",
+ " var newArr = [];",
+ " // Same, same; but different.",
+ " return newArr;",
+ "}",
+ "",
+ "diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);"
+ ],
"tests": [
"expect(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])).to.be.a('array');",
"assert.deepEqual(diff(['diorite', 'andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['pink wool'], 'arrays with only one difference');",
@@ -333,8 +469,14 @@
"Convert the number be a roman numeral.",
"All roman numerals answers should be provided in upper-case."
],
- "challengeSeed": "function convert(num) {\n return num;\n}\n\nconvert(36);",
- "MDNlinks" : ["Array.splice()", "Array.indexOf()", "Array.join()"]
+ "challengeSeed": [
+ "function convert(num) {",
+ " return num;",
+ "}",
+ "",
+ "convert(36);"
+ ],
+ "MDNlinks": ["Array.splice()", "Array.indexOf()", "Array.join()"]
},
{
"_id": "a0b5010f579e69b815e7c5d6",
@@ -354,8 +496,14 @@
"Third argument is what you will be replacing the second argument with (after).",
"NOTE: Preserve the case of the original word when you are replacing it. For example if you mean to replace the word 'Book' with the word 'dog', it should be replaced as 'Dog'"
],
- "challengeSeed": "function replace(str, before, after) {\n return str;\n}\n\nreplace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");",
- "MDNlinks" : ["Array.splice()", "String.replace()", "Array.join()"]
+ "challengeSeed": [
+ "function replace(str, before, after) {",
+ " return str;",
+ "}",
+ "",
+ "replace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");"
+ ],
+ "MDNlinks": ["Array.splice()", "String.replace()", "Array.join()"]
},
{
"_id": "aa7697ea2477d1316795783b",
@@ -373,8 +521,14 @@
"Pig Latin takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
"If a word begins with a vowel you just add \"way\" to the end."
],
- "challengeSeed": "function translate(str) {\n return str;\n}\n\ntranslate(\"consonant\");",
- "MDNlinks" : ["Array.indexOf()", "Array.push()", "Array.join()", "String.substr()", "String.split()"]
+ "challengeSeed": [
+ "function translate(str) {",
+ " return str;",
+ "}",
+ "",
+ "translate(\"consonant\");"
+ ],
+ "MDNlinks": ["Array.indexOf()", "Array.push()", "Array.join()", "String.substr()", "String.split()"]
},
{
"_id": "afd15382cdfb22c9efe8b7de",
@@ -390,8 +544,14 @@
"Base pairs are a pair of AT and CG. Match the missing element to the provided character.",
"Return the provided character as the first element in each array."
],
- "challengeSeed": "function pair(str) {\n return str;\n}\n\npair(\"GCG\");",
- "MDNlinks" : ["Array.push()", "String.split()"]
+ "challengeSeed": [
+ "function pair(str) {",
+ " return str;",
+ "}",
+ "",
+ "pair(\"GCG\");"
+ ],
+ "MDNlinks": ["Array.push()", "String.split()"]
},
{
"_id": "af7588ade1100bde429baf20",
@@ -401,14 +561,20 @@
"Find the missing letter in the passed letter range and return it.",
"If all letters are present in the range, return undefined."
],
- "challengeSeed": "function fearNotLetter(str) {\n return str;\n}\n\nfearNotLetter('abce');",
+ "challengeSeed": [
+ "function fearNotLetter(str) {",
+ " return str;",
+ "}",
+ "",
+ "fearNotLetter('abce');"
+ ],
"tests": [
"expect(fearNotLetter('abce')).to.equal('d');",
"expect(fearNotLetter('bcd')).to.be.undefined;",
"expect(fearNotLetter('abcdefghjklmno')).to.equal('i');",
"expect(fearNotLetter('yz')).to.be.undefined;"
],
- "MDNlinks" : ["String.charCodeAt()"]
+ "MDNlinks": ["String.charCodeAt()"]
},
{
"_id": "a77dbc43c33f39daa4429b4f",
@@ -418,7 +584,14 @@
"Check if a value is classified as a boolean primitive. Return true or false.",
"Boolean primitives are true and false."
],
- "challengeSeed": "function boo(bool) {\n // What is the new fad diet for ghost developers? The Boolean.\n return bool;\n}\n\nboo(null);",
+ "challengeSeed": [
+ "function boo(bool) {",
+ " // What is the new fad diet for ghost developers? The Boolean.",
+ " return bool;",
+ "}",
+ "",
+ "boo(null);"
+ ],
"tests": [
"assert.strictEqual(boo(true), true);",
"assert.strictEqual(boo(false), true);",
@@ -429,7 +602,7 @@
"assert.strictEqual(boo(NaN), false);",
"assert.strictEqual(boo('a'), false);"
],
- "MDNlinks" : ["Boolean Objects"]
+ "MDNlinks": ["Boolean Objects"]
},
{
"_id": "a105e963526e7de52b219be9",
@@ -441,7 +614,13 @@
"The unique numbers should be sorted by their original order, but the final array should not be sorted in numerical order.",
"Check the assertion tests for examples."
],
- "challengeSeed": "function unite(arr1, arr2, arr3) {\n return arr1;\n}\n\nunite([1, 2, 3], [5, 2, 1, 4], [2, 1]);",
+ "challengeSeed": [
+ "function unite(arr1, arr2, arr3) {",
+ " return arr1;",
+ "}",
+ "",
+ "unite([1, 2, 3], [5, 2, 1, 4], [2, 1]);"
+ ],
"tests": [
"assert.deepEqual(unite([1, 3, 2], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4], 'should return the union of the given arrays');",
"assert.deepEqual(unite([1, 3, 2], [1, [5]], [2, [4]]), [1, 3, 2, [5], [4]], 'should not flatten nested arrays');"
@@ -454,12 +633,19 @@
"description": [
"Convert the characters \"&\", \"<\", \">\", '\"', and \"'\", in a string to their corresponding HTML entities."
],
- "challengeSeed": "function convert(str) {\n // :)\n return str;\n}\n\nconvert('Dolce & Gabbana');",
+ "challengeSeed": [
+ "function convert(str) {",
+ " // :)",
+ " return str;",
+ "}",
+ "",
+ "convert('Dolce & Gabbana');"
+ ],
"tests": [
"assert.strictEqual(convert('Dolce & Gabbana'), 'Dolce & Gabbana', 'should escape characters');",
"assert.strictEqual(convert('abc'), 'abc', 'should handle strings with nothing to escape');"
],
- "MDNlinks" : ["RegExp"]
+ "MDNlinks": ["RegExp"]
},
{
"_id": "a103376db3ba46b2d50db289",
@@ -468,14 +654,22 @@
"description": [
"Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes."
],
- "challengeSeed": "function spinalCase(str) {\n // \"It's such a fine line between stupid, and clever.\"\n // --David St. Hubbins\n return str;\n}\n\nspinalCase('This Is Spinal Tap');",
+ "challengeSeed": [
+ "function spinalCase(str) {",
+ " // \"It's such a fine line between stupid, and clever.\"",
+ " // --David St. Hubbins",
+ " return str;",
+ "}",
+ "",
+ "spinalCase('This Is Spinal Tap');"
+ ],
"tests": [
"assert.strictEqual(spinalCase('This Is Spinal Tap'), 'this-is-spinal-tap', 'should return spinal case from string with spaces');",
"assert.strictEqual(spinalCase('thisIsSpinalTap'), 'this-is-spinal-tap', 'should return spinal case from string with camel case');",
"assert.strictEqual(spinalCase('The_Andy_Griffith_Show'), 'the-andy-griffith-show', 'should return spinal case from string with snake case');",
"assert.strictEqual(spinalCase('Teletubbies say Eh-oh'), 'teletubbies-say-eh-oh', 'should return spinal case from string with spaces and hyphens');"
],
- "MDNlinks" : ["RegExp", "String.replace()"]
+ "MDNlinks": ["RegExp", "String.replace()"]
},
{
"_id": "a5229172f011153519423690",
@@ -486,7 +680,13 @@
"The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers.",
"As an example, passing 4 to the function should return 5 because all the odd Fibonacci numbers under 4 are 1, 1, and 3."
],
- "challengeSeed": "function sumFibs(num) {\n return num;\n}\n\nsumFibs(4);",
+ "challengeSeed": [
+ "function sumFibs(num) {",
+ " return num;",
+ "}",
+ "",
+ "sumFibs(4);"
+ ],
"tests": [
"expect(sumFibs(1)).to.be.a('number');",
"expect(sumFibs(1000)).to.equal(1785);",
@@ -495,7 +695,7 @@
"expect(sumFibs(75024)).to.equal(60696);",
"expect(sumFibs(75025)).to.equal(135721);"
],
- "MDNlinks" : ["Remainder"]
+ "MDNlinks": ["Remainder"]
},
{
"_id": "a3bfc1673c0526e06d3ac698",
@@ -506,7 +706,13 @@
"A prime number is defined as having only two divisors, 1 and itself. For example, 2 is a prime number because it's only divisible by 1 and 2. 1 isn't a prime number, because it's only divisible by itself.",
"The provided number may not be a prime."
],
- "challengeSeed": "function sumPrimes(num) {\n return num;\n}\n\nsumPrimes(10);",
+ "challengeSeed": [
+ "function sumPrimes(num) {",
+ " return num;",
+ "}",
+ "",
+ "sumPrimes(10);"
+ ],
"tests": [
"expect(sumPrimes(10)).to.be.a('number');",
"expect(sumPrimes(10)).to.equal(17);",
@@ -521,7 +727,14 @@
"Find the smallest number that is evenly divisible by all numbers in the provided range.",
"The range will be an array of two numbers that will not necessarily be in numerical order."
],
- "challengeSeed": "function smallestCommons(arr) {\n return arr;\n}\n\n\nsmallestCommons([1,5]);",
+ "challengeSeed": [
+ "function smallestCommons(arr) {",
+ " return arr;",
+ "}",
+ "",
+ "",
+ "smallestCommons([1,5]);"
+ ],
"tests": [
"expect(smallestCommons([1,5])).to.be.a('number');",
"expect(smallestCommons([1,5])).to.equal(60);",
@@ -536,12 +749,19 @@
"description": [
"Create a function that looks through an array (first argument) and returns the first element in the array that passes a truth test (second argument)."
],
- "challengeSeed": "function find(arr, func) {\n var num = 0;\n return num;\n}\n\nfind([1, 2, 3, 4], function(num){ return num % 2 === 0; });",
+ "challengeSeed": [
+ "function find(arr, func) {",
+ " var num = 0;",
+ " return num;",
+ "}",
+ "",
+ "find([1, 2, 3, 4], function(num){ return num % 2 === 0; });"
+ ],
"tests": [
"assert.strictEqual(find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; }), 8, 'should return first found value');",
"assert.strictEqual(find([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'should return undefined if not found');"
],
- "MDNlinks" : ["Array.some()"]
+ "MDNlinks": ["Array.some()"]
},
{
"_id": "a5deed1811a43193f9f1c841",
@@ -550,13 +770,20 @@
"description": [
"Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true."
],
- "challengeSeed": "function drop(arr, func) {\n // Drop them elements.\n return arr;\n}\n\ndrop([1, 2, 3], function(n) {return n < 3; });",
+ "challengeSeed": [
+ "function drop(arr, func) {",
+ " // Drop them elements.",
+ " return arr;",
+ "}",
+ "",
+ "drop([1, 2, 3], function(n) {return n < 3; });"
+ ],
"tests": [
"expect(drop([1, 2, 3, 4], function(n) {return n >= 3; })).to.eqls([3, 4]);",
"expect(drop([1, 2, 3], function(n) {return n > 0; })).to.eqls([1, 2, 3]);",
"expect(drop([1, 2, 3, 4], function(n) {return n > 5; })).to.eqls([]);"
],
- "MDNlinks" : ["Arguments object", "Array.shift()"]
+ "MDNlinks": ["Arguments object", "Array.shift()"]
},
{
"_id": "ab306dbdcc907c7ddfc30830",
@@ -565,13 +792,20 @@
"description": [
"Flatten a nested array. You must account for varying levels of nesting."
],
- "challengeSeed": "function steamroller(arr) {\n // I'm a steamroller, baby\n return arr;\n}\n\nsteamroller([1, [2], [3, [[4]]]]);",
+ "challengeSeed": [
+ "function steamroller(arr) {",
+ " // I'm a steamroller, baby",
+ " return arr;",
+ "}",
+ "",
+ "steamroller([1, [2], [3, [[4]]]]);"
+ ],
"tests": [
"assert.deepEqual(steamroller([[['a']], [['b']]]), ['a', 'b'], 'should flatten nested arrays');",
"assert.deepEqual(steamroller([1, [2], [3, [[4]]]]), [1, 2, 3, 4], 'should flatten nested arrays');",
"assert.deepEqual(steamroller([1, [], [3, [[4]]]]), [1, 3, 4], 'should work with empty arrays');"
],
- "MDNlinks" : ["Array.isArray()"]
+ "MDNlinks": ["Array.isArray()"]
},
{
"_id": "a8d97bd4c764e91f9d2bda01",
@@ -581,12 +815,19 @@
"Return an English translated sentence of the passed binary string.",
"The binary string will be space separated."
],
- "challengeSeed": "function binaryAgent(str) {\n return str;\n}\n\nbinaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111');",
+ "challengeSeed": [
+ "function binaryAgent(str) {",
+ " return str;",
+ "}",
+ "",
+ "binaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111');"
+ ],
"tests": [
"expect(binaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111')).to.equal(\"Aren't bonfires fun!?\");",
"expect(binaryAgent('01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001')).to.equal(\"I love FreeCodeCamp!\");"
],
- "MDNlinks" : ["String.charCodeAt()", "String.fromCharCode()"]
+ "MDNlinks": ["String.charCodeAt()", "String.fromCharCode()"
+ ]
},
{
"_id" : "a3f503de51cfab748ff001aa",
@@ -597,7 +838,13 @@
"For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7.",
"pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!"
],
- "challengeSeed": "function pairwise(arr, arg) {\n return arg;\n}\n\npairwise([1,4,2,3,0,5], 7);",
+ "challengeSeed": [
+ "function pairwise(arr, arg) {",
+ " return arg;",
+ "}",
+ "",
+ "pairwise([1,4,2,3,0,5], 7);"
+ ],
"tests": [
"expect(pairwise([1, 4, 2, 3, 0, 5], 7)).to.equal(11);",
"expect(pairwise([1, 3, 2, 4], 4)).to.equal(1);",
@@ -615,12 +862,19 @@
"For this, check to see if the property defined in the second argument is present on every element of the collection.",
"Remember, you can access object properties through either dot notation or [] notation."
],
- "challengeSeed": "function every(collection, pre) {\n // Does everyone have one of these?\n return pre;\n}\n\nevery([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex');",
+ "challengeSeed": [
+ "function every(collection, pre) {",
+ " // Does everyone have one of these?",
+ " return pre;",
+ "}",
+ "",
+ "every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex');"
+ ],
"tests": [
"assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex'), true, 'should return true if predicate returns truthy for all elements in the collection');",
"assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], {'sex': 'female'}), false, 'should return false if predicate returns falsey for any element in the collection');"
],
- "MDNlinks" : ["Object.hasOwnProperty()", "Object.getOwnPropertyNames()"]
+ "MDNlinks": ["Object.hasOwnProperty()", "Object.getOwnPropertyNames()"]
},
{
"_id": "a97fd23d9b809dac9921074f",
@@ -631,7 +885,13 @@
"For example, add(2, 3) should return 5, and add(2) should return a function that is waiting for an argument so that var sum2And = add(2); return sum2And(3); // 5
",
"If either argument isn't a valid number, return undefined."
],
- "challengeSeed": "function add() {\n return false;\n}\n\nadd(2,3);",
+ "challengeSeed": [
+ "function add() {",
+ " return false;",
+ "}",
+ "",
+ "add(2,3);"
+ ],
"tests": [
"expect(add(2, 3)).to.equal(5);",
"expect(add(2)(3)).to.equal(5);",
@@ -651,7 +911,14 @@
"All functions that take an argument have an arity of 1, and the argument will be a string.",
"These methods must be the only available means for interacting with the object."
],
- "challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\n};\n\nvar bob = new Person('Bob Ross');\nbob.getFullName();",
+ "challengeSeed": [
+ "var Person = function(firstAndLast) {",
+ " return firstAndLast;",
+ "};",
+ "",
+ "var bob = new Person('Bob Ross');",
+ "bob.getFullName();"
+ ],
"tests": [
"expect(Object.keys(bob).length).to.eql(6);",
"expect(bob instanceof Person).to.be.true;",
@@ -668,7 +935,7 @@
"expect(bob.getFullName()).to.eql('George Carlin');",
"bob.setFullName('Bob Ross');"
],
- "MDNlinks" : ["Closures", "Details of the Object Model"]
+ "MDNlinks": ["Closures", "Details of the Object Model"]
},
{
"_id": "af4afb223120f7348cdfc9fd",
@@ -681,12 +948,20 @@
"The values should be rounded to the nearest whole number. The body being orbited is Earth.",
"The radius of the earth is 6367.4447 kilometers, and the GM value of earth is 398600.4418"
],
- "challengeSeed": "function orbitalPeriod(arr) {\n var GM = 398600.4418;\n var earthRadius = 6367.4447;\n return arr;\n}\n\norbitalPeriod([{name : \"sputkin\", avgAlt : 35873.5553}]);",
+ "challengeSeed": [
+ "function orbitalPeriod(arr) {",
+ " var GM = 398600.4418;",
+ " var earthRadius = 6367.4447;",
+ " return arr;",
+ "}",
+ "",
+ "orbitalPeriod([{name : \"sputkin\", avgAlt : 35873.5553}]);"
+ ],
"tests": [
"expect(orbitalPeriod([{name : \"sputkin\", avgAlt : 35873.5553}])).to.eqls([{name: \"sputkin\", orbitalPeriod: 86400}]);",
"expect(orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}])).to.eqls([{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}]);"
],
- "MDNlinks" : ["Math.pow()"]
+ "MDNlinks": ["Math.pow()"]
},
{
"_id": "aff0395860f5d3034dc0bfc9",
@@ -722,7 +997,16 @@
"assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
],
- "challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n\n\ntelephoneCheck(\"555-555-5555\");"
+ "challengeSeed": [
+ "function telephoneCheck(str) {",
+ " // Good luck!",
+ " return true;",
+ "}",
+ "",
+ "",
+ "",
+ "telephoneCheck(\"555-555-5555\");"
+ ]
},
{
"_id": "a3f503de51cf954ede28891d",
@@ -732,7 +1016,13 @@
"Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.",
"The mathematical term symmetric difference refers to the elements in two sets that are in either the first or second set, but not in both."
],
- "challengeSeed": "function sym(args) {\n return arguments;\n}\n\nsym([1, 2, 3], [5, 2, 1, 4]);",
+ "challengeSeed": [
+ "function sym(args) {",
+ " return arguments;",
+ "}",
+ "",
+ "sym([1, 2, 3], [5, 2, 1, 4]);"
+ ],
"tests": [
"expect(sym([1, 2, 3], [5, 2, 1, 4])).to.eqls([3, 5, 4])",
"assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'should return the symmetric difference of the given arrays');",
@@ -747,7 +1037,26 @@
"description": [
"Design a cash register drawer function that accepts purchase price as the first argument, payment as the second argument, and cash-in-drawer (cid) as the third argument.", "cid is a 2d array listing available currency.", "Return the string \"Insufficient Funds\" if cash-in-drawer is less than the change due. Return the string \"Closed\" if cash-in-drawer is equal to the change due.", "Otherwise, return change in coin and bills, sorted in highest to lowest order."
],
- "challengeSeed": "function drawer(price, cash, cid) {\n var change;\n // Here is your change, ma'am.\n return change;\n}\n\n// Example cash-in-drawer array:\n// [['PENNY', 1.01],\n// ['NICKEL', 2.05],\n// ['DIME', 3.10],\n// ['QUARTER', 4.25],\n// ['ONE', 90.00],\n// ['FIVE', 55.00],\n// ['TEN', 20.00],\n// ['TWENTY', 60.00],\n// ['ONE HUNDRED', 100.00]]\n\ndrawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);",
+ "challengeSeed": [
+ "function drawer(price, cash, cid) {",
+ " var change;",
+ " // Here is your change, ma'am.",
+ " return change;",
+ "}",
+ "",
+ "// Example cash-in-drawer array:",
+ "// [['PENNY', 1.01],",
+ "// ['NICKEL', 2.05],",
+ "// ['DIME', 3.10],",
+ "// ['QUARTER', 4.25],",
+ "// ['ONE', 90.00],",
+ "// ['FIVE', 55.00],",
+ "// ['TEN', 20.00],",
+ "// ['TWENTY', 60.00],",
+ "// ['ONE HUNDRED', 100.00]]",
+ "",
+ "drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);"
+ ],
"tests": [
"expect(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]])).to.be.a('array');",
"expect(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
@@ -765,7 +1074,29 @@
"description": [
"Compare and update inventory stored in a 2d array against a second 2d array of a fresh delivery. Update current inventory item quantity, and if an item cannot be found, add the new item and quantity into the inventory array in alphabetical order."
],
- "challengeSeed": "function inventory(arr1, arr2) {\n // All inventory must be accounted for or you're fired!\n return arr1;\n}\n\n// Example inventory lists\nvar curInv = [\n [21, 'Bowling Ball'],\n [2, 'Dirty Sock'],\n [1, 'Hair Pin'],\n [5, 'Microphone']\n];\n\nvar newInv = [\n [2, 'Hair Pin'],\n [3, 'Half-Eaten Apple'],\n [67, 'Bowling Ball'],\n [7, 'Toothpaste']\n];\n\ninventory(curInv, newInv);",
+ "challengeSeed": [
+ "function inventory(arr1, arr2) {",
+ " // All inventory must be accounted for or you're fired!",
+ " return arr1;",
+ "}",
+ "",
+ "// Example inventory lists",
+ "var curInv = [",
+ " [21, 'Bowling Ball'],",
+ " [2, 'Dirty Sock'],",
+ " [1, 'Hair Pin'],",
+ " [5, 'Microphone']",
+ "];",
+ "",
+ "var newInv = [",
+ " [2, 'Hair Pin'],",
+ " [3, 'Half-Eaten Apple'],",
+ " [67, 'Bowling Ball'],",
+ " [7, 'Toothpaste']",
+ "];",
+ "",
+ "inventory(curInv, newInv);"
+ ],
"tests": [
"expect(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']])).to.be.a('array');",
"assert.equal(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]).length, 6);",
@@ -783,7 +1114,13 @@
"Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
"For example, 'aab' should return 2 because it has 6 total permutations, but only 2 of them don't have the same letter (in this case 'a') repeating."
],
- "challengeSeed": "function permAlone(str) {\n return str;\n}\n\npermAlone('aab');",
+ "challengeSeed": [
+ "function permAlone(str) {",
+ " return str;",
+ "}",
+ "",
+ "permAlone('aab');"
+ ],
"tests": [
"expect(permAlone('aab')).to.be.a.number;",
"expect(permAlone('aab')).to.equal(2);",
@@ -805,7 +1142,13 @@
"Secondly, if the starting year is the current year, and the ending year can be inferred by the reader, the year should be omitted.",
"Input date is formatted as YYYY-MM-DD"
],
- "challengeSeed": "function friendly(str) {\n return str;\n}\n\nfriendly(['2015-07-01', '2015-07-04']);",
+ "challengeSeed": [
+ "function friendly(str) {",
+ " return str;",
+ "}",
+ "",
+ "friendly(['2015-07-01', '2015-07-04']);"
+ ],
"tests": [
"assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
"assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'one month apart can be inferred it is the next year');",
@@ -814,6 +1157,6 @@
"assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
"assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
],
- "MDNlinks" : ["String.split()", "String.substr()", "parseInt()"]
+ "MDNlinks": ["String.split()", "String.substr()", "parseInt()"]
}
]
diff --git a/seed_data/challenges/basejumps.json b/seed_data/challenges/basejumps.json
new file mode 100644
index 0000000000..95ec8505f8
--- /dev/null
+++ b/seed_data/challenges/basejumps.json
@@ -0,0 +1,176 @@
+{
+ "name": "Basejumps",
+ "order" : 0.010,
+ "challenges": [
+ {
+ "_id": "bd7158d8c443eddfaeb5bcef",
+ "name": "Get Set for Basejumps",
+ "difficulty": 2.00,
+ "challengeSeed": "126433451",
+ "description": [
+ "Objective: Get the MEAN stack running on Cloud 9, push your code to GitHub, and deploy it to Heroku.",
+ "We'll build our Basejumps on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
+ "If you don't already have Cloud 9 account, create one now at http://c9.io.",
+ "Now let's get your development environment ready for a new Angular-Fullstack application provided by Yeoman.",
+ "Open up http://c9.io and sign in to your account.",
+ "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
+ "Give your workspace a name.",
+ "Choose Node.js in the selection area below the name field.",
+ "Click the Create button.",
+ "Wait for the workspace to finish processing and select it on the left sidebar, below the Create New Workspace button.",
+ "Click the \"Start Editing\" button.",
+ "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
+ "Never run this command on your local machine. But in your Cloud 9 terminal window, run: rm -rf * && echo \"export NODE_PATH=$NODE_PATH:/home/ubuntu/.nvm/v0.10.35/lib/node_modules\" >> ~/.bashrc && source ~/.bashrc && npm install -g yo grunt grunt-cli generator-angular-fullstack && yo angular-fullstack
",
+ "Yeoman will prompt you to answer some questions. Answer them like this:",
+ "What would you like to write scripts with? JavaScript",
+ "What would you like to write markup with? HTML",
+ "What would you like to write stylesheets with? CSS",
+ "What Angular router would you like to use? ngRoute",
+ "Would you like to include Bootstrap? Yes",
+ "Would you like to include UI Bootstrap? Yes",
+ "Would you like to use MongoDB with Mongoose for data modeling? Yes",
+ "Would you scaffold out an authentication boilerplate? Yes",
+ "Would you like to include additional oAuth strategies? Twitter",
+ "Would you like to use socket.io? No",
+ "May bower anonymously report usage statistics to improve the tool over time? (Y/n) Y",
+ "You may get an error similar to ERR! EEXIST, open ‘/home/ubuntu/.npm
. This is caused when Cloud9 runs out of memory and kills an install. If you get this, simply re-run this process with the command yo angular-fullstack
. You will then be asked a few questions regarding the re-install. Answer them as follows:",
+ "Existing .yo-rc configuration found, would you like to use it? (Y/n) Y",
+ "Overwrite client/favicon.ico? (Ynaxdh) Y",
+ "To finish the installation run the commands: bower install && npm install
",
+ "To start MongoDB, run the following commands in your terminal: mkdir data && echo 'mongod --bind_ip=$IP --dbpath=data --nojournal --rest \"$@\"' > mongod && chmod a+x mongod && ./mongod
",
+ "You will want to open up a new terminal to work from by clicking on the + icon and select New Terminal",
+ "Start the application by running the following command in your new terminal window: grunt serve
",
+ "Wait for the following message to appear: xdg-open: no method available for opening 'http://localhost:8080'
. Now you can open the internal Cloud9 browser. To launch the browser select Preview in the toolbar then select the dropdown option Preview Running Application.",
+ "Turn the folder in which your application is running into a Git repository by running the following commands: git init && git add . && git commit -am 'initial commit'
.",
+ "Create a new Github repository by signing in to http://github.com and clicking on the + button next to your username in the upper-right hand side of your screen, then selecting \"New Repository\".",
+ "Enter a project name, then click the \"Create Repository\" button.",
+ "Find the \"...or push an existing repository from the command line\" section and click the Copy to Clipboard button beside it.",
+ "Paste the commands from your clipboard into the Cloud9 terminal prompt. This will push your changes to your repository on Cloud 9 up to Github.",
+ "Check back on your Github profile to verify the changes were successfully pushed up to Github.",
+ "Now let's push your code to Heroku. If you don't already have a Heroku account, create one at http://heroku.com. You shouldn't be charged for anything, but you will need to add your credit card information to your Heroku before you will be able to use Heroku's free MongoLab add on.",
+ "Before you publish to Heroku, you should free up as much memory as possible on Cloud9. In each of the Cloud9 terminal prompt tabs where MongoDB and Grunt are running, press the control + c
hotkey to shut down these processes.",
+ "Run the following command in a Cloud9 terminal prompt tab: npm install grunt-contrib-imagemin --save-dev && npm install --save-dev && heroku login
. At this point, the terminal will prompt you to log in to Heroku from the command line.",
+ "Now run yo angular-fullstack:heroku
. You can choose a name for your Heroku project, or Heroku will create a random one for you. You can choose whether you want to deploy to servers the US or the EU.",
+ "Set the config flag for your Heroku environment and add MongoLab for your MongoDB instance by running the following command: cd ~/workspace/dist && heroku config:set NODE_ENV=production && heroku addons:add mongolab
.",
+ "As you build your app, you should frequently commit changes to your codebase. Make sure you're in the ~/workspace
directory by running cd ~/workspace
. Then you can this code to stage the changes to your changes and commit them: git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a short summary of the changes you made to your code, such as \"added a records controller and corresponding routes\".",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Now you're ready to move on to your first Basejump. Click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it."
+ ],
+ "challengeType": 4,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c443eddfaeb5bdef",
+ "name": "Basejump: Build a Voting App",
+ "difficulty": 2.01,
+ "challengeSeed": "123488494",
+ "description": [
+ "Objective: Build a full stack JavaScript app that successfully reverse-engineers this: http://voteplex.herokuapp.com/ and deploy it to Heroku.",
+ "Note that for each Basejump, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-basejumps.",
+ "As you build your app, you should frequently commit changes to your codebase. You can do this by running git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a brief summary of the changes you made to your code.",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Here are the specific User Stories you should implement for this Basejump:",
+ "User Story: As an authenticated user, I can keep my polls and come back later to access them.",
+ "User Story: As an authenticated user, I can share my polls with my friends.",
+ "User Story: As an authenticated user, I can see the aggregate results of my polls.",
+ "User Story: As an authenticated user, I can delete polls that I decide I don't want anymore.",
+ "User Story: As an authenticated user, I can create a poll with any number of possible items.",
+ "Bonus User Story: As an unauthenticated user, I can see everyone's polls, but I can't vote on anything.",
+ "Bonus User Story: As an unauthenticated or authenticated user, I can see the results of polls in chart form. (This could be implemented using Chart.js or Google Charts.)",
+ "Bonus User Story: As an authenticated user, if I don't like the options on a poll, I can create a new option.",
+ "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 4,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c443eddfaeb5bdff",
+ "name": "Basejump: Build a Nightlife Coordination App",
+ "difficulty": 2.02,
+ "challengeSeed": "123488494",
+ "description": [
+ "Objective: Build a full stack JavaScript app that successfully reverse-engineers this: http://sociallife.herokuapp.com/ and deploy it to Heroku.",
+ "Note that for each Basejump, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-basejumps.",
+ "As you build your app, you should frequently commit changes to your codebase. You can do this by running git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a brief summary of the changes you made to your code.",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Here are the specific User Stories you should implement for this Basejump:",
+ "User Story: As an unauthenticated user, I can view all bars in my area.",
+ "User Story: As an authenticated user, I can add myself to a bar to indicate I am going there tonight.",
+ "User Story: As an authenticated user, I can remove myself from a bar if I no longer want to go there.",
+ "Bonus User Story: As an unauthenticated user, when I login I should not have to search again.",
+ "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 4,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c443eddfaeb5bd0e",
+ "name": "Basejump: Chart the Stock Market",
+ "difficulty": 2.03,
+ "challengeSeed": "123488494",
+ "description": [
+ "Objective: Build a full stack JavaScript app that successfully reverse-engineers this: http://stockjump.herokuapp.com/ and deploy it to Heroku.",
+ "Note that for each Basejump, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-basejumps.",
+ "As you build your app, you should frequently commit changes to your codebase. You can do this by running git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a brief summary of the changes you made to your code.",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Here are the specific User Stories you should implement for this Basejump:",
+ "User Story: As a user, I can view a graph displaying the recent trend lines for each added stock.",
+ "User Story: As a user, I can add new stocks by their symbol name.",
+ "User Story: As a user, I can remove stocks.",
+ "Bonus User Story: As a user, I can see changes in real-time when any other user adds or removes a stock.",
+ "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 4,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c443eddfaeb5bd0f",
+ "name": "Basejump: Manage a Book Trading Club",
+ "difficulty": 2.04,
+ "challengeSeed": "123488494",
+ "description": [
+ "Objective: Build a full stack JavaScript app that successfully reverse-engineers this: http://bookoutpost.herokuapp.com/ and deploy it to Heroku.",
+ "Note that for each Basejump, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-basejumps.",
+ "As you build your app, you should frequently commit changes to your codebase. You can do this by running git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a brief summary of the changes you made to your code.",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Here are the specific User Stories you should implement for this Basejump:",
+ "User Story: As an authenticated user, I can view all books posted by every user.",
+ "User Story: As an authenticated user, I can add a new book.",
+ "User Story: As an authenticated user, I can update my settings to store my full name, city, and state.",
+ "Bonus User Story: As an authenticated user, I can propose a trade and wait for the other user to accept the trade.",
+ "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 4,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c443eddfaeb5bdee",
+ "name": "Basejump: Build a Pinterest Clone",
+ "difficulty": 2.05,
+ "challengeSeed": "123488494",
+ "description": [
+ "Objective: Build a full stack JavaScript app that successfully reverse-engineers this: http://linkterest.herokuapp.com/ and deploy it to Heroku.",
+ "Note that for each Basejump, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-basejumps.",
+ "As you build your app, you should frequently commit changes to your codebase. You can do this by running git commit -am \"your commit message\"
. Note that you should replace \"your commit message\" with a brief summary of the changes you made to your code.",
+ "You can push these new commits to Github by running git push origin master
, and to Heroku by running grunt --force && grunt buildcontrol:heroku
.",
+ "Here are the specific User Stories you should implement for this Basejump:",
+ "User Story: As an unauthenticated user, I can login with Twitter.",
+ "User Story: As an authenticated user, I can link to images.",
+ "User Story: As an authenticated user, I can delete images that I've linked to.",
+ "User Story: As an authenticated user, I can see a Pinterest-style wall of all the images I've linked to.",
+ "User Story: As an unauthenticated user, I can browse other users' walls of images.",
+ "User Story: As an unauthenticated user, I can see everyone's polls, but not be able to vote.",
+ "Bonus User Story: As an authenticated user, if I upload an image that is broken, it will be replaced by a placeholder image. (can use jQuery broken image detection)",
+ "Hint: Masonry.js is a library that allows for Pinterest-style image grids.",
+ "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your Github repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 4,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/challenges/basic-html5-and-css.json b/seed_data/challenges/basic-html5-and-css.json
new file mode 100644
index 0000000000..274d64485b
--- /dev/null
+++ b/seed_data/challenges/basic-html5-and-css.json
@@ -0,0 +1,1626 @@
+{
+ "name": "Basic HTML5 and CSS",
+ "order" : 0.002,
+ "challenges": [
+ {
+ "_id": "bd7123c8c441eddfaeb5bdef",
+ "name": "Use HTML Elements",
+ "difficulty": 0.0085,
+ "description": [
+ "Welcome to Free Code Camp's first coding challenge! Click on the button below for further instructions.",
+ "Awesome. Now you can read the rest of this challenge's instructions.",
+ "You can edit code
in your text editor
, which we've embedded into this web page.",
+ "Do you see the code in your text editor that says <h1>Hello</h1>
? That's an HTML element
.",
+ "Most HTML elements have an opening tag
and a closing tag
. Opening tags look like this: <h1>
. Closing tags look like this: </h1>
. Note that the only difference between opening and closing tags is that closing tags have a slash after their opening angle bracket.",
+ "Once you've completed each challenge, and all its tests are passing, the \"Go to my next challenge\" button will become enabled. Click it - or press control and enter at the same time - to advance to the next challenge.",
+ "To enable the \"Go to my next challenge\" button on this exercise, change your h1
tag's text to say \"Hello World\" instead of \"Hello\"."
+ ],
+ "tests": [
+ "assert.isTrue((/hello(\\s)+world/gi).test($('h1').text()), 'Your h1 element should have the text \"Hello World\"')"
+ ],
+ "challengeSeed": [
+ "
h2
tag that says \"CatPhotoApp\" to create a second HTML element
below your \"Hello World\" h1
element.",
+ "The h2 element you enter will create an h2 element on the website.",
+ "This element tells the browser how to render the text that it contains.",
+ "h2
elements are slightly smaller than h1
elements. There are also h3
, h4
, h5
and h6
elements."
+ ],
+ "tests": [
+ "assert.isTrue((/cat(\\s)?photo(\\s)?app/gi).test($('h2').text()), 'Your h2 element should have the text \"CatPhotoApp\"')",
+ "assert.isTrue((/hello(\\s)+world/gi).test($('h1').text()), 'Your h1 element should have the text \"Hello World\"')"
+ ],
+ "challengeSeed": [
+ "<p>I'm a p tag!</p>
"
+ ],
+ "tests": [
+ "assert.isTrue((/hello(\\s)+paragraph/gi).test($('p').text()), 'Your paragraph element should have the text \"Hello Paragraph\"')"
+ ],
+ "challengeSeed": [
+ "line break
between the <h2>
and <p>
elements.",
+ "You can create an line break element with <br/>
.",
+ "Note that <br/>
has no closing tag. It is a self-closing
element. See how a forward-slash precedes the closing bracket?",
+ "You'll encounter other self-closing
element tags soon."
+ ],
+ "tests": [
+ "assert(($('br').length > 0), 'You should have a br element between your h2 and paragraph elements.')"
+ ],
+ "challengeSeed": [
+ "Hello Paragraph
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08802", + "name": "Uncomment HTML", + "difficulty": 0.013, + "description": [ + "Uncomment theh1
, h2
and p
elements.",
+ "Commenting is a way that you can leave comments within your code without affecting the code itself.",
+ "Commenting is also a convenient way to make code inactive without having to delete it entirely.",
+ "You can start a comment with <!--
and end a comment with -->
."
+ ],
+ "tests": [
+ "assert(($('h1').length > 0), 'The h1 element should not commented. It should be visible in the browser.')",
+ "assert(($('h2').length > 0), 'The h2 element should not commented. It should be visible in the browser.')",
+ "assert(($('p').length > 0), 'The paragraph element should not commented. It should be visible in the browser.')"
+ ],
+ "challengeSeed": [
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08804",
+ "name": "Comment out HTML",
+ "difficulty": 0.014,
+ "description": [
+ "Comment out the h1
element and the p
element, but leave the h2
element uncommented.",
+ "Remember that in order to start a comment, you need to use <!--
and to end a comment, you need to use -->
.",
+ "Here you'll need to end the comment before the h2 element begins."
+ ],
+ "tests": [
+ "assert(($('h1').length == 0), 'The h1 element should be commented. It should not be visible in the browser.')",
+ "assert(($('h2').length > 0), 'The h2 element should not commented. It should be visible in the browser.')",
+ "assert(($('p').length == 0), 'The paragraph element should be commented. It should not be visible in the browser.')"
+ ],
+ "challengeSeed": [
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08833",
+ "name": "Use Lorem Ipsum Text as a Placeholder",
+ "difficulty": 0.015,
+ "description": [
+ "Change the text in the p
element to use the first few words of Kitty Ipsum
text.",
+ "Web developers traditionally use Lorem Ipsum
as placeholder text. It's called Lorem Ipsum text because those are the first two words of a famous passage by Cicero of Ancient Rome.",
+ "Lorem Ipsum text has been used as placeholder text by typesetters since the 16th century, and this tradition continues on the web.",
+ "Well, 5 centuries is long enough. Since we're building a CatPhotoApp, let's use something called Kitty Ipsum!",
+ "Here are the first few words of Kitty Ipsum text, which you can copy and paste into the right position: Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
+ ],
+ "tests": [
+ "assert.isTrue((/Kitty(\\s)+ipsum(\\s)+dolor/gi).test($('p').text()), 'Your paragraph element should contain the first few words of the famous Kitty Ipsum text.')"
+ ],
+ "challengeSeed": [
+ "Hello Paragraph
" + ] + }, + { + "_id": "bad87fed1348bd9aedf08833", + "name": "Delete HTML Elements", + "difficulty": 0.016, + "description": [ + "Delete the h1 and br elements so we can simplify our view.", + "Our phone doesn't have much space, for HTML elements.", + "Let's remove the unnecessary elements so we can start building our CatPhotoApp." + ], + "tests": [ + "assert(($('h1').length == 0), 'Delete the h1 element.')", + "assert(($('h2').length > 0), 'Leave the h2 element on the page.')", + "assert(($('br').length == 0), 'Delete the br element.')", + "assert(($('p').length > 0), 'Leave the paragraph element on the page.')" + ], + "challengeSeed": [ + "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08803", + "name": "Change the Color of Text", + "difficulty": 0.017, + "description": [ + "Change theh2
element's style so that its text color is red.",
+ "We can do this by changing the style
of the h2
element.",
+ "The style that is responsible for the color of an element's text is the \"color\" style.",
+ "Here's how you would set your h2
element's text color to blue: <h2 style=\"color: blue\">CatPhotoApp<h2>
"
+ ],
+ "tests": [
+ "assert($('h2').css('color') === 'rgb(255, 0, 0)', 'Your h2 element should be red.')"
+ ],
+ "challengeSeed": [
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08805", + "name": "Use CSS Selectors to Style Elements", + "difficulty": 0.018, + "description": [ + "Delete yourh2
element's style
tag and write the CSS to make all h2
elements blue.",
+ "With CSS, there are hundreds of CSS attributes
that you can use to change the way an element looks on a web page.",
+ "When you entered <h2 style=\"color: red\">CatPhotoApp<h2>
, you were giving that individual h2 element an inline style
",
+ "That's one way to add style to an element, but a better way is by using Cascading Style Sheets (CSS)
.",
+ "At the top of your code, create a style tag
like this: <style></style>
",
+ "Inside that style element, you can create a css selector
for all h2
elements. For example, if you wanted all h2
elements to be red, your style element would look like this: <style>h2 {color: red;}</style>
",
+ "Note that it's important to have opening and closing curly braces
({
and }
) around each element's style. You also need to make sure your element's style is between the opening and closing style tags. Finally, be sure to add the semicolon to the end of each of your element's styles."
+ ],
+ "tests": [
+ "assert($('h2').css('color') === 'rgb(0, 0, 255)', 'Your h2 element should be blue.')",
+ "assert(!$('h2').attr('style'), 'You should remove the style attribute from your h2 element.')"
+ ],
+ "challengeSeed": [
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aecf08806", + "name": "Use a CSS Class to Style an Element", + "difficulty": 0.019, + "description": [ + "Create a CSS class called \"red-text\" and apply it to yourh2
element.",
+ "Classes are reusable styles that can be added to HTML elements.",
+ "Here's the anatomy of a CSS class:",
+ "<style>
tag.",
+ "You can apply a class to an HTML element like this: <h2 class=\"blue-text\">CatPhotoApp<h2>
",
+ "Note that in your CSS style
element, classes should start with a period. In your HTML elements' class declarations, classes shouldn't start with a period.",
+ "Instead of creating a new Style tag, try removing the h2 style declaration from the existing style element, and replace it with the class declaration for \".red-text\"."
+ ],
+ "tests": [
+ "assert($('h2').css('color') === 'rgb(255, 0, 0)', 'Your h2 element should be red.')",
+ "assert($('h2').hasClass('red-text'), 'You h2 element should have the class \"red-text\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aefe08806", + "name": "Use a CSS Class to Style Multiple Elements", + "difficulty": 0.020, + "description": [ + "Apply the \"red-text\" class to theh2
and p
elements.",
+ "Remember that you can attach classes to HTML elements by using the class=\"class\"
within the relevant element's opening tag."
+ ],
+ "tests": [
+ "assert($('h2').css('color') === 'rgb(255, 0, 0)', 'Your h2 element should be red.')",
+ "assert($('h2').hasClass('red-text'), 'You h2 element should have the class \"red-text\".')",
+ "assert($('p').css('color') === 'rgb(255, 0, 0)', 'Your paragraph element should be red.')",
+ "assert($('p').hasClass('red-text'), 'You paragraph element should have the class \"red-text\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08806", + "name": "Change the Font Size of an Element", + "difficulty": 0.021, + "description": [ + "Create a secondp
element. Then set the font size of all p
elements to 16 pixels.",
+ "Font size is controlled by the font-size
CSS attribute, like this: h1 { font-size: 30px; }
.",
+ "First, create a second paragraph element with the following Kitty Ipsum text: Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
",
+ "See if you can figure out how to give both of your paragraph elements the font-size of 16 pixels (16px
). You can do this inside the same <style>
tag that we created for your \"red-text\" class."
+ ],
+ "tests": [
+ "assert($('p').length > 1, 'You need 2 paragraph elements with Kitty Ipsum text.')",
+ "assert($('p').css('font-size') === '16px', 'Your paragraph elements should have the font-size of 16px.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
" + ] + }, + { + "_id": "bad87fee1348bd9aede08807", + "name": "Set the Font Family of an Element", + "difficulty": 0.022, + "description": [ + "Make all paragraph elements use the \"Monospace\" font.", + "You can set an element's font by using thefont-family
attribute.",
+ "For example, if you wanted to set your h2 element's font to \"San-serif\", you would use the following CSS: h2 { font-family: 'San-serif'; }
"
+ ],
+ "tests": [
+ "assert($('p').css('font-family').match(/monospace/i), 'Your paragraph elements should use the font \"Monospace\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08807", + "name": "Import a Google Font", + "difficulty": 0.023, + "description": [ + "Apply thefont-family
of \"Lobster\" to your h2
element.",
+ "First, you'll need to make a call
to Google to grab the \"Lobster\" font and load it into your HTML.",
+ "Copy the following code snippet and paste it into your code editor above your style
element:",
+ "<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
",
+ "Now you can set \"Lobster\" as a font-family attribute on your h2
element."
+ ],
+ "tests": [
+ "assert($('h2').css('font-family').match(/lobster/i), 'Your h2 element should use the font \"Lobster\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08808", + "name": "Specify How Fonts Should Degrade", + "difficulty": 0.024, + "description": [ + "Make all yourh2
elements use \"Lobster\" as their font family, but degrade to the \"Monospace\" font when the \"Lobster\" font isn't available.",
+ "You can leave \"Lobster\" your h2
element's font-family, and have it \"degrade\" to a different font when \"Lobster\" isn't available.",
+ "For example, if you wanted an element to use the \"Helvetica\" font, but also degrade to the \"Sans-Serif\" font when \"Helvetica\" wasn't available, you could do use this CSS style: p { font-family: \"Helvetica\", \"Sans-Serif\"; }
.",
+ "There are several default fonts that are available in all browsers. These include \"Monospace\", \"Serif\" and \"Sans-Serif\". See if you can set your h2 elements to use \"Lobster\" and degrade to \"Monospace\".",
+ "Now try commenting out your call to Google Fonts, so that the \"Lobster\" font isn't available. Notice how it degrades to the \"Monospace\" font."
+ ],
+ "tests": [
+ "assert($('h2').css('font-family').match(/lobster/i), 'Your h2 element should use the font \"Lobster\".')",
+ "assert($('h2').css('font-family').match(/monospace/i), 'Your h2 element should degrade to the font \"Monospace\" when \"Lobster\" is not available.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08809", + "name": "Using Important to Override Styles", + "difficulty": 0.025, + "description": [ + "Create a \"blue-text\" class that gives an element the font-color of blue. Also create a \"urgently-red\" class that give an element the font-color of red, but use!important
to ensure the element is rendered as being red. Apply both classes to your h2
element.",
+ "Sometimes HTML elements will receive conflicting information from CSS classes as to how they should be styled.",
+ "If there's a conflict in the CSS, the browser will use whichever style declaration is closest to the bottom of the CSS document (whichever declaration comes last). Note that in-line style declarations are the final authority in how an HTML element will be rendered.",
+ "There's one way to ensure that an element is rendered with a certain style, regardless of where that declaration is located. That one way is to use !important
.",
+ "In case you're curious, this is the priority hierarchy for element styles: !important > inline style > css class selector > css selector. That is, !important trumps all other styles, and inline styles trump style tag declarations.",
+ "Here's an example of a CSS style that uses !important
: <style> .urgently-blue { color: blue !important; } </style>
.",
+ "Now see if you can make sure the h2 element is rendered in the color red without removing the \"blue-text\" class, doing an in-line styling, or changing the sequence of CSS class declarations."
+ ],
+ "tests": [
+ "assert($('h2').hasClass('blue-text'), 'Your h2 element should have the class \"blue-text\".')",
+ "assert($('h2').hasClass('urgently-red'), 'Your h2 element should have the class \"urgently-red\".')",
+ "assert($('h2').css('color') === 'rgb(255, 0, 0)', 'Your h2 element should be red.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + + { + "_id": "bad87fee1348bd9aedf08812", + "name": "Add an Image to your Website", + "difficulty": 0.026, + "description": [ + "Use animg
element to add the image http://bit.ly/fcc-kittens
to your website.",
+ "You can add images to your website by using the img
element, and point to an specific image's URL using the src
attribute.",
+ "An example of this would be <img src=\"www.your-image-source.com/your-image.jpg\"/>
. Note that in most cases, img
elements are self-closing.",
+ "Try it with this image: http://bit.ly/fcc-kittens
."
+ ],
+ "tests": [
+ "assert($('img').length > 0, 'Your webpage should have an image element.')",
+ "assert(!!$('img').attr('src'), 'Your image should have have a src
attribute that points to the kitten image.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9acdf08812", + "name": "Specify an Image Size", + "difficulty": 0.027, + "description": [ + "Create a class calledsmaller-image
and use it to resize the image so that it's only 100 pixels wide.",
+ "CSS has an attribute called width
that controls an element's width. Just like with fonts, we'll use pixels(px) to specify the images width.",
+ "For example, if we wanted to create a CSS class called \"larger-image\" that gave HTML elements a width of 500 pixels, we'd use: <style> .larger-image { width: 500px; } </style>
."
+ ],
+ "tests": [
+ "assert($('img').hasClass('smaller-image'), 'Your img
element should have the class \"smaller-image\".')",
+ "assert($('img').width() === 100, 'Your image should be 100 pixels wide.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9bedf08813", + "name": "Add a Border Around an Element", + "difficulty": 0.028, + "description": [ + "Create a class called \"thick-green-border\" that puts a 10-pixel-wide green border around an HTML element, and apply it to your cat photo.", + "CSS borders have attributes like style, color and width.", + "For example, if we wanted to create a red, 5 pixel border around an HTML element, we could use this class:<style> .thin-red-border { border-color: red; border-width: 5px; border-style: solid; } </style>
."
+ ],
+ "tests": [
+ "assert($('img').hasClass('smaller-image'), 'Your img
element should have the class \"smaller-image\".')",
+ "assert($('img').hasClass('thick-green-border'), 'Your image element should have the class \"thick-green-border\".')",
+ "assert(parseInt($('img').css('border-left-width')) > 8, 'Your image should have a border with a width of 10 pixels.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08814", + "name": "Add Rounded Corners with a Border Radius", + "difficulty": 0.029, + "description": [ + "Give your cat photo a border radius of 10 pixels.", + "Your cat photo currently has sharp corners. We can round out those corners with a CSS attribute calledborder-radius
.",
+ "You can specify a border-radius
with pixels. This will affect how rounded the corners are. Add this attribute to your thick-green-border
class and set it to 10 pixels."
+ ],
+ "tests": [
+ "assert($('img').hasClass('thick-green-border'), 'Your image element should have the class \"thick-green-border\".')",
+ "assert(parseInt($('img').css('border-top-left-radius')) > 8, 'Your image should have a border radius of 10 pixels')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08815", + "name": "Make an Image Circular with a Border Radius", + "difficulty": 0.030, + "description": [ + "Give your cat photo aborder-radius
of 50%.",
+ "In addition to pixels, you can also specify a border-radius
using a percentage."
+ ],
+ "tests": [
+ "assert(parseInt($('img').css('border-top-left-radius')) > 48, 'Your image should have a border radius of 50 percent, making it perfectly circular.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08816", + "name": "Use an Anchor Tag to Link to an External Page", + "difficulty": 0.031, + "description": [ + "Create ananchor
element that links to http://catphotoapp.com and has \"cat photos\" as its anchor text (link text).",
+ "Here's a diagram of an anchor tag
. In this case, it's used in the middle of a paragraph element, which means your link will appear in the middle of your sentence.",
+ "<p>Here's a <a href='http://freecodecamp.com'> link to Free Code Camp</a> for you to follow.</p>
"
+ ],
+ "tests": [
+ "assert((/photo/gi).test($('a').text()), 'You need an anchor
element that links to \"catphotoapp.com\".')",
+ "assert($('a').filter(function(index) { return /photo/gi.test($('a')[index]); }).length === 1, 'Your anchor
element should have the anchor text of \"See my cat photos\"')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aede08817", + "name": "Wrap an Anchor Element within a Paragraph", + "difficulty": 0.032, + "description": [ + "Now wrap your anchor element within aparagraph
element so that the surrounding paragraph says \"click here for cat photos\", but where only \"cat photos\" is a link - the rest is plain text.",
+ "Again, here's a diagram of an anchor tag
for your reference:",
+ "<p>Here's a <a href='http://freecodecamp.com'> link to Free Code Camp</a> for you to follow.</p>
"
+ ],
+ "tests": [
+ "assert((/photo/gi).test($('a').text()), 'You need an anchor
element that links to \"catphotoapp.com\".')",
+ "assert($('a').filter(function(index) { return /photo/gi.test($('a')[index]); }).length === 1, 'Your anchor
element should have the anchor text of \"See my cat photos\"')",
+ "assert($('a').parent().is('p'), 'Your anchor element should be wrapped within a paragraph element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + + { + "_id": "bad87fee1348bd9aedf08817", + "name": "Make Dead Links using the Hash Symbol", + "difficulty": 0.033, + "description": [ + "Use the hash symbol(#) to turn youranchor
element's link into a dead link.",
+ "Sometimes you want to add anchor
elements to your website before you know where they will link.",
+ "This is also handy when you're changing the behavior of a link using jQuery
, which we'll learn about later.",
+ "Replace your anchor
element's href
attribute with a hash symbol to turn it into a dead link."
+ ],
+ "tests": [
+ "assert($('a').attr('href') === '#', 'Your anchor
element should be a dead link with a href
attribute set to \"#\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08820", + "name": "Turn an Image into a Link", + "difficulty": 0.034, + "description": [ + "Wrap yourimg
element inside an anchor element with a dead link.",
+ "You can make elements into links by wrapping them in an anchor tag
.",
+ "Wrap your image in an anchor tag
. Here's an example: <a href='#'><img src='http://bit.ly/fcc-kittens2'></a>
",
+ "Remember to use the hash symbol as your anchor tag
's href
property in order to turn it into a dead link.",
+ "Once you've done this, hover over your image with your cursor. Your cursor's normal pointer should become the link clicking pointer. The photo is now a link."
+ ],
+ "tests": [
+ "assert($('a').filter(function(index) { return /#/gi.test($('a')[index]); }).length > 1, 'Wrap your image element inside an anchor element that has its href
attribute set to \"#\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + { + "_id": "bad87fee1348bd9aedf08818", + "name": "Add Alt Text to an image", + "difficulty": 0.035, + "description": [ + "Add thealt text
\"A cute orange cat lying on its back\" to our cat photo",
+ "alt text
is what browsers will display if they fail to load the image. alt text
is also important for blind or visually impaired users to understand what an image portrays. Search engines also look at alt text
.",
+ "In short, every image should have alt text
!",
+ "Alt text
is a useful way to tell people (and web crawlers like Google) what is pictured in a photo. It's extremely important for helping blind or visually impaired people understand the content of your website.",
+ "You can add alt text right in the img element like this: <img src=\"www.your-image-source.com/your-image.jpg\" alt=\"your alt text\"/>
."
+ ],
+ "tests": [
+ "assert($('img').filter(function(){ return /cat/gi.test(this.alt) }).length > 0, 'Your image element should have an alt
attribute set to \"A cute orange cat lying on its back\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + + { + "_id" : "bad87fee1348bd9aedf08827", + "name": "Create a Bulleted Unordered List", + "difficulty" : 0.036, + "description": [ + "Replace the paragraph elements with an unordered list of three things that cats love.", + "HTML has a special element for creating unordered lists, or bullet point-style lists.", + "Unordered lists start with a<ul>
element. Then they contain some number of <li>
elements.",
+ "For example: <ul><li>milk</li><li>cheese</li><ul>
would create a bulleted list of \"milk\" and \"cheese\"."
+ ],
+ "tests": [
+ "assert($('ul').length > 0, 'Create a ul
element.')",
+ "assert($('li').length > 2, 'Add three li
elements to your ul
element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
", + "Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
" + ] + }, + + { + "_id" : "bad87fee1348bd9aedf08828", + "name": "Create an Ordered List", + "difficulty" : 0.037, + "description": [ + "Create anordered list
of the the top 3 things cats hate the most.",
+ "HTML has a special element for creating ordered lists, or numbered-style lists.",
+ "Ordered lists start with a <ol>
element. Then they contain some number of <li>
elements.",
+ "For example: <ol><li>hydrogen</li><li>helium</li><ol>
would create a numbered list of \"hydrogen\" and \"helium\"."
+ ],
+ "tests": [
+ "assert($('ul').length > 0, 'You should have an ul
element on your webpage.')",
+ "assert($('ol').length > 0, 'You should have an ol
element on your webpage.')",
+ "assert($('li').length > 5, 'You should have three li
elements on within your ul
element.')",
+ "assert($('li').length > 5, 'You should have three li
elements on within your ol
element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Things cats love:
", + "<input type='text'>
"
+ ],
+ "tests": [
+ "assert($('input[type=\"text\"').length > 0, 'Your webpage should have an text field input element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Things cats love:
", + "Top 3 things cats hate:
", + "<input type='text' placeholder='this is placeholder text'>
"
+ ],
+ "tests": [
+ "assert($('[placeholder]').length > 0, 'Your text field should have the placeholder text of \"cat photo URL\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Things cats love:
", + "Top 3 things cats hate:
", + "<form>
element. Add the action=\"/submit-cat-photo\"
attribute to this form element.",
+ "You can build web forms that actually submit data to a server using nothing more than pure HTML. You can do this by specifying an action on your form
element.",
+ "For example: <form action=\"/url-where-you-want-to-submit-form-data\"></form>
"
+ ],
+ "tests": [
+ "assert($('form').length > 0, 'Wrap your text input element within a form
element.')",
+ "assert($('form').attr('action'), 'Your form
element should have an action
attribute.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "Click here for cat photos.
", + "", + "Things cats love:
", + "Top 3 things cats hate:
", + "action
attribute.",
+ "Here's an example submit button: <button type='submit'>this button submits the form</button>"
+ ],
+ "tests": [
+ "assert($('button').length > 0, 'Your form should have a button inside it.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedc08830",
+ "name": "Use HTML5 to Make a Field Required",
+ "difficulty" : 0.042,
+ "description": [
+ "Make it required for your user to input text into your form before being able to submit it.",
+ "You can require your user to complete specific form fields before they will be able to submit your form.",
+ "For example, if you wanted to make a text input field required, you can just add the word \"required\" within your input
element use: <input type='text' required>
"
+ ],
+ "tests": [
+ "assert($('input').prop('required'), 'Your text field have the property of being required.')",
+ "assert($('[placeholder]').length > 0, 'Your text field should have the placeholder text of \"cat photo URL\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedf08834",
+ "name": "Create a Set of Radio Buttons",
+ "difficulty" : 0.043,
+ "description": [
+ "Add to your form a pair of radio buttons
that are wrapped in label
elements and share a name
attribute, with the options of \"indoor\" and \"outdoor\".",
+ "You can use radio buttons
for questions where you want the user to only give you one answer.",
+ "Radio buttons are a type of input
.",
+ "Radio buttons should be wrapped within label
elements.",
+ "All related radio buttons should have the same name
attribute.",
+ "Here's an example of a radio button: <label><input type='radio' name='indoor-outdoor'> Indoor</label>
"
+ ],
+ "tests": [
+ "assert($('input[type=\"radio\"').length > 1, 'Your webpage should have two radio button elements.')",
+ "assert($('input[type=\"radio\"').attr('name'), 'Both of your radio button should have name
attributes with the same value.')",
+ "assert($('label').length > 1, 'Each of your two radio button elements should be wrapped in a label element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedf08835",
+ "name": "Create a Set of Checkboxes",
+ "difficulty" : 0.044,
+ "description": [
+ "Add to your form a set of three checkbox
elements that are wrapped in label
elements and share the same name
attribute.",
+ "Forms commonly use checkbox
elements for questions that may have more than one answer.",
+ "For example: <label><input type='checkbox' name='personality'> Loving</label>
"
+ ],
+ "tests": [
+ "assert($('input[type=\"checkbox\"').length > 2, 'Your webpage should have three checkbox elements.')",
+ "assert($('label').length > 2, 'Each of your three checkbox elements should be wrapped in a label element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aede08835",
+ "name": "Clean up your form using Linebreaks",
+ "difficulty" : 0.045,
+ "description": [
+ "Clean up your form by adding linebreaks between form elements.",
+ "Remember that you can create a linebreak element by using the code: <br>
"
+ ],
+ "tests": [
+ "assert($('br').length > 1, 'Add at least 2 line breaks to visually separate your form elements.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedd08835",
+ "name": "Check Radio Buttons and Checkboxes by Default",
+ "difficulty" : 0.046,
+ "description": [
+ "Set one of your radio buttons and one of your checkboxes to be checked by default.",
+ ""
+ ],
+ "tests": [
+ "assert($('input[type=\"radio\"').prop('checked'), 'One of the radio buttons on your form should be checked by default.')",
+ "assert($('input[type=\"checkbox\"').prop('checked'), 'One of the checkboxes on your form should be checked by default.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ }
+ ]
+}
diff --git a/seed_data/challenges/basic-javascript.json b/seed_data/challenges/basic-javascript.json
new file mode 100644
index 0000000000..7f33bd5bbc
--- /dev/null
+++ b/seed_data/challenges/basic-javascript.json
@@ -0,0 +1,167 @@
+{
+ "name": "Basic JavaScript",
+ "order" : 0.006,
+ "challenges": [
+ {
+ "_id": "bd7129d8c441eddfaeb5bdef",
+ "name": "Build an Adventure Game",
+ "difficulty": 0.24,
+ "challengeSeed": "114604814",
+ "description": [
+ "Now that you understand some Computer Science fundamentals, let's focus on programming JavaScript!",
+ "We're going to work through Codecademy's famous interactive JavaScript course.",
+ "This course will teach us some JavaScript fundamentals while guiding us through the process of building interesting web apps, all within Codecademy's learner-friendly environment!",
+ "Go to http://www.codecademy.com/courses/getting-started-v2/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-x9DnD/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7130d8c441eddfaeb5bdef",
+ "name": "Build Rock Paper Scissors",
+ "difficulty": 0.25,
+ "challengeSeed": "114604815",
+ "description": [
+ "Now we'll learn how JavaScript functions work, and use them to build a simple Rock Paper Scissors game.",
+ "Go to http://www.codecademy.com/courses/javascript-beginner-en-6LzGd/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-Bthev-mskY8/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7131d8c441eddfaeb5bdef",
+ "name": "Learn JavaScript For Loops",
+ "difficulty": 0.26,
+ "challengeSeed": "114614220",
+ "description": [
+ "Let's learn more about the loops that make virtually all programs possible - the \"For Loop\" and \"While Loop\". First, we'll learn the For Loop.",
+ "Go to http://www.codecademy.com/courses/javascript-beginner-en-NhsaT/0/1web and complete both the both For and While loop section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-XEDZA/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7132d8c441eddfaeb5bdef",
+ "name": "Learn JavaScript While Loops",
+ "difficulty": 0.27,
+ "challengeSeed": "114612889",
+ "description": [
+ "Go to http://www.codecademy.com/courses/javascript-beginner-en-ASGIv/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-mrTNH-6VIZ9/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7133d8c441eddfaeb5bdef",
+ "name": "Learn Control Flow",
+ "difficulty": 0.28,
+ "challengeSeed": "114612888",
+ "description": [
+ "Much of human reasoning can be broken down into what we call Boolean Logic. Lucky for us, computers can think the same way! Let's learn how to instruct our computers by writing \"If Statements\" and \"Else Statements\".",
+ "We'll also learn some advanced \"Control Flow\" principals, such as ways we can exit loops early.",
+ "Go to http://www.codecademy.com/courses/javascript-beginner-en-qDwp0/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-ZA2rb/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7134d8c441eddfaeb5bdef",
+ "name": "Build a Contact List",
+ "difficulty": 0.29,
+ "challengeSeed": "114612887",
+ "description": [
+ "Up to this point, you've been working mostly with strings and numbers. Now we're going to learn more complicated data structures, like \"Arrays\" and \"Objects\".",
+ "Go to http://www.codecademy.com/courses/javascript-beginner-en-9Sgpi/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/javascript-beginner-en-3bmfN/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7135d8c441eddfaeb5bdef",
+ "name": "Build an Address Book",
+ "difficulty": 0.30,
+ "challengeSeed": "114612885",
+ "description": [
+ "Let's learn more about objects.",
+ "Go to http://www.codecademy.com/courses/spencer-sandbox/0/1 and complete the section.",
+ "Be sure to also complete this section: http://www.codecademy.com/courses/building-an-address-book/0/1?curriculum_id=506324b3a7dffd00020bf661."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7136d8c441eddfaeb5bdef",
+ "name": "Build a Cash Register",
+ "difficulty": 0.31,
+ "challengeSeed": "114612882",
+ "description": [
+ "In this final Codecademy section, we'll learn even more about JavaScript objects.",
+ "Go to http://www.codecademy.com/courses/objects-ii/0/1 and complete this section.",
+ "Be sure to also complete the final section: http://www.codecademy.com/courses/close-the-super-makert/0/1."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7118d8c441eddfaeb5bdef",
+ "name": "Discover Chrome's DevTools",
+ "difficulty": 0.32,
+ "challengeSeed": "110752743",
+ "description": [
+ "It's time to learn the most powerful tool your browser has - the Development Tools!",
+ "If you aren't already using Chrome, you'll want to download it here: http://www.google.com/chrome/. While it's true that Firefox has a tool called Firebug that is very similar to Chrome's DevTools, we will use Chrome for this challenge.",
+ "Note that this course, jointly produced by Google and Code School, is technologically impressive, but occasionally buggy. If you encounter a bug, just ignore it and keep going.",
+ "Go to http://discover-devtools.codeschool.com and complete this short course."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7138d8c441eddfaeb5bdef",
+ "name": "Learn Regular Expressions",
+ "difficulty": 0.33,
+ "challengeSeed": "112547802",
+ "description": [
+ "You can use a Regular Expression, or \"Regex\", to select specific types of characters in text.",
+ "Check out http://www.regexr.com. It's a Regular Expression Sandbox.",
+ "Now go to http://www.regexone.com and complete the tutorial and exercises 1 - 6.",
+ "Note that you can click \"continue\" to move on to the next step as soon as all the tasks have green check marks beside them. You can often do this just by using the wildcard \"dot\" operator, but try to use the techniques that each lesson recommends."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7139d8c441eddfaeb5bdef",
+ "name": "Pair Program on Bonfires",
+ "difficulty": 0.44,
+ "challengeSeed": "119657641",
+ "description": [
+ "OK, we're finally ready to start pair programming!",
+ "Pair Programming is where two people code together on the same computer. It is an efficient way to collaborate, and widely practiced at software companies. Pair Programming is one of the core concepts of \"Agile\" Software Development, which you will hear more about later.",
+ "Many people use Skype or Google Hangouts to pair program, but if you talk with professional software engineers, they will tell you that it's not really pair programming unless both people have the ability to use the keyboard and mouse.",
+ "The most popular tool for pair programming is Screen Hero. You can download Screen Hero for Mac or Windows. Create your new user account from within the app.",
+ "We have a special chat room for people ready to pair program. Go to our Slack chatroom and navigate to the #letspair channel and type \"Hello Pair Programmers!\"",
+ "If someone is available, they will be your \"pair\" - the person you pair programming with.",
+ "If no one gets back to you in the first few minutes, don't worry. There will be lots of opportunities to pair program in the future.",
+ "If someone does get back to you, private message them and ask for the email address they used to register Screen Hero.",
+ "Add them as a new contact in Screen Hero, then click the monitor-looking button to attempt to share your screen with them.",
+ "Once the Screen Hero session starts, your screen's margins will glow orange. You are now sharing your screen.",
+ "Your pair will have their own cursor, and will be able to type text on his or her and keyboard.",
+ "Now it's time to tackle our Bonfires.",
+ "Go to http://freecodecamp.com/bonfires and start working through our Bonfire challenges.",
+ "Once you you finish pair programming, end the session in Screen Hero session.",
+ "Congratulations! You have completed your first pair programming session.",
+ "Pair program as much as possible with different campers until you've completed all the Bonfire challenges. This is a big time investment, but the JavaScript practice you get will be well worth it!",
+ "Mark this challenge as complete and move on to the Bonfires."
+ ],
+ "challengeType": 2,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/challenges/basics.json b/seed_data/challenges/basics.json
deleted file mode 100644
index 16134aa92f..0000000000
--- a/seed_data/challenges/basics.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "name": "basics",
- "order" : 0.001,
- "challenges": [
- {
- "_id": "bd7126d8c441eddfaeb5bd3e",
- "name": "Meet Other Campers in your City",
- "difficulty": 0.065,
- "challengeSeed": "127358841",
- "description": [
- "One of the best ways to stay motivated when learning to code is to hang out with other campers.",
- "Slack and Camper News are great ways to communicate with other campers, but there's no substitute for meeting people in-person.",
- "The easiest way to meet other campers in your city is to join your city's Facebook Group. Click here to view our growing list of local groups.",
- "Click the link to your city, then, once Facebook loads, click \"Join group\".",
- "Our local groups are new, so if you don't see your city on this list, you should follow the directions to create a Facebook group for your city.",
- "If you don't have a Facebook account, we strongly recommend you create one, even if it's just for the purpose of coordinating with campers in your city through this group.",
- "Our groups allow you to create events, coordinate those events, and share photos from the events afterward.",
- "Whether you're hosting a study group, pair programming at your local library, or going to a weekend hackathon, your city's group will help you make it happen."
- ],
- "challengeType": 2,
- "tests": []
- },
- {
- "_id": "bd7137d8c441eddfaeb5bdef",
- "name": "Get Help the Hacker Way with RSAP",
- "difficulty": 0.07,
- "challengeSeed": "125407432",
- "description": [
- "Let's cover one last thing before you start working through our lessons: how to get help.",
- "Any time you get stuck or don't know what to do next, follow this simple algorithm (procedure): RSAP (Read, Search, Ask, Post).",
- "First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.",
- "Next, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.",
- "Then, if you still haven't found an answer to your question, A - Ask your friends. If you have trouble, you can ask your fellow campers. We have a special chat room specifically for getting help with tools you learn through these Free Code Camp Challenges. Go to https://freecode.slack.com/messages/help/. Keep this chat open while you work on the remaining challenges.",
- "Finally, P - Post on Stack Overflow. Before you attempt to do this, read Stack Overflow's guide to asking good questions: http://stackoverflow.com/help/how-to-ask.",
- "Here's our detailed field guide on getting help: http://freecodecamp.com/field-guide/how-do-i-get-help-when-i-get-stuck.",
- "Now you have a clear algorithm to follow when you need help! Let's start coding! Move on to your next challenge."
- ],
- "challengeType": 2,
- "tests": []
- },
- {
- "_id": "bd7127d8c441eddfaeb5bdef",
- "name": "Build a Landing Page with HTML",
- "difficulty": 0.08,
- "challengeSeed": "125671867",
- "description": [
- "Now it's time for us to start our actual coding lessons. We've curated a series of free, self-paced, browser-based lessons from providers like Codecademy and Stanford University.",
- "These lessons will cover a lot of ground quickly, and will hold your hand throughout the process. Don't try to memorize everything - you'll spend more than a thousand hours practicing these later, and you can always look things up. Just keep moving.",
- "If you've learned HTML and CSS before, these next few Waypoints will be a valuable review. If you haven't learned HTML or CSS before, you're in for a treat!",
- "This Codecademy will quickly cover HTML, CSS and even Responsive Design with Bootstrap.",
- "If you don't already have a Codecademy account, create one here: http://www.codecademy.com.",
- "Go to http://www.codecademy.com/en/skills/make-a-website/topics/html-elements and complete the section.",
- "Once you're done, mark this Waypoint complete and move on the next Waypoint."
- ],
- "challengeType": 2,
- "tests": []
- }
- ]
-}
\ No newline at end of file
diff --git a/seed_data/challenges/bonfires.json b/seed_data/challenges/bonfires.json
new file mode 100644
index 0000000000..ad9d6c4b4e
--- /dev/null
+++ b/seed_data/challenges/bonfires.json
@@ -0,0 +1,1166 @@
+{
+ "name": "Bonfires",
+ "order" : 0.007,
+ "challenges": [
+ {
+ "_id": "ad7123c8c441eddfaeb5bdef",
+ "name": "Meet Bonfire",
+ "difficulty": "0",
+ "description": [
+ "Click the button below for further instructions.",
+ "Your goal is to fix the failing test.",
+ "First, run all the tests by clicking \"Run code\" or by pressing Control + Enter",
+ "The failing test is in red. Fix the code so that all tests pass. Then you can move on to the next Bonfire.",
+ "Make this function return true no matter what."
+ ],
+ "tests": [
+ "expect(meetBonfire()).to.be.a(\"boolean\");",
+ "expect(meetBonfire()).to.be.true;"
+ ],
+ "challengeSeed": [
+ "function meetBonfire(argument) {",
+ " // Good luck!",
+ " console.log(\"you can read this function's argument in the developer tools\", argument);",
+ "",
+ " return false;",
+ "}",
+ "",
+ "",
+ "",
+ "meetBonfire(\"You can do this!\");"
+ ]
+ },
+ {
+ "_id": "a202eed8fc186c8434cb6d61",
+ "name": "Reverse a String",
+ "difficulty": "1.01",
+ "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."
+ ],
+ "challengeSeed": [
+ "function reverseString(str) {",
+ " return str;",
+ "}",
+ "",
+ "reverseString('hello');"
+ ],
+ "MDNlinks": ["Global String Object", "String.split()", "Array.reverse()", "Array.join()"]
+ },
+ {
+ "_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.02",
+ "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) {",
+ " return num;",
+ "}",
+ "",
+ "factorialize(5);"
+ ],
+ "MDNlinks": ["Arithmetic Operators"]
+ },
+ {
+ "_id": "aaa48de84e1ecc7c742e1124",
+ "name": "Check for Palindromes",
+ "difficulty": "1.03",
+ "description": [
+ "Return true if the given string is a palindrome. Otherwise, return false.",
+ "A palindrome is a word or sentence that's spelled the same way both forward and backward, ignoring punctuation, case, and spacing.",
+ "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."
+ ],
+ "tests": [
+ "expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
+ "assert.deepEqual(palindrome(\"eye\"), true);",
+ "assert.deepEqual(palindrome(\"race car\"), true);",
+ "assert.deepEqual(palindrome(\"not a palindrome\"), false);",
+ "assert.deepEqual(palindrome(\"A man, a plan, a canal. Panama\"), true);",
+ "assert.deepEqual(palindrome(\"never odd or even\"), true);",
+ "assert.deepEqual(palindrome(\"nope\"), false);"
+ ],
+ "challengeSeed": [
+ "function palindrome(str) {",
+ " // Good luck!",
+ " return true;",
+ "}",
+ "",
+ "",
+ "",
+ "palindrome(\"eye\");"
+ ],
+ "MDNlinks": ["String.replace()", "String.toLowerCase()"]
+ },
+ {
+ "_id": "a26cbbe9ad8655a977e1ceb5",
+ "name": "Find the Longest Word in a String",
+ "difficulty": "1.04",
+ "description": [
+ "Return the length of the longest word in the provided sentence.",
+ "Your response should be a number."
+ ],
+ "challengeSeed": [
+ "function findLongestWord(str) {",
+ " return str.length;",
+ "}",
+ "",
+ "findLongestWord('The quick brown fox jumped over the lazy dog');"
+ ],
+ "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);"
+ ],
+ "MDNlinks": ["String.split()", "String.length"]
+ },
+ {
+ "_id": "ab6137d4e35944e21037b769",
+ "name": "Title Case a Sentence",
+ "difficulty": "1.05",
+ "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'."
+ ],
+ "challengeSeed": [
+ "function titleCase(str) {",
+ " return str;",
+ "}",
+ "",
+ "titleCase(\"I'm a little tea pot\");"
+ ],
+ "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\");"
+ ],
+ "MDNlinks": ["String.charAt()"]
+ },
+ {
+ "_id": "a789b3483989747d63b0e427",
+ "name": "Return Largest Numbers in Arrays",
+ "difficulty": "1.06",
+ "description": [
+ "Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.",
+ "Remember, you can iterate through an array with a simple for loop, and access each member with array syntax arr[i] .",
+ "If you are writing your own Chai.js tests, be sure to use a deep equal statement instead of an equal statement when comparing arrays."
+ ],
+ "challengeSeed": [
+ "function largestOfFour(arr) {",
+ " // You can do this!",
+ " return arr;",
+ "}",
+ "",
+ "largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);"
+ ],
+ "tests": [
+ "expect(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).to.be.a('array');",
+ "(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).should.eql([5,27,39,1001]);",
+ "assert(largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]).should.eql([9,35,97,1000000]));"
+ ],
+ "MDNlinks": ["Comparison Operators"]
+ },
+ {
+ "_id": "acda2fb1324d9b0fa741e6b5",
+ "name": "Confirm the Ending",
+ "difficulty": "1.07",
+ "description": [
+ "Check if a string (first argument) ends with the given target string (second argument)."
+ ],
+
+ "challengeSeed": [
+ "function end(str, target) {",
+ " // \"Never give up and good luck will find you.\"",
+ " // -- Falcor",
+ " return str;",
+ "}",
+ "",
+ "end('Bastian', 'n');"
+ ],
+ "tests": [
+ "assert.strictEqual(end('Bastian', 'n'), true, 'should equal true if target equals end of string');",
+ "assert.strictEqual(end('He has to give me a new name', 'name'), true, 'should equal true if target equals end of string');",
+ "assert.strictEqual(end('If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing', 'mountain'), false, 'should equal false if target does not equal end of string');"
+ ],
+ "MDNlinks": ["String.substr()"]
+ },
+ {
+ "_id": "afcc8d540bea9ea2669306b6",
+ "name": "Repeat a string repeat a string",
+ "difficulty": "1.08",
+ "description": [
+ "Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number."
+ ],
+ "challengeSeed": [
+ "function repeat(str, num) {",
+ " // repeat after me",
+ " return str;",
+ "}",
+ "",
+ "repeat('abc', 3);"
+ ],
+ "tests": [
+ "assert.strictEqual(repeat('*', 3), '***', 'should repeat a string n times');",
+ "assert.strictEqual(repeat('abc', 3), 'abcabcabc', 'should repeat a string n times');",
+ "assert.strictEqual(repeat('abc', -2), '', 'should return an empty string for negative numbers');"
+ ],
+ "MDNlinks": ["Global String Object"]
+ },
+ {
+ "_id": "ac6993d51946422351508a41",
+ "name": "Truncate a string",
+ "difficulty": "1.09",
+ "description": [
+ "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."
+ ],
+ "challengeSeed": [
+ "function truncate(str, num) {",
+ " // Clear out that junk in your trunk",
+ " return str;",
+ "}",
+ "",
+ "truncate('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');",
+ "assert.strictEqual(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2), 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is < length');"
+ ],
+ "MDNlinks": ["String.slice()"]
+ },
+ {
+ "_id": "a9bd25c716030ec90084d8a1",
+ "name": "Chunky Monkey",
+ "difficulty": "1.10",
+ "description": [
+ "Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a multidimensional array."
+ ],
+ "challengeSeed": [
+ "function chunk(arr, size) {",
+ " // Break it up.",
+ " return arr;",
+ "}",
+ "",
+ "chunk(['a', 'b', 'c', 'd'], 2);"
+ ],
+ "tests": [
+ "assert.deepEqual(chunk(['a', 'b', 'c', 'd'], 2), [['a', 'b'], ['c', 'd']], 'should return chunked arrays');",
+ "assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]], 'should return chunked arrays');",
+ "assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'should return the last chunk as remaining elements');"
+ ],
+ "MDNlinks": ["Array.push()"]
+ },
+ {
+ "_id": "ab31c21b530c0dafa9e241ee",
+ "name": "Slasher Flick",
+ "difficulty": "1.11",
+ "description": [
+ "Return the remaining elements of an array after chopping off n elements from the head."
+ ],
+ "challengeSeed": [
+ "function slasher(arr, howMany) {",
+ " // it doesn't always pay to be first",
+ " return arr;",
+ "}",
+ "",
+ "slasher([1, 2, 3], 2);"
+ ],
+ "tests": [
+ "assert.deepEqual(slasher([1, 2, 3], 2), [3], 'should drop the first two elements');",
+ "assert.deepEqual(slasher([1, 2, 3], 0), [1, 2, 3], 'should return all elements when n < 1');",
+ "assert.deepEqual(slasher([1, 2, 3], 9), [], 'should return an empty array when n >= array.length');"
+ ],
+ "MDNlinks": ["Array.slice()", "Array.splice()"]
+ },
+ {
+ "_id": "af2170cad53daa0770fabdea",
+ "name": "Mutations",
+ "difficulty": "1.12",
+ "description": [
+ "Return true if the string in the first element of the array contains the letters of the string in the second element of the array.",
+ "For example, ['hello', 'Hello'], should return true because all of the letters in the second string are present in the first, ignoring case.",
+ "The arguments ['hello', 'hey'] should return false because the string 'hello' does not contain a 'y'.",
+ "Another example, ['Alien', 'line'], should return true because all of the letters in 'line' are present in 'Alien'."
+ ],
+ "challengeSeed": [
+ "function mutation(arr) {",
+ " return arr;",
+ "}",
+ "",
+ "mutation(['hello', 'hey']);"
+ ],
+ "tests": [
+ "expect(mutation(['hello', 'hey'])).to.be.false;",
+ "expect(mutation(['hello', 'Hello'])).to.be.true;",
+ "expect(mutation(['zyxwvutsrqponmlkjihgfedcba', 'qrstu'])).to.be.true;",
+ "expect(mutation(['Mary', 'Army'])).to.be.true;",
+ "expect(mutation(['Alien', 'line'])).to.be.true;"
+ ],
+ "MDNlinks": ["Array.sort()"]
+ },
+ {
+ "_id": "adf08ec01beb4f99fc7a68f2",
+ "name": "Falsey Bouncer",
+ "difficulty": "1.50",
+ "description": [
+ "Remove all falsey values from an array.",
+ "Falsey values in javascript are false, null, 0, \"\", undefined, and NaN."
+ ],
+ "challengeSeed": [
+ "function bouncer(arr) {",
+ " // Don't show a false ID to this bouncer.",
+ " return arr;",
+ "}",
+ "",
+ "bouncer([7, 'ate', '', false, 9]);"
+ ],
+ "tests": [
+ "assert.deepEqual(bouncer([7, 'ate', '', false, 9]), [7, 'ate', 9], 'should remove falsey values');",
+ "assert.deepEqual(bouncer(['a', 'b', 'c']), ['a', 'b', 'c'], 'should return full array if no falsey elements');",
+ "assert.deepEqual(bouncer([false, null, 0]), [], 'should return empty array if all elements are falsey');"
+ ],
+ "MDNlinks": ["Boolean Objects", "Array.filter()"]
+ },
+ {
+ "_id":"a8e512fbe388ac2f9198f0fa",
+ "name":"Where art thou",
+ "difficulty":"1.55",
+ "description":[
+ "Make 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) {",
+ " var arr = [];",
+ " // What's in a name?",
+ " return arr;",
+ "}",
+ "",
+ "where([{ 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, 'b': 2 }], 'should return with multiples');"
+ ],
+ "MDNlinks": ["Global Object", "Object.hasOwnProperty()", "Object.keys()"]
+ },
+ {
+ "_id":"a39963a4c10bc8b4d4f06d7e",
+ "name":"Seek and Destroy",
+ "difficulty":"1.60",
+ "description":[
+ "You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments."
+ ],
+ "challengeSeed": [
+ "function destroyer(arr) {",
+ " // Remove all the values",
+ " return arr;",
+ "}",
+ "",
+ "destroyer([1, 2, 3, 1, 2, 3], 2, 3);"
+ ],
+ "tests": [
+ "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');"
+ ],
+ "MDNlinks": ["Arguments object","Array.filter()"]
+ },
+ {
+ "_id": "a24c1a4622e3c05097f71d67",
+ "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).",
+ "For example, where([1,2,3,4], 1.5) should return 1 because it is greater than 1 (0th index), but less than 2 (1st index)."
+ ],
+ "challengeSeed": [
+ "function where(arr, num) {",
+ " // Find my place in this sorted array.",
+ " return num;",
+ "}",
+ "",
+ "where([40, 60], 50);"
+ ],
+ "tests": [
+ "expect(where([10, 20, 30, 40, 50], 35)).to.equal(3);",
+ "expect(where([10, 20, 30, 40, 50], 30)).to.equal(2);"
+ ]
+ },
+ {
+ "_id": "a3566b1109230028080c9345",
+ "name": "Sum All Numbers in a Range",
+ "difficulty": "2.00",
+ "description": [
+ "We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
+ "The lowest number will not always come first."
+ ],
+ "challengeSeed": [
+ "function sumAll(arr) {",
+ " return(1);",
+ "}",
+ "",
+ "sumAll([1, 4]);"
+ ],
+ "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);"
+ ],
+ "MDNlinks": ["Math.max()", "Math.min()", "Array.reduce()"]
+ },
+ {
+ "_id": "a5de63ebea8dbee56860f4f2",
+ "name": "Diff Two Arrays",
+ "difficulty": "2.01",
+ "description": [
+ "Compare two arrays and return a new array with any items not found in both of the original arrays."
+ ],
+ "challengeSeed": [
+ "function diff(arr1, arr2) {",
+ " var newArr = [];",
+ " // Same, same; but different.",
+ " return newArr;",
+ "}",
+ "",
+ "diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);"
+ ],
+ "tests": [
+ "expect(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])).to.be.a('array');",
+ "assert.deepEqual(diff(['diorite', 'andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['pink wool'], 'arrays with only one difference');",
+ "assert.includeMembers(diff(['andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['diorite', 'pink wool'], 'arrays with more than one difference');",
+ "assert.deepEqual(diff(['andesite', 'grass', 'dirt', 'dead shrub'], ['andesite', 'grass', 'dirt', 'dead shrub']), [], 'arrays with no difference');",
+ "assert.deepEqual(diff([1, 2, 3, 5], [1, 2, 3, 4, 5]), [4], 'arrays with numbers');",
+ "assert.includeMembers(diff([1, 'calf', 3, 'piglet'], [1, 'calf', 3, 4]), ['piglet', 4], 'arrays with numbers and strings');",
+ "assert.deepEqual(diff([], ['snuffleupagus', 'cookie monster', 'elmo']), ['snuffleupagus', 'cookie monster', 'elmo'], 'empty array');"
+ ]
+ },
+ {
+ "_id": "a7f4d8f2483413a6ce226cac",
+ "name": "Roman Numeral Converter",
+ "tests": [
+ "expect(convert(12)).to.equal(\"XII\");",
+ "expect(convert(5)).to.equal(\"V\");",
+ "expect(convert(9)).to.equal(\"IX\");",
+ "expect(convert(29)).to.equal(\"XXIX\");",
+ "expect(convert(16)).to.equal(\"XVI\");"
+ ],
+ "difficulty": "2.02",
+ "description": [
+ "Convert the number be a roman numeral.",
+ "All roman numerals answers should be provided in upper-case."
+ ],
+ "challengeSeed": [
+ "function convert(num) {",
+ " return num;",
+ "}",
+ "",
+ "convert(36);"
+ ],
+ "MDNlinks": ["Array.splice()", "Array.indexOf()", "Array.join()"]
+ },
+ {
+ "_id": "a0b5010f579e69b815e7c5d6",
+ "name": "Search and Replace",
+ "tests": [
+ "expect(replace(\"Let us go to the store\", \"store\", \"mall\")).to.equal(\"Let us go to the mall\");",
+ "expect(replace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\")).to.equal(\"He is Sitting on the couch\");",
+ "expect(replace(\"This has a spellngi error\", \"spellngi\", \"spelling\")).to.equal(\"This has a spelling error\");",
+ "expect(replace(\"His name is Tom\", \"Tom\", \"john\")).to.equal(\"His name is John\");",
+ "expect(replace(\"Let us get back to more Coding\", \"Coding\", \"bonfires\")).to.equal(\"Let us get back to more Bonfires\");"
+ ],
+ "difficulty": "2.03",
+ "description": [
+ "Perform a search and replace on the sentence using the arguments provided and return the new sentence.",
+ "First argument is the sentence the perform the search and replace on.",
+ "Second argument is the word that you will be replacing (before).",
+ "Third argument is what you will be replacing the second argument with (after).",
+ "NOTE: Preserve the case of the original word when you are replacing it. For example if you mean to replace the word 'Book' with the word 'dog', it should be replaced as 'Dog'"
+ ],
+ "challengeSeed": [
+ "function replace(str, before, after) {",
+ " return str;",
+ "}",
+ "",
+ "replace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");"
+ ],
+ "MDNlinks": ["Array.splice()", "String.replace()", "Array.join()"]
+ },
+ {
+ "_id": "aa7697ea2477d1316795783b",
+ "name": "Pig Latin",
+ "tests": [
+ "expect(translate(\"california\")).to.equal(\"aliforniacay\");",
+ "expect(translate(\"paragraphs\")).to.equal(\"aragraphspay\");",
+ "expect(translate(\"glove\")).to.equal(\"oveglay\");",
+ "expect(translate(\"algorithm\")).to.equal(\"algorithmway\");",
+ "expect(translate(\"eight\")).to.equal(\"eightway\");"
+ ],
+ "difficulty": "2.04",
+ "description": [
+ "Translate the provided string to pig latin.",
+ "Pig Latin takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
+ "If a word begins with a vowel you just add \"way\" to the end."
+ ],
+ "challengeSeed": [
+ "function translate(str) {",
+ " return str;",
+ "}",
+ "",
+ "translate(\"consonant\");"
+ ],
+ "MDNlinks": ["Array.indexOf()", "Array.push()", "Array.join()", "String.substr()", "String.split()"]
+ },
+ {
+ "_id": "afd15382cdfb22c9efe8b7de",
+ "name": "DNA Pairing",
+ "tests": [
+ "assert.deepEqual(pair(\"ATCGA\"),[['A','T'],['T','A'],['C','G'],['G','C'],['A','T']], 'should return the dna pair');",
+ "assert.deepEqual(pair(\"TTGAG\"),[['T','A'],['T','A'],['G','C'],['A','T'],['G','C']], 'should return the dna pair');",
+ "assert.deepEqual(pair(\"CTCTA\"),[['C','G'],['T','A'],['C','G'],['T','A'],['A','T']], 'should return the dna pair');"
+ ],
+ "difficulty": "2.05",
+ "description": [
+ "The DNA strand is missing the pairing element. Match each character with the missing element and return the results as a 2d array.",
+ "Base pairs are a pair of AT and CG. Match the missing element to the provided character.",
+ "Return the provided character as the first element in each array."
+ ],
+ "challengeSeed": [
+ "function pair(str) {",
+ " return str;",
+ "}",
+ "",
+ "pair(\"GCG\");"
+ ],
+ "MDNlinks": ["Array.push()", "String.split()"]
+ },
+ {
+ "_id": "af7588ade1100bde429baf20",
+ "name" : "Missing letters",
+ "difficulty": "2.05",
+ "description" : [
+ "Find the missing letter in the passed letter range and return it.",
+ "If all letters are present in the range, return undefined."
+ ],
+ "challengeSeed": [
+ "function fearNotLetter(str) {",
+ " return str;",
+ "}",
+ "",
+ "fearNotLetter('abce');"
+ ],
+ "tests": [
+ "expect(fearNotLetter('abce')).to.equal('d');",
+ "expect(fearNotLetter('bcd')).to.be.undefined;",
+ "expect(fearNotLetter('abcdefghjklmno')).to.equal('i');",
+ "expect(fearNotLetter('yz')).to.be.undefined;"
+ ],
+ "MDNlinks": ["String.charCodeAt()"]
+ },
+ {
+ "_id": "a77dbc43c33f39daa4429b4f",
+ "name": "Boo who",
+ "difficulty": "2.06",
+ "description": [
+ "Check if a value is classified as a boolean primitive. Return true or false.",
+ "Boolean primitives are true and false."
+ ],
+ "challengeSeed": [
+ "function boo(bool) {",
+ " // What is the new fad diet for ghost developers? The Boolean.",
+ " return bool;",
+ "}",
+ "",
+ "boo(null);"
+ ],
+ "tests": [
+ "assert.strictEqual(boo(true), true);",
+ "assert.strictEqual(boo(false), true);",
+ "assert.strictEqual(boo([1, 2, 3]), false);",
+ "assert.strictEqual(boo([].slice), false);",
+ "assert.strictEqual(boo({ 'a': 1 }), false);",
+ "assert.strictEqual(boo(1), false);",
+ "assert.strictEqual(boo(NaN), false);",
+ "assert.strictEqual(boo('a'), false);"
+ ],
+ "MDNlinks": ["Boolean Objects"]
+ },
+ {
+ "_id": "a105e963526e7de52b219be9",
+ "name": "Sorted Union",
+ "difficulty": "2.07",
+ "description": [
+ "Write a function that takes two or more arrays and returns a new array of unique values in the order of the original provided arrays.",
+ "In other words, all values present from all arrays should be included in their original order, but with no duplicates in the final array.",
+ "The unique numbers should be sorted by their original order, but the final array should not be sorted in numerical order.",
+ "Check the assertion tests for examples."
+ ],
+ "challengeSeed": [
+ "function unite(arr1, arr2, arr3) {",
+ " return arr1;",
+ "}",
+ "",
+ "unite([1, 2, 3], [5, 2, 1, 4], [2, 1]);"
+ ],
+ "tests": [
+ "assert.deepEqual(unite([1, 3, 2], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4], 'should return the union of the given arrays');",
+ "assert.deepEqual(unite([1, 3, 2], [1, [5]], [2, [4]]), [1, 3, 2, [5], [4]], 'should not flatten nested arrays');"
+ ]
+ },
+ {
+ "_id": "a6b0bb188d873cb2c8729495",
+ "name": "Convert HTML Entities",
+ "difficulty": "2.07",
+ "description": [
+ "Convert the characters \"&\", \"<\", \">\", '\"', and \"'\", in a string to their corresponding HTML entities."
+ ],
+ "challengeSeed": [
+ "function convert(str) {",
+ " // :)",
+ " return str;",
+ "}",
+ "",
+ "convert('Dolce & Gabbana');"
+ ],
+ "tests": [
+ "assert.strictEqual(convert('Dolce & Gabbana'), 'Dolce & Gabbana', 'should escape characters');",
+ "assert.strictEqual(convert('abc'), 'abc', 'should handle strings with nothing to escape');"
+ ],
+ "MDNlinks": ["RegExp"]
+ },
+ {
+ "_id": "a103376db3ba46b2d50db289",
+ "name": "Spinal Tap Case",
+ "difficulty": "2.08",
+ "description": [
+ "Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes."
+ ],
+ "challengeSeed": [
+ "function spinalCase(str) {",
+ " // \"It's such a fine line between stupid, and clever.\"",
+ " // --David St. Hubbins",
+ " return str;",
+ "}",
+ "",
+ "spinalCase('This Is Spinal Tap');"
+ ],
+ "tests": [
+ "assert.strictEqual(spinalCase('This Is Spinal Tap'), 'this-is-spinal-tap', 'should return spinal case from string with spaces');",
+ "assert.strictEqual(spinalCase('thisIsSpinalTap'), 'this-is-spinal-tap', 'should return spinal case from string with camel case');",
+ "assert.strictEqual(spinalCase('The_Andy_Griffith_Show'), 'the-andy-griffith-show', 'should return spinal case from string with snake case');",
+ "assert.strictEqual(spinalCase('Teletubbies say Eh-oh'), 'teletubbies-say-eh-oh', 'should return spinal case from string with spaces and hyphens');"
+ ],
+ "MDNlinks": ["RegExp", "String.replace()"]
+ },
+ {
+ "_id": "a5229172f011153519423690",
+ "name": "Sum All Odd Fibonacci Numbers",
+ "difficulty": "2.09",
+ "description": [
+ "Return the sum of all odd Fibonacci numbers up to and including the passed number if it is a Fibonacci number.",
+ "The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers.",
+ "As an example, passing 4 to the function should return 5 because all the odd Fibonacci numbers under 4 are 1, 1, and 3."
+ ],
+ "challengeSeed": [
+ "function sumFibs(num) {",
+ " return num;",
+ "}",
+ "",
+ "sumFibs(4);"
+ ],
+ "tests": [
+ "expect(sumFibs(1)).to.be.a('number');",
+ "expect(sumFibs(1000)).to.equal(1785);",
+ "expect(sumFibs(4000000)).to.equal(4613732);",
+ "expect(sumFibs(4)).to.equal(5);",
+ "expect(sumFibs(75024)).to.equal(60696);",
+ "expect(sumFibs(75025)).to.equal(135721);"
+ ],
+ "MDNlinks": ["Remainder"]
+ },
+ {
+ "_id": "a3bfc1673c0526e06d3ac698",
+ "name": "Sum All Primes",
+ "difficulty": "2.10",
+ "description": [
+ "Sum all the prime numbers up to and including the provided number.",
+ "A prime number is defined as having only two divisors, 1 and itself. For example, 2 is a prime number because it's only divisible by 1 and 2. 1 isn't a prime number, because it's only divisible by itself.",
+ "The provided number may not be a prime."
+ ],
+ "challengeSeed": [
+ "function sumPrimes(num) {",
+ " return num;",
+ "}",
+ "",
+ "sumPrimes(10);"
+ ],
+ "tests": [
+ "expect(sumPrimes(10)).to.be.a('number');",
+ "expect(sumPrimes(10)).to.equal(17);",
+ "expect(sumPrimes(977)).to.equal(73156);"
+ ]
+ },
+ {
+ "_id": "ae9defd7acaf69703ab432ea",
+ "name": "Smallest Common Multiple",
+ "difficulty": "2.11",
+ "description": [
+ "Find the smallest number that is evenly divisible by all numbers in the provided range.",
+ "The range will be an array of two numbers that will not necessarily be in numerical order."
+ ],
+ "challengeSeed": [
+ "function smallestCommons(arr) {",
+ " return arr;",
+ "}",
+ "",
+ "",
+ "smallestCommons([1,5]);"
+ ],
+ "tests": [
+ "expect(smallestCommons([1,5])).to.be.a('number');",
+ "expect(smallestCommons([1,5])).to.equal(60);",
+ "expect(smallestCommons([5,1])).to.equal(60);",
+ "(smallestCommons([1,13])).should.equal(360360);"
+ ]
+ },
+ {
+ "_id": "a6e40f1041b06c996f7b2406",
+ "name": "Finders Keepers",
+ "difficulty": "2.12",
+ "description": [
+ "Create a function that looks through an array (first argument) and returns the first element in the array that passes a truth test (second argument)."
+ ],
+ "challengeSeed": [
+ "function find(arr, func) {",
+ " var num = 0;",
+ " return num;",
+ "}",
+ "",
+ "find([1, 2, 3, 4], function(num){ return num % 2 === 0; });"
+ ],
+ "tests": [
+ "assert.strictEqual(find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; }), 8, 'should return first found value');",
+ "assert.strictEqual(find([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'should return undefined if not found');"
+ ],
+ "MDNlinks": ["Array.some()"]
+ },
+ {
+ "_id": "a5deed1811a43193f9f1c841",
+ "name": "Drop it like it's hot",
+ "difficulty": "2.13",
+ "description": [
+ "Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true."
+ ],
+ "challengeSeed": [
+ "function drop(arr, func) {",
+ " // Drop them elements.",
+ " return arr;",
+ "}",
+ "",
+ "drop([1, 2, 3], function(n) {return n < 3; });"
+ ],
+ "tests": [
+ "expect(drop([1, 2, 3, 4], function(n) {return n >= 3; })).to.eqls([3, 4]);",
+ "expect(drop([1, 2, 3], function(n) {return n > 0; })).to.eqls([1, 2, 3]);",
+ "expect(drop([1, 2, 3, 4], function(n) {return n > 5; })).to.eqls([]);"
+ ],
+ "MDNlinks": ["Arguments object", "Array.shift()"]
+ },
+ {
+ "_id": "ab306dbdcc907c7ddfc30830",
+ "name": "Steamroller",
+ "difficulty": "2.14",
+ "description": [
+ "Flatten a nested array. You must account for varying levels of nesting."
+ ],
+ "challengeSeed": [
+ "function steamroller(arr) {",
+ " // I'm a steamroller, baby",
+ " return arr;",
+ "}",
+ "",
+ "steamroller([1, [2], [3, [[4]]]]);"
+ ],
+ "tests": [
+ "assert.deepEqual(steamroller([[['a']], [['b']]]), ['a', 'b'], 'should flatten nested arrays');",
+ "assert.deepEqual(steamroller([1, [2], [3, [[4]]]]), [1, 2, 3, 4], 'should flatten nested arrays');",
+ "assert.deepEqual(steamroller([1, [], [3, [[4]]]]), [1, 3, 4], 'should work with empty arrays');"
+ ],
+ "MDNlinks": ["Array.isArray()"]
+ },
+ {
+ "_id": "a8d97bd4c764e91f9d2bda01",
+ "name": "Binary Agents",
+ "difficulty": "2.15",
+ "description": [
+ "Return an English translated sentence of the passed binary string.",
+ "The binary string will be space separated."
+ ],
+ "challengeSeed": [
+ "function binaryAgent(str) {",
+ " return str;",
+ "}",
+ "",
+ "binaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111');"
+ ],
+ "tests": [
+ "expect(binaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111')).to.equal(\"Aren't bonfires fun!?\");",
+ "expect(binaryAgent('01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001')).to.equal(\"I love FreeCodeCamp!\");"
+ ],
+ "MDNlinks": ["String.charCodeAt()", "String.fromCharCode()"
+ ]
+ },
+ {
+ "_id" : "a3f503de51cfab748ff001aa",
+ "name": "Pairwise",
+ "difficulty": "2.16",
+ "description": [
+ "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
+ "For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7.",
+ "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!"
+ ],
+ "challengeSeed": [
+ "function pairwise(arr, arg) {",
+ " return arg;",
+ "}",
+ "",
+ "pairwise([1,4,2,3,0,5], 7);"
+ ],
+ "tests": [
+ "expect(pairwise([1, 4, 2, 3, 0, 5], 7)).to.equal(11);",
+ "expect(pairwise([1, 3, 2, 4], 4)).to.equal(1);",
+ "expect(pairwise([1,1,1], 2)).to.equal(1);",
+ "expect(pairwise([0, 0, 0, 0, 1, 1], 1)).to.equal(10);",
+ "expect(pairwise([], 100)).to.equal(0);"
+ ]
+ },
+ {
+ "_id": "a10d2431ad0c6a099a4b8b52",
+ "name": "Everything Be True",
+ "difficulty": "2.21",
+ "description": [
+ "Check if the predicate (second argument) returns truthy (defined) for all elements of a collection (first argument).",
+ "For this, check to see if the property defined in the second argument is present on every element of the collection.",
+ "Remember, you can access object properties through either dot notation or [] notation."
+ ],
+ "challengeSeed": [
+ "function every(collection, pre) {",
+ " // Does everyone have one of these?",
+ " return pre;",
+ "}",
+ "",
+ "every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex');"
+ ],
+ "tests": [
+ "assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex'), true, 'should return true if predicate returns truthy for all elements in the collection');",
+ "assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], {'sex': 'female'}), false, 'should return false if predicate returns falsey for any element in the collection');"
+ ],
+ "MDNlinks": ["Object.hasOwnProperty()", "Object.getOwnPropertyNames()"]
+ },
+ {
+ "_id": "a97fd23d9b809dac9921074f",
+ "name": "Arguments Optional",
+ "difficulty": "2.22",
+ "description": [
+ "Create a function that sums two arguments together. If only one argument is provided, return a function that expects one additional argument and will return the sum.",
+ "For example, add(2, 3) should return 5, and add(2) should return a function that is waiting for an argument so that var sum2And = add(2); return sum2And(3); // 5
",
+ "If either argument isn't a valid number, return undefined."
+ ],
+ "challengeSeed": [
+ "function add() {",
+ " return false;",
+ "}",
+ "",
+ "add(2,3);"
+ ],
+ "tests": [
+ "expect(add(2, 3)).to.equal(5);",
+ "expect(add(2)(3)).to.equal(5);",
+ "expect(add('http://bit.ly/IqT6zt')).to.be.undefined;",
+ "expect(add(2, '3')).to.be.undefined;",
+ "expect(add(2)([3])).to.be.undefined;"
+ ],
+ "MDNlinks": ["Global Function Object", "Arguments object"]
+ },
+ {
+ "_id": "a2f1d72d9b908d0bd72bb9f6",
+ "name": "Make a Person",
+ "difficulty": "3.12",
+ "description": [
+ "Fill in the object constructor with the methods specified in the tests.",
+ "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).",
+ "All functions that take an argument have an arity of 1, and the argument will be a string.",
+ "These methods must be the only available means for interacting with the object."
+ ],
+ "challengeSeed": [
+ "var Person = function(firstAndLast) {",
+ " return firstAndLast;",
+ "};",
+ "",
+ "var bob = new Person('Bob Ross');",
+ "bob.getFullName();"
+ ],
+ "tests": [
+ "expect(Object.keys(bob).length).to.eql(6);",
+ "expect(bob instanceof Person).to.be.true;",
+ "expect(bob.firstName).to.be.undefined();",
+ "expect(bob.lastName).to.be.undefined();",
+ "expect(bob.getFirstName()).to.eql('Bob');",
+ "expect(bob.getLastName()).to.eql('Ross');",
+ "expect(bob.getFullName()).to.eql('Bob Ross');",
+ "bob.setFirstName('Happy');",
+ "expect(bob.getFirstName()).to.eql('Happy');",
+ "bob.setLastName('Trees');",
+ "expect(bob.getLastName()).to.eql('Trees');",
+ "bob.setFullName('George Carlin');",
+ "expect(bob.getFullName()).to.eql('George Carlin');",
+ "bob.setFullName('Bob Ross');"
+ ],
+ "MDNlinks": ["Closures", "Details of the Object Model"]
+ },
+ {
+ "_id": "af4afb223120f7348cdfc9fd",
+ "name": "Map the Debris",
+ "difficulty": "3.50",
+ "description": [
+ "Return a new array that transforms the element's average altitude into their orbital periods.",
+ "The array will contain objects in the format {name: 'name', avgAlt: avgAlt}
.",
+ "You can read about orbital periods on wikipedia.",
+ "The values should be rounded to the nearest whole number. The body being orbited is Earth.",
+ "The radius of the earth is 6367.4447 kilometers, and the GM value of earth is 398600.4418"
+ ],
+ "challengeSeed": [
+ "function orbitalPeriod(arr) {",
+ " var GM = 398600.4418;",
+ " var earthRadius = 6367.4447;",
+ " return arr;",
+ "}",
+ "",
+ "orbitalPeriod([{name : \"sputkin\", avgAlt : 35873.5553}]);"
+ ],
+ "tests": [
+ "expect(orbitalPeriod([{name : \"sputkin\", avgAlt : 35873.5553}])).to.eqls([{name: \"sputkin\", orbitalPeriod: 86400}]);",
+ "expect(orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}])).to.eqls([{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}]);"
+ ],
+ "MDNlinks": ["Math.pow()"]
+ },
+ {
+ "_id": "aff0395860f5d3034dc0bfc9",
+ "name": "Validate US Telephone Numbers",
+ "difficulty": "4.01",
+ "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:",
+ "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 is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
+ ],
+ "tests": [
+ "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(\"1 456 789 4444\"), true);",
+ "assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);",
+ "assert.deepEqual(telephoneCheck(\"55555555\"), false);",
+ "assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
+ "assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"27576227382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
+ "assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
+ ],
+ "challengeSeed": [
+ "function telephoneCheck(str) {",
+ " // Good luck!",
+ " return true;",
+ "}",
+ "",
+ "",
+ "",
+ "telephoneCheck(\"555-555-5555\");"
+ ]
+ },
+ {
+ "_id": "a3f503de51cf954ede28891d",
+ "name": "Symmetric Difference",
+ "difficulty": "4.02",
+ "description": [
+ "Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.",
+ "The mathematical term symmetric difference refers to the elements in two sets that are in either the first or second set, but not in both."
+ ],
+ "challengeSeed": [
+ "function sym(args) {",
+ " return arguments;",
+ "}",
+ "",
+ "sym([1, 2, 3], [5, 2, 1, 4]);"
+ ],
+ "tests": [
+ "expect(sym([1, 2, 3], [5, 2, 1, 4])).to.eqls([3, 5, 4])",
+ "assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'should return the symmetric difference of the given arrays');",
+ "assert.deepEqual(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], 'should return an array of unique values');",
+ "assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');"
+ ]
+ },
+ {
+ "_id": "aa2e6f85cab2ab736c9a9b24",
+ "name": "Cash Register",
+ "difficulty": "4.03",
+ "description": [
+ "Design a cash register drawer function that accepts purchase price as the first argument, payment as the second argument, and cash-in-drawer (cid) as the third argument.", "cid is a 2d array listing available currency.", "Return the string \"Insufficient Funds\" if cash-in-drawer is less than the change due. Return the string \"Closed\" if cash-in-drawer is equal to the change due.", "Otherwise, return change in coin and bills, sorted in highest to lowest order."
+ ],
+ "challengeSeed": [
+ "function drawer(price, cash, cid) {",
+ " var change;",
+ " // Here is your change, ma'am.",
+ " return change;",
+ "}",
+ "",
+ "// Example cash-in-drawer array:",
+ "// [['PENNY', 1.01],",
+ "// ['NICKEL', 2.05],",
+ "// ['DIME', 3.10],",
+ "// ['QUARTER', 4.25],",
+ "// ['ONE', 90.00],",
+ "// ['FIVE', 55.00],",
+ "// ['TEN', 20.00],",
+ "// ['TWENTY', 60.00],",
+ "// ['ONE HUNDRED', 100.00]]",
+ "",
+ "drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);"
+ ],
+ "tests": [
+ "expect(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]])).to.be.a('array');",
+ "expect(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
+ "expect(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
+ "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]), [['QUARTER', 0.50]], 'return correct change');",
+ "assert.deepEqual(drawer(3.26, 100.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]), [['TWENTY', 60.00], ['TEN', 20.00], ['FIVE', 15], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');",
+ "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), 'Insufficient Funds', 'insufficient funds');",
+ "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), \"Closed\", 'cash-in-drawer equals change');"
+ ]
+ },
+ {
+ "_id": "a56138aff60341a09ed6c480",
+ "name": "Inventory Update",
+ "difficulty": "4.04",
+ "description": [
+ "Compare and update inventory stored in a 2d array against a second 2d array of a fresh delivery. Update current inventory item quantity, and if an item cannot be found, add the new item and quantity into the inventory array in alphabetical order."
+ ],
+ "challengeSeed": [
+ "function inventory(arr1, arr2) {",
+ " // All inventory must be accounted for or you're fired!",
+ " return arr1;",
+ "}",
+ "",
+ "// Example inventory lists",
+ "var curInv = [",
+ " [21, 'Bowling Ball'],",
+ " [2, 'Dirty Sock'],",
+ " [1, 'Hair Pin'],",
+ " [5, 'Microphone']",
+ "];",
+ "",
+ "var newInv = [",
+ " [2, 'Hair Pin'],",
+ " [3, 'Half-Eaten Apple'],",
+ " [67, 'Bowling Ball'],",
+ " [7, 'Toothpaste']",
+ "];",
+ "",
+ "inventory(curInv, newInv);"
+ ],
+ "tests": [
+ "expect(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']])).to.be.a('array');",
+ "assert.equal(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]).length, 6);",
+ "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[88, 'Bowling Ball'], [2, 'Dirty Sock'], [3, 'Hair Pin'], [3, 'Half-Eaten Apple'], [5, 'Microphone'], [7, 'Toothpaste']]);",
+ "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], []), [[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']]);",
+ "assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[67, 'Bowling Ball'], [2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [7, 'Toothpaste']]);",
+ "assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair Pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [0, 'Dirty Sock'], [1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [0, 'Microphone'], [1, 'Toothpaste']]);"
+ ]
+ },
+ {
+ "_id": "a7bf700cd123b9a54eef01d5",
+ "name": "No repeats please",
+ "difficulty": "4.05",
+ "description": [
+ "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
+ "For example, 'aab' should return 2 because it has 6 total permutations, but only 2 of them don't have the same letter (in this case 'a') repeating."
+ ],
+ "challengeSeed": [
+ "function permAlone(str) {",
+ " return str;",
+ "}",
+ "",
+ "permAlone('aab');"
+ ],
+ "tests": [
+ "expect(permAlone('aab')).to.be.a.number;",
+ "expect(permAlone('aab')).to.equal(2);",
+ "expect(permAlone('aaa')).to.equal(0);",
+ "expect(permAlone('aabb')).to.equal(8);",
+ "expect(permAlone('abcdefa')).to.equal(3600);",
+ "expect(permAlone('abfdefa')).to.equal(2640);",
+ "expect(permAlone('zzzzzzzz')).to.equal(0);"
+ ]
+ },
+ {
+ "_id": "a19f0fbe1872186acd434d5a",
+ "name": "Friendly Date Ranges",
+ "difficulty": "4.06",
+ "description": [
+ "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
+ "It must not show any redundant information in the date range.",
+ "For example, if the year and month are the same then only the day range should be displayed.",
+ "Secondly, if the starting year is the current year, and the ending year can be inferred by the reader, the year should be omitted.",
+ "Input date is formatted as YYYY-MM-DD"
+ ],
+ "challengeSeed": [
+ "function friendly(str) {",
+ " return str;",
+ "}",
+ "",
+ "friendly(['2015-07-01', '2015-07-04']);"
+ ],
+ "tests": [
+ "assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
+ "assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'one month apart can be inferred it is the next year');",
+ "assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);",
+ "assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th, 2016']);",
+ "assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
+ "assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
+ ],
+ "MDNlinks": ["String.split()", "String.substr()", "parseInt()"]
+ }
+ ]
+}
diff --git a/seed_data/challenges/bootstrap.json b/seed_data/challenges/bootstrap.json
new file mode 100644
index 0000000000..5c86dce808
--- /dev/null
+++ b/seed_data/challenges/bootstrap.json
@@ -0,0 +1,1575 @@
+{
+ "name": "Bootstrap",
+ "order" : 0.003,
+ "challenges": [
+ {
+ "_id": "bad87fee1348bd9acde08812",
+ "name": "Use Bootstrap for Responsive Images",
+ "difficulty": 0.047,
+ "description": [
+ "Add a new image with the src
attribute of \"http://bit.ly/fcc-kittens2\", and add the img-responsive
Bootstrap class to the image.",
+ "Specifying a width of 200 pixels on our img element made it fit our phone's screen, but it's not a perfect fit. It would be great if the image could be exactly the width of our phone's screen.",
+ "Fortunately, there's a Responsive CSS Framework
called written by Twitter called Bootstrap. You can add Bootstrap to any app just by including it with <link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css'/>
at the top of your HTML, but we've gone ahead and included it for you here.",
+ "Bootstrap will figure out how wide your screen is and respond by resizing your HTML elements - hence the name Responsive Design
.",
+ "Now all you need to do is add the img-responsive
class to your image."
+ ],
+ "tests": [
+ "assert($('img').hasClass('img-responsive'), 'Your new image should have the class \"img-responsive\"')",
+ "assert($('img').length > 1, 'You should add an image with the src of \"http://bit.ly/fcc-kittens2\"')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd8acde08812",
+ "name": "Center Text with Bootstrap",
+ "difficulty": 0.048,
+ "description": [
+ "Add Bootstrap's text-center
class to your h2 element.",
+ "Now that we're using Bootstrap, we can center our heading elements (h2) to make them look better. All we need to do is add the class text-center
to the h1 and h2 elements.",
+ "Note that you can add several classes to the same element by separating each of them with a space, like this: <h2 class=\"text-red text-center\">your text</h2>
."
+ ],
+ "tests": [
+ "assert($('h2').hasClass('text-center'), 'Your h2 element should be centered by applying the class \"text-center\"')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348cd8acdf08812",
+ "name": "Create a Bootstrap Button",
+ "difficulty": 0.049,
+ "description": [
+ "Create a new button below your large kitten photo with the class \"btn\" and the text of \"like this photo\".",
+ "Bootstrap has its own button styles, which look much better than the plain HTML ones."
+ ],
+ "tests": [
+ "assert($('.btn').length > 0, 'your new button should have the class \"btn\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348cd8acef08812",
+ "name": "Create a Block Element Bootstrap Button",
+ "difficulty": 0.050,
+ "description": [
+ "Add Bootstrap's btn-block
class to your Bootstrap button.",
+ "Normally, your buttons are only as wide as the text they contain. By making them block elements
, your button will stretch to fill your page's entire horizontal space.",
+ "Note that these buttons still need the btn
class."
+ ],
+ "tests": [
+ "assert($('.btn-block').length > 0, 'your new button should have the class \"btn-block\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348cd8acef08811",
+ "name": "Color a Bootstrap Button with Button Primary",
+ "difficulty": 0.051,
+ "description": [
+ "Add Bootstrap's btn-block
class to both of your buttons.",
+ "Normally, your buttons are only as wide as the text they contain. By making them block elements
, your button will stretch to fill your page's entire horizontal space.",
+ "Note that these buttons still need the btn
class."
+ ],
+ "tests": [
+ "assert($('.btn-primary').length > 0, 'your new button should have the class \"btn-primary\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348cd8acef08813",
+ "name": "Color a Bootstrap Button with Button Info",
+ "difficulty": 0.052,
+ "description": [
+ "Create a new block-level Bootstrap button below your \"like\" button with the text \"Info\", and add Bootstrap's btn-info
class to it.",
+ "Bootstrap comes with several pre-defined colors for buttons. The btn-primary
class is the main button color you'll use throughout your app.",
+ "Note that these buttons still need the btn
and btn-block
classes."
+ ],
+ "tests": [
+ "assert($('.btn-info').length > 0, 'your new button should have the class \"btn-info\".')",
+ "assert($('.btn-block').length > 1, 'Both of your Bootstrap buttons should have the class \"btn-block\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348ce8acef08814",
+ "name": "Warn your Users of a Dangerous Action with the Bootstrap Button Danger Class",
+ "difficulty": 0.053,
+ "description": [
+ "Create a button with the text \"delete\" and give it the class btn-danger
.",
+ "Bootstrap comes with several pre-defined colors for buttons. The btn-danger
class is the button color you'll use to notify users that the button performs a destructive action, such as deleting a cat photo.",
+ "Note that this button still needs the btn
and btn-block
classes."
+ ],
+ "tests": [
+ "assert($('.btn-danger').length > 0, 'Your new button should have the class \"btn-danger\".')",
+ "assert($('.btn-block').length > 1, 'Both of your Bootstrap buttons should have the class \"btn-block\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad88fee1348ce8acef08815",
+ "name": "Use the Bootstrap Grid to Put Elements Side By Side",
+ "difficulty": 0.054,
+ "description": [
+ "Put the \"like\", \"Info\" and \"Delete\" buttons side-by-side by wrapping them in both in a <div class=\"row\">
element and each of them in a <div class=\"col-xs-4\">
element.",
+ "Bootstrap uses a responsive grid system, which makes it easy to put elements into rows and specify each element's relative width. Most of Bootstrap's classes can be applied to a div
element.",
+ "The row
class is applied to a div
, and the buttons themselves can be nested
within it."
+ ],
+ "tests": [
+ "assert($('.row').length > 0, 'Your new button should be wrapped within a div with the class \"row\".')",
+ "assert($('.col-xs-4').length > 2, 'Each of your bootstrap buttons should be wrapped in a div with the class \"col-xs-4\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedf08845",
+ "name": "Use Bootstrap Text Primary Class instead of Custom CSS",
+ "difficulty" : 0.055,
+ "description": [
+ "Delete the following from your style tag: .red-text
, p
, .smaller-image
. Delete the p
element with the dead link. Remove your red-text
class from your h2
element and instead apply the text-primary
Bootstrap class. Replace the smaller-image
class on your top image with the img-responsive
class."
+ ],
+ "tests": [
+ "assert(!$('h2').hasClass('red-text'), 'You h2 element should no longer have the class \"red-text\".')",
+ "assert($('h2').hasClass('text-primary'), 'You h2 element should now have the class \"text-primary\".')",
+ "assert(!$('p').css('font-family').match(/monospace/i), 'Your paragraph elements should no longer use the font \"Monospace\".')",
+ "assert($('.img-responsive').length > 1, 'Remove the \"smaller-image\" class from your top image and replace it with the \"img-responsive\" class.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "Click here for cat photos.
",
+ "",
+ "
",
+ "",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aede08845",
+ "name": "Create a Custom Heading",
+ "difficulty" : 0.056,
+ "description": [
+ "Wrap your first image and your h2 element in a <div class='row'>
element. Wrap your h2 text in a <div class='col-xs-8'>
and your image in a <div class='col-xs-4'>
so that they are on the same line."
+ ],
+ "tests": [
+ "assert($('.row').length > 1, 'Your h2 and top image elements should both be wrapped together within a div with the class \"row\".')",
+ "assert($('.col-xs-4').length > 3, 'Wrap your top image inside a div with the class \"col-xs-4\".')",
+ "assert($('.col-xs-8').length > 0, 'Wrap your h2 element inside a div with the class \"col-xs-8\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "CatPhotoApp
",
+ "",
+ "
",
+ "",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedd08845",
+ "name": "Add Font Awesome Icons to our Buttons",
+ "difficulty" : 0.057,
+ "description": [
+ "Use Font Awesome to add a \"like\" icon to your like button.",
+ "You should add a <i class=\"fa fa-thumbs-up\">
within your like button's element."
+ ],
+ "tests": [
+ "assert($('.fa-thumbs-up').length > 0, 'You should add a <i class=\"fa fa-thumbs-up\"><i>
within your like button element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedc08845",
+ "name": "Add Font Awesome Icons all of our Buttons",
+ "difficulty" : 0.058,
+ "description": [
+ "Use Font Awesome to add a \"info-circle\" icon to your info button and a \"trash\" button to your delete button.",
+ "You should add a <i class=\"fa fa-thumbs-up\">
within your like button's element."
+ ],
+ "tests": [
+ "assert($('.fa-trash').length > 0, 'You should add a <i class=\"fa fa-trash\"><i>
within your like button element.')",
+ "assert($('.fa-info-circle').length > 0, 'You should add a <i class=\"fa fa-info-circle\"><i>
within your like button element.')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aedb08845",
+ "name": "Use Bootstrap to Responsively Style a Radio Buttons",
+ "difficulty" : 0.059,
+ "description": [
+ "Wrap all of your radio buttons in a <div class='row'>
element. Then wrap each of them in a <div class='col-xs-6'>
element."
+ ],
+ "tests": [
+ "assert($('.row').length > 2, 'Wrap your all of your radio buttons inside one div with the class \"row\".')",
+ "assert($('.col-xs-6').length > 3, 'Wrap each of your radio buttons inside its own div with the class \"col-xs-6\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aeda08845",
+ "name": "Use Bootstrap to Responsively Style Checkboxes",
+ "difficulty" : 0.060,
+ "description": [
+ "Wrap all your checkboxes in a <div class='row'>
element. Then wrap each of them in a <div class='col-xs-4'>
element."
+ ],
+ "tests": [
+ "assert($('.row').length > 3, 'Wrap your all of your checkboxes inside one div with the class \"row\".')",
+ "assert($('.col-xs-4').length > 6, 'Wrap each of your checkboxes inside its own div with the class \"col-xs-4\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aed908845",
+ "name": "Style a Text Input with the Bootstrap Form Control Class",
+ "difficulty" : 0.061,
+ "description": [
+ "Give your form's text input field in a class of \"form-control\". Give your form's submit button the classes \"btn btn-primary\" and give it the Font Awesome icon of \"fa-paper-plane\"."
+ ],
+ "tests": [
+ "assert($('.btn-primary').length > 1, 'Give your form's submit button the classes \"btn btn-primary\".')",
+ "assert($('.fa-paper-plane').length > 0, 'You should add a <i class=\"fa fa-paper-plane\"><i>
within your submit button element.')",
+ "assert($('.form-control').length > 0, 'Give your form's text input field in a class of \"form-control\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id" : "bad87fee1348bd9aec908845",
+ "name": "Line up Form Elements Responsively with Bootstrap",
+ "difficulty" : 0.062,
+ "description": [
+ "Wrap both your form's text input field and submit button within a div with the class \"row\". Wrap your form's text input field within a div with the class of \"col-xs-7\". Wrap your form's submit button the in a div with the class \"col-xs-5\"."
+ ],
+ "tests": [
+ "assert($('.row').length > 4, 'Wrap your all of your checkboxes inside one div with the class \"row\".')",
+ "assert($('.col-xs-5').length > 0, 'Wrap each of your checkboxes inside its own div with the class \"col-xs-4\".')",
+ "assert($('.col-xs-7').length > 0, 'Wrap each of your checkboxes inside its own div with the class \"col-xs-4\".')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "
",
+ "
",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "Things cats love:
",
+ "",
+ " - cat nip
",
+ " - laser pointers
",
+ " - lasagna
",
+ "
",
+ "Top 3 things cats hate:
",
+ "",
+ " - flea treatment
",
+ " - thunder
",
+ " - other cats
",
+ "
",
+ ""
+ ]
+ },
+
+ {
+ "_id": "bad88fee1348bd9aedf08825",
+ "name": "Adjusting the Padding of an Element",
+ "difficulty": 0.064,
+ "description": [
+ "Change the padding
of the green box to match that of the red box.",
+ "An element's padding
controls the amount of space between an element and its border
.",
+ "Here, we can see that the green box and the red box and the green box are nested within the yellow box. Note that the red box has more padding
than the green box.",
+ "When you increase the green box's padding, it will increase the distance between the word \"padding\" and the border around the text."
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('padding', '20px')"
+ ],
+ "challengeSeed": [
+ "",
+ "margin
",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08822",
+ "name": "Adjust the Margin of an Element",
+ "difficulty": 0.065,
+ "description": [
+ "Change the margin
of the green box to match that of the red box.",
+ "An element's margin
controls the amount of space between an element's border
and surrounding elements.",
+ "Here, we can see that the green box and the red box and the green box are nested within the yellow box. Note that the red box has more margin
than the green box, making it appear smaller.",
+ "When you increase the green box's padding, it will increase the distance between its border and surrounding elements."
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('margin', '20px')"
+ ],
+ "challengeSeed": [
+ "",
+ "margin
",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08823",
+ "name": "Add a Negative Margin to an Element",
+ "difficulty": 0.066,
+ "description": [
+ "Change the margin
of the green box to a negative value, so it fills the entire horizontal width of the blue box.",
+ "An element's margin
controls the amount of space between an element's border
and surrounding elements.",
+ "If you set an element's margin to a negative value, the element will grow larger.",
+ "Try to set the margin to a negative value like the one for the red box."
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('margin', '-15px')"
+ ],
+ "challengeSeed": [
+ "",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08824",
+ "name": "Add Different Padding to Each Side of an Element TEST",
+ "difficulty": 0.067,
+ "description": [
+ "Give the green box a padding of 40 pixels on its top and left side, but only 20 pixels on its bottom and right side.",
+ "Sometimes you will want to customize an element so that it has different padding on each of its sides.",
+ "CSS allows you to control the padding of an element on all four sides with padding-top
, padding-right
, padding-bottom
, and padding-left
attributes."
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('padding-bottom', '20px')",
+ "expect($('.green-box')).to.have.css('padding-left', '40px')"
+ ],
+ "challengeSeed": [
+ "",
+ "margin
",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1248bd9aedf08824",
+ "name": "Add Different a Margin to Each Side of an Element TEST",
+ "difficulty": 0.068,
+ "description": [
+ "Give the green box a margin of 40 pixels on its top and left side, but only 20 pixels on its bottom and right side.",
+ "Sometimes you will want to customize an element so that it has a different margin on each of its sides.",
+ "CSS allows you to control the margin of an element on all four sides with margin-top
, margin-right
, margin-bottom
, and margin-left
attributes."
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('margin-bottom', '20px')",
+ "expect($('.green-box')).to.have.css('margin-left', '40px')"
+ ],
+ "challengeSeed": [
+ "",
+ "margin
",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+ {
+ "_id": "bad87fee1348bd9aedf08826",
+ "name": "Use Clockwise Notation to Specify an Element's Padding",
+ "difficulty": 0.069,
+ "description": [
+ "Use Clockwise Notation
to give an element padding of 40 pixels on its top and left side, but only 20 pixels on its bottom and right side.",
+ "Instead of specifying an element's padding-top
, padding-right
, padding-bottom
, and padding-left
attributes, you can specify them all in one line, like this: padding: 10px 20px 10px 20px;
.",
+ "These four values work like a clock: top, right, bottom, left, and will produce the exact same result as using the side-specific padding instructions.",
+ "You can also use this notation for margins!"
+ ],
+ "tests": [
+ "expect($('.green-box')).to.have.css('margin-bottom', '20px')",
+ "expect($('.green-box')).to.have.css('margin-left', '40px')"
+ ],
+ "challengeSeed": [
+ "",
+ "margin
",
+ "",
+ "",
+ " padding
",
+ " padding
",
+ ""
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aede08826",
+ "name": "Use Hex Codes for Precise Colors",
+ "difficulty": 0.070,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aedd08826",
+ "name": "Use Shortened Hex Codes for Colors",
+ "difficulty": 0.071,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ }
+ ]
+}
diff --git a/seed_data/challenges/computer-science.json b/seed_data/challenges/computer-science.json
new file mode 100644
index 0000000000..50c0b873a5
--- /dev/null
+++ b/seed_data/challenges/computer-science.json
@@ -0,0 +1,86 @@
+{
+ "name": "Computer Science",
+ "order" : 0.005,
+ "challenges": [
+ {
+ "_id": "bd7123d8c441eddfaeb5bdef",
+ "name": "Learn Basic Computer Science",
+ "difficulty": 0.90,
+ "challengeSeed": "114628241",
+ "description": [
+ "Stanford has an excellent free online Computer Science curriculum. This interactive course uses a modified version of JavaScript. It will cover a lot of concepts quickly.",
+ "Note that Harvard also has an excellent introduction to computer science course called CS50, but it takes more than 100 hours to complete, and doesn't use JavaScript.",
+ "Despite being completely self-paced, Stanford's CS101 course is broken up into weeks. Each of the following challenges will address one of those weeks.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z54/z1/ and complete the first week's course work."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd8124d8c441eddfaeb5bdef",
+ "name": "Learn Loops",
+ "difficulty": 0.19,
+ "challengeSeed": "114597348",
+ "description": [
+ "Now let's tackle week 2 of Stanford's Intro to Computer Science course.",
+ "This will introduce us to loops, a fundamental feature of every programming language.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z100/a7a70ce6e4724c58862ee6007284face/ and complete Week 2."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd8125d8c441eddfaeb5bdef",
+ "name": "Learn Computer Hardware",
+ "difficulty": 0.20,
+ "challengeSeed": "114597347",
+ "description": [
+ "Week 3 of Stanford's Intro to Computer Science covers computer hardware and explains Moore's law of exponential growth in the price-performance of processors.",
+ "This challenge will also give you an understanding of how bits and bytes work.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z143/z101/ and complete Week 3."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd8126d8c441eddfaeb5bdef",
+ "name": "Learn Computer Networking",
+ "difficulty": 0.21,
+ "challengeSeed": "114604811",
+ "description": [
+ "Now that you've learned about computer hardware, it's time to learn about the software that runs on top of it.",
+ "Particularly important, you will learn about networks and TCP/IP - the protocol that powers the internet.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z187/z144/ and complete Week 4."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd8127d8c441eddfaeb5bdef",
+ "name": "Learn Boolean Logic",
+ "difficulty": 0.22,
+ "challengeSeed": "114604812",
+ "description": [
+ "Now we'll do some more table exercises and learn boolean logic.",
+ "We'll also learn the difference between digital data and analog data.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z208/z188/ and complete Week 5."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd8128d8c441eddfaeb5bdef",
+ "name": "Learn Computer Security",
+ "difficulty": 0.23,
+ "challengeSeed": "114604813",
+ "description": [
+ "We're almost done with Stanford's Introduction to Computer Science course!",
+ "We'll learn about one of the most important inventions of the 20th century - spreadsheets.",
+ "We'll also learn about Computer Security and some of the more common vulnerabilities software systems have.",
+ "Go to https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z229/z213/ and complete Week 6, the final week of the course."
+ ],
+ "challengeType": 2,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/challenges/full-stack-javascript.json b/seed_data/challenges/full-stack-javascript.json
new file mode 100644
index 0000000000..c1491ce793
--- /dev/null
+++ b/seed_data/challenges/full-stack-javascript.json
@@ -0,0 +1,155 @@
+{
+ "name": "Full Stack JavaScript",
+ "order" : 0.008,
+ "challenges": [
+ {
+ "_id": "bd7154d8c441eddfaeb5bdef",
+ "name": "Get Started with Angular.js",
+ "difficulty": 0.34,
+ "challengeSeed": "114684726",
+ "description": [
+ "Code School has a short, free Angular.js course. This will give us a quick tour of Angular.js's mechanics and features.",
+ "In this course, we'll build a virtual shop entirely in Angular.js.",
+ "Go to http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/1/section/1/video/1 and complete the section."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7155d8c441eddfaeb5bdef",
+ "name": "Apply Angular.js Directives",
+ "difficulty": 0.35,
+ "challengeSeed": "114684727",
+ "description": [
+ "Directives serve as markers in your HTML. When Angular.js compiles your HTML, it will can alter the behavior of DOM elements based on the directives you've used.",
+ "Let's learn how these powerful directives work, and how to use them to make your web apps more dynamic",
+ "Go to http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/2/section/1/video/1 and complete the section."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7156d8c441eddfaeb5bdef",
+ "name": "Power Forms with Angular.js",
+ "difficulty": 0.36,
+ "challengeSeed": "114684729",
+ "description": [
+ "One area where Angular.js really shines is its powerful web forms.",
+ "Learn how to create reactive Angular.js forms, including real-time form validation.",
+ "Go to http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/3/section/1/video/1 and complete the section."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7157d8c441eddfaeb5bdef",
+ "name": "Customize Angular.js Directives",
+ "difficulty": 0.37,
+ "challengeSeed": "114685062",
+ "description": [
+ "Now we'll learn how to modify existing Angular.js directives, and even build directives of your own.",
+ "Go to http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/4/section/1/video/1 and complete the section."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c441eddfaeb5bdef",
+ "name": "Create Angular.js Services",
+ "difficulty": 0.38,
+ "challengeSeed": "114685060",
+ "description": [
+ "Services are functions that you can use and reuse throughout your Angular.js app to get things done.",
+ "We'll learn how to use services in this final Code School Angular.js challenge.",
+ "Go to http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/5/section/1/video/1 and complete the section."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7153d8c441eddfaeb5bd0f",
+ "name": "Manage Packages with NPM",
+ "difficulty": 0.39,
+ "challengeSeed": "126433450",
+ "description": [
+ "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
+ "If you don't already have Cloud 9 account, create one now at http://c9.io.",
+ "Open up http://c9.io and sign in to your account.",
+ "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
+ "Give your workspace a name.",
+ "Choose Node.js in the selection area below the name field",
+ "Click the Create button",
+ "Wait for the workspace to finish processing and select it on the left sidebar, below the Create New Workspace button",
+ "Click the \"Start Editing\" button.",
+ "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
+ "Run this command: sudo npm install how-to-npm -g
",
+ "Now start this tutorial by running how-to-npm
",
+ "Note that you can resize the c9.io's windows by dragging their borders.",
+ "Follow the directions and work through all of the the tutorial's steps before moving on."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7153d8c441eddfaeb5bdff",
+ "name": "Start a Node.js Server",
+ "difficulty": 0.40,
+ "challengeSeed": "126411561",
+ "description": [
+ "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
+ "If you don't already have Cloud 9 account, create one now at http://c9.io.",
+ "Open up http://c9.io and sign in to your account.",
+ "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
+ "Give your workspace a name.",
+ "Choose Node.js in the selection area below the name field",
+ "Click the Create button",
+ "Wait for the workspace to finish processing and select it on the left sidebar, below the Create New Workspace button",
+ "Click the \"Start Editing\" button.",
+ "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
+ "Run this command: sudo npm install learnyounode -g
",
+ "Now start this tutorial by running learnyounode
",
+ "Note that you can resize the c9.io's windows by dragging their borders.",
+ "Follow the directions and work through all of the the tutorial's steps before moving on."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7153d8c441eddfaeb5bd1f",
+ "name": "Build Web Apps with Express.js",
+ "difficulty": 0.41,
+ "challengeSeed": "126411559",
+ "description": [
+ "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
+ "If you don't already have Cloud 9 account, create one now at http://c9.io.",
+ "Open up http://c9.io and sign in to your account.",
+ "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
+ "Give your workspace a name.",
+ "Choose Node.js in the selection area below the name field",
+ "Click the Create button",
+ "Wait for the workspace to finish processing and select it on the left sidebar, below the Create New Workspace button",
+ "Click the \"Start Editing\" button.",
+ "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
+ "Run this command: git clone http://github.com/reddock/fcc_express && chmod 744 fcc_express/setup.sh && fcc_express/setup.sh && source ~/.profile
",
+ "Now start this tutorial by running expressworks
",
+ "Note that you can resize the c9.io's windows by dragging their borders.",
+ "Follow the directions and work through all of the the tutorial's steps before moving on."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7140d8c441eddfaeb5bdef",
+ "name": "Manage Source Code with Git",
+ "difficulty": 0.43,
+ "challengeSeed": "114635309",
+ "description": [
+ "Version Control Systems like Git ensure that, no matter how you experiment with your code, you can always roll back your app to a stable previous state.",
+ "Git is also a great way to share and contribute to open source software.",
+ "Go to https://www.codeschool.com/courses/try-git and complete this short interactive course."
+ ],
+ "challengeType": 2,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/challenges/getting-set-for-free-code-camp.json b/seed_data/challenges/getting-set-for-free-code-camp.json
new file mode 100644
index 0000000000..92c5cc6f8b
--- /dev/null
+++ b/seed_data/challenges/getting-set-for-free-code-camp.json
@@ -0,0 +1,146 @@
+{
+ "name": "Getting Set for Free Code Camp",
+ "order" : 0.001,
+ "challenges": [
+ {
+ "_id": "bd7124d8c441eddfaeb5bdef",
+ "name": "Learn how Free Code Camp Works",
+ "difficulty": 0.001,
+ "challengeSeed": "125407438",
+ "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 by building projects for nonprofits.",
+ "We built this community because learning to code is hard. But anyone who can stay motivated can learn to code. And to stay motivated, you just need to: - make friends with people who code
- code a little every day
",
+ "All our challenges are - free
- self-paced
- browser-based
",
+ "We'll spend - 200 hours learning tools like HTML, CSS, JavaScript, Node.js and databases
- 600 hours building practice projects
- 800 hours building full stack solutions for nonprofits
",
+ "By the end, we'll - be good at coding
- have the portfolio of apps with happy users to prove it
",
+ "Once 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.",
+ "Now it's time to join our chat room. Click the \"I've completed this challenge\" button to move on to your next challenge."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7125d8c441eddfaeb5bd0f",
+ "name": "Join Our Chat Room",
+ "difficulty": 0.002,
+ "challengeSeed": "124555254",
+ "description": [
+ "Now we're going to join the Free Code Camp chat room. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.",
+ "Make sure your Free Code Camp account includes your email address. Please note that the email address you use will be invisible to the public, but Slack will make it visible to other campers in our slack chat rooms. You can do this here: http://freecodecamp.com/account.",
+ "Click this link, which will email you an invite to Free Code Camp's Slack chat rooms: http://freecodecamp.com/api/slack.",
+ "Now check your email and click the link in the email from Slack.",
+ "Complete the sign up process, then update your biographical information and upload an image. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward.",
+ "Now enter the General chat room and introduce yourself to our chat room by typing: \"Hello world!\".",
+ "Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
+ "Keep the chat room open while you work through the other challenges. That way you ask for help if you get stuck on a challenge. You can also socialize when you feel like taking a break.",
+ "You can also access this chat room by clicking the \"Chat\" button in the upper right hand corner.",
+ "In order to keep our community a friendly and positive place to learn to code, please read and follow our Code of Conduct: http://freecodecamp.com/field-guide/what-is-the-free-code-camp-code-of-conduct?"
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7125d8c441eddfaeb5bdff",
+ "name": "Preview our Challenge Map",
+ "difficulty": 0.003,
+ "challengeSeed": "125407437",
+ "description": [
+ "Before you start learning how to code, we'd like to introduce you to a few things.",
+ "Let's look at our Challenge Map. Click on the \"Map\" button in the upper right hand corner. This map shows all the challenges that will teach you how to code.",
+ "You should complete all these challenges in order.",
+ "Once you finish these Waypoint challenges, you'll move on to Bonfires (algorithm practice), then Ziplines (front end development practice) and finally Basejumps (full stack development practice). After that, you'll start building projects for nonprofits.",
+ "This challenge map is just for your reference. When you return to FreeCodeCamp.com, we'll automatically redirect you to the next challenge that you should be doing."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7125d8c441eddfaeb5bd1f",
+ "name": "Browse our Field Guide",
+ "difficulty": 0.004,
+ "challengeSeed": "125407435",
+ "description": [
+ "Free Code Camp has an up-to-date field guide that will answer your many questions.",
+ "Click the \"Field Guide\" button in the upper right hand corner.",
+ "You can browse the field guide at your convenience. Most of its articles take less than 1 minute to read.",
+ "When you click the Field Guide button, it will always take you back to whichever article you were last reading.",
+ "Read a few field guide articles, then move on to your next challenge."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7125d8c441eddfaeb5bd2f",
+ "name": "Customize your Portfolio Page",
+ "difficulty": 0.005,
+ "challengeSeed": "125407433",
+ "description": [
+ "You and all your fellow campers have portfolio pages.",
+ "To see your portfolio page, click your picture in the upper right hand corner.",
+ "Your portfolio page will automatically show off your progress through Free Code Camp.",
+ "Click the \"Update my portfolio page or manage my account\" button",
+ "You can link to your Github, Twitter and LinkedIn accounts. If you've already built some websites, you can link to them here as well.",
+ "Be sure to click the \"Update my Bio\" or \"Update my Social Links\" button to save this new information to your portfolio page.",
+ "Once you're happy with your portfolio page, you can move on to your next challenge."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7126d8c441eddfaeb5bd3f",
+ "name": "Try Camper News",
+ "difficulty": 0.006,
+ "challengeSeed": "124553410",
+ "description": [
+ "Camper News is the best place for our campers to share and discuss helpful links.",
+ "Click \"News\" in the upper right hand corner.",
+ "You'll see a variety of links that have been submitted. Click on the \"Discuss\" button under one of them.",
+ "You can upvote links. This will push the link up the rankings of hot links.",
+ "You an also comment on a link. If someone responds to your comment, you'll get an email notification so you can come back and respond to them.",
+ "You can also submit links. You can modify the link's headline and also leave an initial comment about the link.",
+ "You can view the portfolio pages of any camper who has posted links or comments on Camper News. Just click on their photo.",
+ "When you submit a link, you'll get a point. You will also get a point each time someone upvotes your link.",
+ "Now that you've learned how to use Camper News, let's move on to your next challenge."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7126d8c441eddfaeb5bd3e",
+ "name": "Meet Other Campers in your City",
+ "difficulty": 0.007,
+ "challengeSeed": "127358841",
+ "description": [
+ "One of the best ways to stay motivated when learning to code is to hang out with other campers.",
+ "Slack and Camper News are great ways to communicate with other campers, but there's no substitute for meeting people in-person.",
+ "The easiest way to meet other campers in your city is to join your city's Facebook Group. Click here to view our growing list of local groups.",
+ "Click the link to your city, then, once Facebook loads, click \"Join group\".",
+ "Our local groups are new, so if you don't see your city on this list, you should follow the directions to create a Facebook group for your city.",
+ "If you don't have a Facebook account, we strongly recommend you create one, even if it's just for the purpose of coordinating with campers in your city through this group.",
+ "Our groups allow you to create events, coordinate those events, and share photos from the events afterward.",
+ "Whether you're hosting a study group, pair programming at your local library, or going to a weekend hackathon, your city's group will help you make it happen."
+ ],
+ "challengeType": 2,
+ "tests": []
+ },
+ {
+ "_id": "bd7137d8c441eddfaeb5bdef",
+ "name": "Get Help the Hacker Way with RSAP",
+ "difficulty": 0.008,
+ "challengeSeed": "125407432",
+ "description": [
+ "Let's cover one last thing before you start working through our lessons: how to get help.",
+ "Any time you get stuck or don't know what to do next, follow this simple algorithm (procedure): RSAP (Read, Search, Ask, Post).",
+ "First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.",
+ "Next, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.",
+ "Then, if you still haven't found an answer to your question, A - Ask your friends. If you have trouble, you can ask your fellow campers. We have a special chat room specifically for getting help with tools you learn through these Free Code Camp Challenges. Go to https://freecode.slack.com/messages/help/. Keep this chat open while you work on the remaining challenges.",
+ "Finally, P - Post on Stack Overflow. Before you attempt to do this, read Stack Overflow's guide to asking good questions: http://stackoverflow.com/help/how-to-ask.",
+ "Here's our detailed field guide on getting help: http://freecodecamp.com/field-guide/how-do-i-get-help-when-i-get-stuck.",
+ "Now you have a clear algorithm to follow when you need help! Let's start coding! Move on to your next challenge."
+ ],
+ "challengeType": 2,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/challenges/jquery-ajax-and-json.json b/seed_data/challenges/jquery-ajax-and-json.json
new file mode 100644
index 0000000000..8a51f9ddbb
--- /dev/null
+++ b/seed_data/challenges/jquery-ajax-and-json.json
@@ -0,0 +1,283 @@
+{
+ "name": "jQuery Ajax and JSON",
+ "order" : 0.004,
+ "challenges": [
+ {
+ "_id": "bad87fee1348bd9acdd08826",
+ "name": "Learn how Script Tags and Document Ready Work",
+ "difficulty": 0.072,
+ "description": [
+ "Test"
+ ],
+ "tests": [
+ "assert($('#target').hasClass('disabled'), 'The button with the ID of \"target\" should continue to have the \"disabled\" class.')",
+ "assert(!!$('#target[disabled]'), 'Enable the button with the ID of \"target\" by using jQuery.')",
+ "expect($('#target')).to.exist()"
+ ],
+ "challengeSeed": [
+ "fccss",
+ " $(document).ready(function() {",
+ " $('#target').attr('disabled', true)",
+ " });",
+ "fcces",
+ ""
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aedc08826",
+ "name": "Target Elements by Selectors Using jQuery",
+ "difficulty": 0.073,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aedb08826",
+ "name": "Target Elements by Class Using jQuery",
+ "difficulty": 0.074,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aeda08826",
+ "name": "Target an element by ID Using jQuery",
+ "difficulty": 0.075,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed908826",
+ "name": "Change the CSS of an Element Using jQuery",
+ "difficulty": 0.076,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed808826",
+ "name": "Disable an Element Using jQuery",
+ "difficulty": 0.077,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed708826",
+ "name": "Remove an Element Using jQuery",
+ "difficulty": 0.078,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed608826",
+ "name": "Move an Element Using jQuery",
+ "difficulty": 0.079,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed508826",
+ "name": "Clone an Element Using jQuery",
+ "difficulty": 0.080,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed408826",
+ "name": "Animate an Element Using jQuery",
+ "difficulty": 0.081,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed308826",
+ "name": "Target the Parent of an Element Using jQuery",
+ "difficulty": 0.082,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed208826",
+ "name": "Target the Children of an Element Using jQuery",
+ "difficulty": 0.083,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+
+ {
+ "_id": "bad87fee1348bd9aed108826",
+ "name": "Target a Specific Child of an Element Using jQuery",
+ "difficulty": 0.084,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aed008826",
+ "name": "Target Even Numbered Elements Using jQuery",
+ "difficulty": 0.085,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aecc08826",
+ "name": "Read Data from an Element Using jQuery",
+ "difficulty": 0.086,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9aebc08826",
+ "name": "Get Data from an URL Using jQuery",
+ "difficulty": 0.087,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9ae9c08826",
+ "name": "Loop through JSON Data Using jQuery",
+ "difficulty": 0.089,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ },
+
+ {
+ "_id": "bad87fee1348bd9ae8c08826",
+ "name": "Setup Click Events Using jQuery",
+ "difficulty": 0.089,
+ "description": [
+
+ ],
+ "tests": [
+
+ ],
+ "challengeSeed": [
+
+ ]
+ }
+ ]
+}
diff --git a/seed_data/challenges/prepwork.json b/seed_data/challenges/prepwork.json
deleted file mode 100644
index 3049d6c31a..0000000000
--- a/seed_data/challenges/prepwork.json
+++ /dev/null
@@ -1,55 +0,0 @@
-[
- {
- "_id": "bd7124d8c441eddfaeb5bdef",
- "name": "Learn how Free Code Camp Works",
- "difficulty": 0.01,
- "challengeSeed": "125407438",
- "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 by building projects for nonprofits.",
- "We built this community because learning to code is hard. But anyone who can stay motivated can learn to code. And to stay motivated, you just need to: - make friends with people who code
- code a little every day
",
- "All our challenges are - free
- self-paced
- browser-based
",
- "We'll spend - 200 hours learning tools like HTML, CSS, JavaScript, Node.js and databases
- 600 hours building practice projects
- 800 hours building full stack solutions for nonprofits
",
- "By the end, we'll - be good at coding
- have the portfolio of apps with happy users to prove it
",
- "Once 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.",
- "Now it's time to join our chat room. Click the \"I've completed this challenge\" button to move on to your next challenge."
- ],
- "challengeType": 2,
- "tests": []
- },
- {
- "_id": "bd7125d8c441eddfaeb5bd0f",
- "name": "Join Our Chat Room",
- "difficulty": 0.02,
- "challengeSeed": "124555254",
- "description": [
- "Now we're going to join the Free Code Camp chat room. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.",
- "Make sure your Free Code Camp account includes your email address. You can do this here: http://freecodecamp.com/account.",
- "Click this link, which will email you an invite to Free Code Camp's Slack chat room: http://freecodecamp.com/api/slack.",
- "Now check your email and click the link in the email from Slack",
- "Complete the sign up process, then update your biographical information and upload an image. A picture of your face works best. This is how people will see you in the chat room, so put your best foot forward.",
- "Now enter the general chat room and introduce yourself to our chat room by typing: \"hello world!\".",
- "Note that you're expected to follow our Code of Conduct: http://freecodecamp.com/field-guide/what-is-the-free-code-camp-code-of-conduct?",
- "Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
- "Keep the chat room open while you work through the other challenges. That way you ask for help if you get stuck on a challenge. You can also socialize when you feel like taking a break.",
- "You can also access this chat room by clicking the \"Chat\" button in the upper right hand corner."
- ],
- "challengeType": 2,
- "tests": []
- },
- {
- "_id": "bd7125d8c441eddfaeb5bdff",
- "name": "Preview our Challenge Map",
- "difficulty": 0.03,
- "challengeSeed": "125407437",
- "description": [
- "Before you start learning how to code, we'd like to introduce you to a few things.",
- "Let's look at our Challenge Map. Click on the \"Map\" button in the upper right hand corner. This map shows all the challenges that will teach you how to code.",
- "You should complete all these challenges in order.",
- "Once you finish these Waypoint challenges, you'll move on to Bonfires (algorithm practice), then Ziplines (front end development practice) and finally Basejumps (full stack development practice). After that, you'll start building projects for nonprofits.",
- "This challenge map is just for your reference. When you return to FreeCodeCamp.com, we'll automatically redirect you to the next challenge that you should be doing."
- ],
- "challengeType": 2,
- "tests": []
- }
-]
\ No newline at end of file
diff --git a/seed_data/challenges/ziplines.json b/seed_data/challenges/ziplines.json
new file mode 100644
index 0000000000..ef23b63bea
--- /dev/null
+++ b/seed_data/challenges/ziplines.json
@@ -0,0 +1,197 @@
+{
+ "name": "Ziplines",
+ "order" : 0.009,
+ "challenges": [
+ {
+ "_id": "bd7158d8c442eddfbeb5bd1f",
+ "name": "Get Set for Ziplines",
+ "difficulty": 1.00,
+ "challengeSeed": "125658022",
+ "description": [
+ "Now you're ready to start our Zipline challenges. These front-end development challenges will give you many opportunities to apply the HTML, CSS, jQuery and JavaScript you've learned to build static (database-less) applications.",
+ "For many of these challenges, you will be using JSON data from external API endpoints, such as Twitch.tv and Twitter. Note that you don't need to have a database to use these data.",
+ "The easiest way to manipulate these data is with jQuery $.getJSON().",
+ "Whatever you do, don't get discouraged! Remember to use RSAP if you get stuck.",
+ "We'll build these challenges using CodePen, a popular tool for creating, sharing, and discovering static web applications.",
+ "Go to http://codepen.io and create an account.",
+ "Click your user image in the top right corner, then click the \"New pen\" button that drops down.",
+ "Drag the windows around and press the buttons in the lower-right hand corner to change the orientation to suit your preference.",
+ "Click the gear next to CSS. Then in the \"External CSS File or Another Pen\" text field, type \"bootstrap\" and scroll down until you see the latest version of Bootstrap. Click it.",
+ "Verify that bootstrap is active by adding the following code to your HTML: <h1 class='text-primary'>Hello CodePen!</h1>
. The text's color should be Bootstrap blue.",
+ "Click the gear next the JavaScript. Click the \"Latest version of...\" select box and choose jQuery.",
+ "Now add the following code to your JavaScript: $(document).ready(function() { $('.text-primary').text('Hi CodePen!') });
. Click the \"Save\" button at the top. Your \"Hello CodePen!\" should change to \"Hi CodePen!\". This means that jQuery is working.",
+ "Now you're ready for your first Zipline. Click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair."
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd1f",
+ "name": "Zipline: Use the Twitch.tv JSON API",
+ "difficulty": 1.01,
+ "challengeSeed": "126411564",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/GeoffStorbeck/full/GJKRxZ.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can see whether Free Code Camp is currently streaming on Twitch.tv.",
+ "User Story: As a user, I can click the status output and be sent directly to the Free Code Camp's Twitch.tv channel.",
+ "User Story: As a user, if Free Code Camp is streaming, I can see additional details about what they are streaming.",
+ "Bonus User Story: As a user, I can search through the streams listed.",
+ "Hint: Here's an example call to Twitch.tv's JSON API: https://api.twitch.tv/kraken/streams/freecodecamp
.",
+ "Hint: The relevant documentation about this API call is here: https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel.",
+ "Hint: Here's an array of the Twitch.tv usernames of people who regularly stream coding: [\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"comster404\",\"brunofin\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]
",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd13",
+ "name": "Zipline: Build a Random Quote Machine",
+ "difficulty": 1.02,
+ "challengeSeed": "126415122",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/AdventureBear/full/vEoVMw.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can click a button to show me a new random quote.",
+ "Bonus User Story: As a user, I can press a button to tweet out a quote.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd10",
+ "name": "Zipline: Show the Local Weather",
+ "difficulty": 1.03,
+ "challengeSeed": "126415127",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/AdventureBear/full/yNBJRj.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can see the weather in my current location.",
+ "Bonus User Story: As a user, I can see an icon depending on the temperature..",
+ "Bonus User Story: As a user, I see a different background image depending on the temperature (e.g. snowy mountain, hot desert).",
+ "Bonus User Story: As a user, I can push a button to toggle between Fahrenheit and Celsius.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd18",
+ "name": "Zipline: Stylize Stories on Camper News",
+ "difficulty": 1.04,
+ "challengeSeed": "126415129",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/GeoffStorbeck/full/Wveezv.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can browse recent posts from Camper News.",
+ "User Story: As a user, I can click on a post to be taken to the story's original URL.",
+ "User Story: As a user, I can click a link to go directly to the post's discussion page.",
+ "Bonus User Story: As a user, I can see how many upvotes each story has.",
+ "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/stories/hotStories
.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd19",
+ "name": "Zipline: Wikipedia Viewer",
+ "difficulty": 1.05,
+ "challengeSeed": "126415131",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/GeoffStorbeck/full/MwgQea.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.",
+ "Bonus User Story:As a user, I can click a button to see a random Wikipedia entry.",
+ "Bonus User Story:As a user, when I type in the search box, I can see a dropdown menu with autocomplete options for matching Wikipedia entries.",
+ "Hint: Here's an entry on using Wikipedia's API: http://www.mediawiki.org/wiki/API:Main_page
.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd0f",
+ "name": "Zipline: Build a Pomodoro Clock",
+ "difficulty": 1.06,
+ "challengeSeed": "126411567",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/GeoffStorbeck/full/RPbGxZ/.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can start a 25 minute pomodoro, and the timer will go off once 25 minutes has elapsed.",
+ "Bonus User Story: As a user, I can reset the clock for my next pomodoro.",
+ "Bonus User Story: As a user, I can customize the length of each pomodoro.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd17",
+ "name": "Zipline: Build a JavaScript Calculator",
+ "difficulty": 1.07,
+ "challengeSeed": "126411565",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/GeoffStorbeck/full/zxgaqw.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can add, subtract, multiply and divide two numbers.",
+ "Bonus User Story: I can clear the input field with a clear button.",
+ "Bonus User Story: I can keep chaining mathematical operations together until I hit the clear button, and the calculator will tell me the correct output.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ },
+ {
+ "_id": "bd7158d8c442eddfaeb5bd1c",
+ "name": "Zipline: Build a Tic Tac Toe Game",
+ "difficulty": 1.08,
+ "challengeSeed": "126415123",
+ "description": [
+ "Objective: Build a CodePen.io that successfully reverse-engineers this: http://codepen.io/alex-dixon/full/JogOpQ/.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: You may use whichever libraries or APIs you need.",
+ "Rule #3: Reverse engineer the example project's functionality, and also feel free to personalize it.",
+ "Here are the user stories you must enable, and optional bonus user stories:",
+ "User Story: As a user, I can play a game of Tic Tac Toe with the computer.",
+ "Bonus User Story: As a user, I can never actually win against the computer - at best I can tie.",
+ "Bonus User Story: As a user, my game will reset as soon as it's over so I can play again.",
+ "Bonus User Story: As a user, I can choose whether I want to play as X or O.",
+ "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
+ "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.
Click here then add your link to your tweet's text"
+ ],
+ "challengeType": 3,
+ "tests": []
+ }
+ ]
+}
diff --git a/seed_data/coursewares.json b/seed_data/coursewares.json
index c8a6bb102a..17f28bfac1 100644
--- a/seed_data/coursewares.json
+++ b/seed_data/coursewares.json
@@ -157,8 +157,7 @@
],
"challengeSeed": [
"Hello
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf0887a",
@@ -176,8 +175,7 @@
],
"challengeSeed": [
"Hello World
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08801",
@@ -194,8 +192,7 @@
"challengeSeed": [
"Hello World
",
"CatPhotoApp
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aeaf08801",
@@ -214,8 +211,7 @@
"Hello World
",
"CatPhotoApp
",
"Hello Paragraph
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08802",
@@ -242,8 +238,7 @@
"",
"Hello Paragraph
",
"-->"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08804",
@@ -269,8 +264,7 @@
"",
"Hello Paragraph
",
"-->"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08833",
@@ -294,8 +288,7 @@
"
",
"",
"Hello Paragraph
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fed1348bd9aedf08833",
@@ -320,8 +313,7 @@
"
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08803",
@@ -340,8 +332,7 @@
"CatPhotoApp
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08805",
@@ -364,8 +355,7 @@
"CatPhotoApp
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aecf08806",
@@ -395,8 +385,7 @@
"CatPhotoApp
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aefe08806",
@@ -422,8 +411,7 @@
"CatPhotoApp
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08806",
@@ -449,8 +437,7 @@
"CatPhotoApp
",
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aede08807",
@@ -479,8 +466,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08807",
@@ -512,8 +498,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08808",
@@ -551,8 +536,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08809",
@@ -593,8 +577,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
@@ -632,8 +615,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9acdf08812",
@@ -671,8 +653,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9bedf08813",
@@ -715,8 +696,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08814",
@@ -764,8 +744,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08815",
@@ -812,8 +791,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08816",
@@ -863,8 +841,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aede08817",
@@ -917,8 +894,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
@@ -970,8 +946,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08820",
@@ -1023,8 +998,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08818",
@@ -1076,8 +1050,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0
+ ]
},
{
@@ -1130,9 +1103,7 @@
"",
"Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.
",
"Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.
"
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1191,9 +1162,7 @@
" - laser pointers
",
" - lasagna
",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1254,9 +1223,7 @@
" - thunder
",
" - other cats
",
"
"
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1318,9 +1285,7 @@
" - other cats
",
"
",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1383,9 +1348,7 @@
" - other cats
",
"
",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1449,9 +1412,7 @@
"
"
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1517,9 +1478,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1589,9 +1548,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1659,9 +1616,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1730,9 +1685,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1804,9 +1757,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -1881,8 +1832,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd8acde08812",
@@ -1954,8 +1904,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
@@ -2027,8 +1976,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348cd8acef08812",
@@ -2101,8 +2049,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348cd8acef08811",
@@ -2175,8 +2122,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348cd8acef08813",
@@ -2250,8 +2196,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348ce8acef08814",
@@ -2326,8 +2271,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad88fee1348ce8acef08815",
@@ -2403,8 +2347,7 @@
" ",
" ",
""
- ],
- "challengeType": 0
+ ]
},
{
@@ -2490,9 +2433,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2563,9 +2504,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2639,9 +2578,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2716,9 +2653,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2792,9 +2727,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2875,9 +2808,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -2968,9 +2899,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -3061,9 +2990,7 @@
" ",
" ",
""
- ],
- "challengeType": 0,
- "completionMessage": ""
+ ]
},
{
@@ -3114,8 +3041,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08822",
@@ -3167,8 +3093,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08823",
@@ -3219,8 +3144,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08824",
@@ -3272,8 +3196,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1248bd9aedf08824",
@@ -3325,8 +3248,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
"_id": "bad87fee1348bd9aedf08826",
@@ -3375,8 +3297,7 @@
" padding
",
" padding
",
""
- ],
- "challengeType": 0
+ ]
},
{
@@ -3391,8 +3312,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3407,8 +3327,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3430,8 +3349,7 @@
" });",
"fcces",
""
- ],
- "challengeType": 0
+ ]
},
{
@@ -3446,8 +3364,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3462,8 +3379,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3478,8 +3394,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3494,8 +3409,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3510,8 +3424,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3526,8 +3439,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3542,8 +3454,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3558,8 +3469,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3574,8 +3484,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3590,8 +3499,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3606,8 +3514,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
@@ -3623,8 +3530,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3639,8 +3545,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3655,8 +3560,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3671,8 +3575,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3687,8 +3590,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{
@@ -3703,8 +3605,7 @@
],
"challengeSeed": [
- ],
- "challengeType": 0
+ ]
},
{