diff --git a/app.js b/app.js index 6d5ac7600a..3500428e0c 100644 --- a/app.js +++ b/app.js @@ -64,6 +64,7 @@ mongoose.connection.on('error', function () { * Express configuration. */ + app.set('port', process.env.PORT || 3000); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); @@ -106,6 +107,11 @@ app.disable('x-powered-by'); app.use(helmet.xssFilter()); app.use(helmet.noSniff()); app.use(helmet.xframe()); +app.use(function(req, res, next) { + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); + next(); +}); var trusted = [ "'self'", @@ -169,6 +175,7 @@ app.use(helmet.contentSecurityPolicy({ '*.vimeo.com', '*.twitter.com', '*.rafflecopter.com', + '*.ghbtns.com' ].concat(trusted), reportOnly: false, // set to true if you only want to report errors setAllHeaders: false, // set to true if you want to set all headers @@ -202,7 +209,9 @@ app.use( app.get('/', homeController.index); app.get('/privacy', resourcesController.privacy); app.get('/jquery-exercises', resourcesController.jqueryExercises); +app.get('/chat', resourcesController.chat); app.get('/live-pair-programming', resourcesController.livePairProgramming); +app.get('/install-screenhero', resourcesController.installScreenHero); app.get('/javascript-in-your-inbox', resourcesController.javaScriptInYourInbox); app.get('/chromebook', resourcesController.chromebook); app.get('/deploy-a-website', resourcesController.deployAWebsite); @@ -256,13 +265,30 @@ app.post( passportConf.isAuthenticated, userController.updateProgress ); + +/** + * Challenge related routes + */ +app.get( + '/challenges/', + challengesController.returnNextChallenge +); app.get( '/challenges/:challengeNumber', challengesController.returnChallenge ); + app.all('/account', passportConf.isAuthenticated); app.get('/account/api', userController.getAccountAngular); +/** + * API routes + */ + +app.get('/api/github', resourcesController.githubCalls); +app.get('/api/blogger', resourcesController.bloggerCalls); +app.get('/api/trello', resourcesController.trelloCalls); + /** * Bonfire related routes */ diff --git a/controllers/challenges.js b/controllers/challenges.js index 9de4496a4c..a0d3f3f52f 100644 --- a/controllers/challenges.js +++ b/controllers/challenges.js @@ -9,7 +9,27 @@ var _ = require('lodash'), var highestChallengeNumber = 53; -exports.returnChallenge = function(req, res, next) { + +exports.returnNextChallenge = function(req, res) { + if (req.user) { + ch = req.user.challengesHash; + if (req.user.challengesHash[0] > 0) { + var max = Object.keys(ch).reduce(function(max, key) { + return (max === undefined || ch[key] > ch[max]) ? +key : max; + }); + nextChallenge = max + 1; + res.redirect('challenges/' + nextChallenge); + } else { + res.redirect('challenges/0'); + } + } else { + res.render('home', { + title: 'Learn to Code and Become a Software Engineer', + }); + } +}; + +exports.returnChallenge = function(req, res) { var challengeNumber = parseInt(req.params.challengeNumber) || 0; if (challengeNumber > highestChallengeNumber) { req.flash('errors', { diff --git a/controllers/home.js b/controllers/home.js index 3105d1ea10..e2e752e423 100644 --- a/controllers/home.js +++ b/controllers/home.js @@ -5,20 +5,10 @@ exports.index = function(req, res) { if (req.user) { - ch = req.user.challengesHash; - if (req.user.challengesHash[0] > 0) { - var max = Object.keys(ch).reduce(function(max, key) { - return (max === undefined || ch[key] > ch[max]) ? +key : max; - }); - nextChallenge = max + 1; - res.redirect('challenges/' + nextChallenge); - } else { - res.redirect('challenges/0'); - } + res.redirect('/learn-to-code') } else { res.render('home', { - title: 'Learn to Code and Become a Software Engineer', - landingPage: true + title: 'Learn to Code and Become a Software Engineer' }); } }; diff --git a/controllers/resources.js b/controllers/resources.js index d0a5a458b9..99844a3095 100644 --- a/controllers/resources.js +++ b/controllers/resources.js @@ -55,6 +55,12 @@ module.exports = { }); }, + chat: function chat(req, res) { + res.render('resources/chat', { + title: "Enter Free Code Camp's Chat Rooms" + }); + }, + nonprofitProjectInstructions: function nonprofitProjectInstructions(req, res) { res.render('resources/nonprofit-project-instructions', { title: 'Nonprofit Project Instructions' @@ -91,63 +97,73 @@ module.exports = { }); }, + installScreenHero: function(req, res) { + res.render('resources/install-screenhero', { + title: 'Install ScreenHero' + }); + }, + javaScriptInYourInbox: function(req, res) { res.render('resources/javascript-in-your-inbox', { title: 'JavaScript in your Inbox' }); }, + githubCalls: function(req, res) { + var githubHeaders = {headers: {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1521.3 Safari/537.36'}, port:80 }; + client.get('https://api.github.com/repos/freecodecamp/freecodecamp/pulls?client_id=' + secrets.github.clientID + '&client_secret=' + secrets.github.clientSecret, githubHeaders, function(pulls, res3) { + pulls = pulls ? Object.keys(JSON.parse(pulls)).length : "Can't connect to github"; + client.get('https://api.github.com/repos/freecodecamp/freecodecamp/issues?client_id=' + secrets.github.clientID + '&client_secret=' + secrets.github.clientSecret, githubHeaders, function (issues, res4) { + issues = ((pulls === parseInt(pulls)) && issues) ? Object.keys(JSON.parse(issues)).length - pulls : "Can't connect to GitHub"; + res.send({"issues": issues, "pulls" : pulls}); + }); + }); + }, + trelloCalls: function(req, res) { + client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, res2) { + trello = trello ? (JSON.parse(trello)).length : "Can't connect to to Trello"; + res.send({"trello": trello}); + }); + }, + bloggerCalls: function(req, res) { + client.get('https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/posts?key=' + secrets.blogger.key, function (blog, res5) { + var blog = blog.length > 100 ? JSON.parse(blog) : ""; + res.send({ + blog1Title: blog ? blog["items"][0]["title"] : "Can't connect to Blogger", + blog1Link: blog ? blog["items"][0]["url"] : "http://blog.freecodecamp.com", + blog2Title: blog ? blog["items"][1]["title"] : "Can't connect to Blogger", + blog2Link: blog ? blog["items"][1]["url"] : "http://blog.freecodecamp.com", + blog3Title: blog ? blog["items"][2]["title"] : "Can't connect to Blogger", + blog3Link: blog ? blog["items"][2]["url"] : "http://blog.freecodecamp.com", + blog4Title: blog ? blog["items"][3]["title"] : "Can't connect to Blogger", + blog4Link: blog ? blog["items"][3]["url"] : "http://blog.freecodecamp.com", + blog5Title: blog ? blog["items"][4]["title"] : "Can't connect to Blogger", + blog5Link: blog ? blog["items"][4]["url"] : "http://blog.freecodecamp.com" + }); + }); + }, about: function(req, res) { var date1 = new Date("10/15/2014"); var date2 = new Date(); var timeDiff = Math.abs(date2.getTime() - date1.getTime()); var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24)); - client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, res2) { - client.get('https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/posts?key=' + secrets.blogger.key, function(blogger, res3) { - var nonprofitProjects = (JSON.parse(trello)).length || 27; - var blog = JSON.parse(blogger); - User.count({'points': {'$gt': 2}}, function (err, c3) { - if (err) { - debug('User err: ', err); - next(err); - } - User.count({'points': {'$gt': 9}}, function (err, c10) { - if (err) { - debug('User err: ', err); - next(err); - } - User.count({'points': {'$gt': 29}}, function (err, c30) { - if (err) { - debug('User err: ', err); - next(err); - } - User.count({'points': {'$gt': 53}}, function (err, all) { - if (err) { - debug('User err: ', err); - next(err); - } - res.render('resources/learn-to-code', { - title: 'About Free Code Camp and Our Team of Volunteers', - daysRunning: daysRunning, - nonprofitProjects: nonprofitProjects, - c3: c3, - c10: c10, - c30: c30, - all: all, - blog1Title: blog["items"][0]["title"], - blog1Link: blog["items"][0]["url"], - blog2Title: blog["items"][1]["title"], - blog2Link: blog["items"][1]["url"], - blog3Title: blog["items"][2]["title"], - blog3Link: blog["items"][2]["url"], - blog4Title: blog["items"][3]["title"], - blog4Link: blog["items"][3]["url"], - blog5Title: blog["items"][4]["title"], - blog5Link: blog["items"][4]["url"] - }); - }); - }); - }); + var announcements = resources.announcements; + User.count({}, function (err, c3) { + if (err) { + debug('User err: ', err); + next(err); + } + User.count({'points': {'$gt': 53}}, function (err, all) { + if (err) { + debug('User err: ', err); + next(err); + } + res.render('resources/learn-to-code', { + title: 'About Free Code Camp and Our Team of Volunteers', + daysRunning: daysRunning, + c3: c3, + all: all, + announcements: announcements }); }); }); diff --git a/controllers/resources.json b/controllers/resources.json index 1a7e038db6..c292aa8aca 100644 --- a/controllers/resources.json +++ b/controllers/resources.json @@ -1,4 +1,9 @@ { + "announcements": [ + ["Screen Hero is now free on Windows and Mac! Follow these special instructions to install it.", "http://freecodecamp.com/install-screenhero"], + ["Bonfire is now live with 30+ challenges! If you haven't started CoderByte, do these instead.", "http://freecodecamp.com/bonfires"], + ["Once you finish all the challenges, we welcome you to attend our Nonprofit Project Office Hours every Monday and Thursday Night at 9 pm EST.", "https://gitter.im/FreeCodeCamp/NonprofitProjects"] + ], "questions": [{ "question": "Time Complexity of Accessing Array Index (int a = ARR[5];)", "answer": "O(1)" diff --git a/public/css/lib/bootstrap/variables.less b/public/css/lib/bootstrap/variables.less index e6d916a76a..3de76507c7 100755 --- a/public/css/lib/bootstrap/variables.less +++ b/public/css/lib/bootstrap/variables.less @@ -717,9 +717,9 @@ @panel-success-border: @state-success-border; @panel-success-heading-bg: @state-success-bg; -@panel-info-text: @state-info-text; -@panel-info-border: @state-info-border; -@panel-info-heading-bg: @state-info-bg; +@panel-info-text: #eee; +@panel-info-border: darken(#4a2b0f, 5%); +@panel-info-heading-bg: #4a2b0f; @panel-warning-text: @state-warning-text; @panel-warning-border: @state-warning-border; diff --git a/public/css/main.less b/public/css/main.less index 50058c04f5..cf8b467ed8 100644 --- a/public/css/main.less +++ b/public/css/main.less @@ -374,6 +374,11 @@ ul { display: block; } +.next-challenge-button { + max-width: 1500px; + margin:0 auto; +} + .btn-big { font-size: 30px; } @@ -690,6 +695,19 @@ iframe.iphone { font-size: 0px; } +.stats-text { + font-size: 26px; + line-height: 150%; +} + +.github-and-twitter-button-text { + padding-top: 10px; +} + +.gitter-imbed { + height: 100%; + margin-bottom: 50px; +} //uncomment this to see the dimensions of all elements outlined in red //* { diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json index 9af6ce4be4..8b9b95f867 100644 --- a/seed_data/bonfires.json +++ b/seed_data/bonfires.json @@ -546,7 +546,7 @@ "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', 80.00], ['TEN', 10.00], ['FIVE', 5], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');", + "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');" ] @@ -558,14 +558,14 @@ "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!\r\n return arr1;\r\n}\n\n// Example inventory lists\r\nvar curInv = [\r\n [21, 'Bowling Ball'],\r\n [2, 'Dirty Sock'],\r\n [1, 'Hair pin'],\r\n [5, 'Microphone']\r\n];\r\n\r\nvar newInv = [\r\n [2, 'Hair Pin'],\r\n [3, 'Half-Eaten Apple'],\r\n [67, 'Bowling Ball'],\r\n [7, 'Toothpaste']\r\n];\r\n\r\ninventory(curInv, newInv);", + "challengeSeed": "function inventory(arr1, arr2) {\n // All inventory must be accounted for or you're fired!\r\n return arr1;\r\n}\n\n// Example inventory lists\r\nvar curInv = [\r\n [21, 'Bowling Ball'],\r\n [2, 'Dirty Sock'],\r\n [1, 'Hair Pin'],\r\n [5, 'Microphone']\r\n];\r\n\r\nvar newInv = [\r\n [2, 'Hair Pin'],\r\n [3, 'Half-Eaten Apple'],\r\n [67, 'Bowling Ball'],\r\n [7, 'Toothpaste']\r\n];\r\n\r\ninventory(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']]), [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [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'], [1, 'Dirty Sock'], [1, 'Hair pin'], [1, 'Half-Eaten Apple'], [1, 'Microphone'], [1, 'Toothpaste']]);" + "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']]);" ] } ] diff --git a/seed_data/challenges.json b/seed_data/challenges.json index 84cad0c051..7286158d48 100644 --- a/seed_data/challenges.json +++ b/seed_data/challenges.json @@ -400,7 +400,7 @@ "Try an intelligent Google query that involves JavaScript and filters for this year (since JavaScript changes).", "Go to http://stackoverflow.com/ and view the recent questions.", "Go to http://webchat.freenode.net/ and create an IRC account.", - "Join the #JavaScript chat room and introduce yourself as a Free Code Camp student.", + "Join the #LearnJavaScript chat room and introduce yourself as a Free Code Camp student.", "Finally, we have a special chat room specifically for getting help with tools you learn through Free Code Camp Challenges. Go to https://gitter.im/FreeCodeCamp/Help. Keep this chat open while you work on the remaining challenges.", "Now you have several ways of getting help when you're stuck." ] diff --git a/seed_data/coursewares.json b/seed_data/coursewares.json index 21454b1d0a..716f24acb2 100644 --- a/seed_data/coursewares.json +++ b/seed_data/coursewares.json @@ -1,45 +1,5 @@ [ - { - "_id" : "bd7123d8c441eddfaeb5bdef", - "name": "Learn how Free Code Camp Works", - "difficulty": 9.99, - "description": [ - "Watch this 90 second video, or simply read this summary:", - "Welcome to Free Code Camp. We're a community of busy people learning to code.", - "We built this community because learning to code is hard. But anyone who can stay motivated can learn to code. And the best way to stay motivated is to code with friends.", - "To maximize accessibility, all our challenges are self-paced, browser-based, and free.", - "All of us start with the same 100 hours of interactive coding challenges. These cover Computer Science and databases. They also cover in-demand JavaScript tools like jQuery, Node.js and MongoDB.", - "Once we have a basic understanding of web development, we'll spend another 900 hours putting that theory into practice. We'll build full stack solutions for nonprofits.", - "By the end of this process, we'll be good at coding. We'll have a portfolio of apps with happy users to prove it. We'll also have an alumni network of fellow coders and nonprofits ready to serve as references.", - "If you make it through Free Code Camp, you will be able to get a coding job. There are far more job openings out there than there are qualified coders to fill them.", - "Also, for every pure coding job, there are at least 5 additional jobs that require some coding skills. So even if you decide not to pursue coding as a career, you'll still walk away with a valuable job skill.", - "There are 3 keys to succeeding in our community: do the challenges, make friends, and find a routine.", - "Now it's time to join our chatroom. Click the \"Go to my next challenge\" button to move on to your next challenge." - ], - "tests": [ - "" - ], - "challengeSeed": [ - "114486344" - ], - "challengeType" : 2 - }, - { - "_id": "bd7123c8c441eddfaeb5bdef", - "name": "Meet Booleans", - "difficulty": "9.999", - "description": [ - "Return true" - ], - "tests": [ - "expect(welcomeToBooleans()).to.be.a(\"boolean\");", - "expect(welcomeToBooleans()).to.be.true;" - ], - "challengeSeed": [ - "function welcomeToBooleans() {\n // Good luck!\n return false;\n}\n\nwelcomeToBooleans();" - ], - "challengeType": 1 - }, + { "_id" : "bd7123c8c441eddfaeb5bdef", "name": "Start our Challenges", @@ -419,6 +379,36 @@ "challengeType": 0 }, + { + "_id" : "bad87fee1348bd9aedf08811", + "name": "Use rgb Codes for Precise Colors", + "difficulty" : "0.17", + "description": [ + "Change the red-text class's color rgb value to be red.", + "Another way to represent color in CSS is with rgb, or red-green-blue notation.", + "For each of the three colors, you specify a value between 0 and 256.", + "For example, black is rgb(0, 0, 0), white is rgb(255, 255, 255), bright green is rgb(0, 255, 0). You can also get less intense colors by using values lower than 255. For example, light green is rgb(0, 123, 0).", + "If you think about it, this is just as precise as using hex code, because 16 times 16 is 256. In practice, most developers use hex code since it's faster to say out loud and to type.", + "We'll use 6-digit hex code in all our challenges going forward, but it's good to be aware of this rgb notation." + ], + "tests": [ + "expect($('h2')).to.have.css('color', 'rgb(255, 0, 0)');", + "expect($('h2')).to.have.class('red-text');" + ], + "challengeSeed": [ + "", + "", + "

hello world

", + "

cat photo app

", + "

lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

" + ], + "challengeType": 0 + }, + { "_id" : "bad87fee1348bd9aedf08810", "name": "Use Hex Codes for Precise Colors", @@ -478,7 +468,7 @@ { "_id" : "bad87fee1348bd9aedf08811", - "name": "Use rgb Codes for Precise Colors", + "name": "Set the Alpha of a Color with rgba", "difficulty" : "0.17", "description": [ "Change the red-text class's color rgb value to be red.", @@ -1293,7 +1283,7 @@ }, { - "_id" : "bad87fee1348cd8acef08812", + "_id" : "bae87fee1348cd8acef08812", "name": "Color a Bootstrap Button with Button Primary", "difficulty" : "0.38", "description": [ @@ -1302,7 +1292,8 @@ "Note that these buttons still need the btn class." ], "tests": [ - "expect($('.btn-block').length).to.eql(2);" + "expect($('.btn-block').length).to.eql(2);", + "expect($('.btn-primary').length).to.eql(2);" ], "challengeSeed": [ "