Merge pull request #1 from FreeCodeCamp/staging

update
This commit is contained in:
Ben McMahon
2015-10-05 22:52:25 +01:00
98 changed files with 4118 additions and 2684 deletions

View File

@ -1,7 +1,7 @@
language: node_js language: node_js
services:
- mongodb
node_js: node_js:
- '0.10' - 'node'
- '1.6.4'
sudo: false

View File

@ -1,2 +1,12 @@
We're getting a lot of duplicate issues and bug reports that just aren't reporting actual bugs. We're getting a lot of duplicate issues and bug reports that just aren't reporting actual bugs.
So, before you submit your issue, please read the [Help I've Found a Bug](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Help-I've-Found-a-Bug) wiki page. So, before you submit your issue, please read the [Help I've Found a Bug](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Help-I've-Found-a-Bug) wiki page.
We welcome pull requests from Free Code Camp campers (our students) and seasoned JavaScript developers alike! Follow these steps to contribute:
1. Check our [public Waffle Board](https://waffle.io/freecodecamp/freecodecamp).
2. Pick an issue that nobody has claimed and start working on it. If your issue isn't on the board, open an issue. If you think you can fix it yourself, start working on it. Feel free to ask for help in our [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp).
3. Fork the project ([Need help with forking a project?](https://help.github.com/articles/fork-a-repo/)). You'll do all of your work on your forked copy.
4. Create a branch specific to the issue or feature you are working on. Push your work to that branch. ([Need help with branching?](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches))
5. Name the branch something like `fix/xxx` or `feature/xxx` where `xxx` is a short description of the changes or feature you are attempting to add. For example `fix/email-login` would be a branch where I fix something specific to email login.
6. You should have [ESLint running in your editor](http://eslint.org/docs/user-guide/integrations.html), and it will highlight anything doesn't conform to [Free Code Camp's JavaScript Style Guide](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Free-Code-Camp-JavaScript-Style-Guide) (you can find a summary of those rules [here](https://github.com/FreeCodeCamp/FreeCodeCamp/blob/staging/.eslintrc). Please do not ignore any linting errors, as they are meant to **help** you and to ensure a clean and simple code base. Make sure none of your JavaScript is longer than 80 characters per line.
7. Once your code is ready, submit a [pull request](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Pull-Request-Contribute) from your branch to Free Code Camp's `staging` branch. We'll do a quick code review and give you feedback, then iterate from there. It may also be helpful to read about git [rebasing](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/git-rebase).

View File

@ -1,4 +1,4 @@
<img src="https://s3.amazonaws.com/freecodecamp/wide-social-banner.png"> ![](https://s3.amazonaws.com/freecodecamp/wide-social-banner.png)
[![Throughput Graph](https://graphs.waffle.io/freecodecamp/freecodecamp/throughput.svg)](https://waffle.io/freecodecamp/freecodecamp/metrics) [![Throughput Graph](https://graphs.waffle.io/freecodecamp/freecodecamp/throughput.svg)](https://waffle.io/freecodecamp/freecodecamp/metrics)
@ -7,7 +7,7 @@
Welcome to Free Code Camp's open source codebase! Welcome to Free Code Camp's open source codebase!
======================= =======================
Free Code Camp is an open-source community of busy people who learn to code, then build projects for nonprofits. Free Code Camp is an open-source community of busy people who learn to code and build projects for nonprofits.
Our campers (students) start by working through our free, self-paced, browser-based curriculum. Next, they build several practice projects. Finally, we pair two campers together with a stakeholder from a nonprofit organization, and help them build the solution the nonprofit has requested. Our campers (students) start by working through our free, self-paced, browser-based curriculum. Next, they build several practice projects. Finally, we pair two campers together with a stakeholder from a nonprofit organization, and help them build the solution the nonprofit has requested.
@ -24,7 +24,7 @@ This code is running live at [FreeCodeCamp.com](http://www.FreeCodeCamp.com). We
Wiki Wiki
------------ ------------
We would love your help expanding our [wiki](https://github.com/freecodecamp/freecodecamp/wiki) with more information about learning to code and getting a coding job. We would love your help expanding our [wiki](https://github.com/freecodecamp/freecodecamp/wiki). Our goal is to become a great resource for people learning to code, building local coding communities, and applying for coding jobs.
Contributing Contributing
------------ ------------
@ -35,10 +35,9 @@ We welcome pull requests from Free Code Camp campers (our students) and seasoned
2. Pick an issue that nobody has claimed and start working on it. If your issue isn't on the board, open an issue. If you think you can fix it yourself, start working on it. Feel free to ask for help in our [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp). 2. Pick an issue that nobody has claimed and start working on it. If your issue isn't on the board, open an issue. If you think you can fix it yourself, start working on it. Feel free to ask for help in our [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp).
3. Fork the project ([Need help with forking a project?](https://help.github.com/articles/fork-a-repo/)). You'll do all of your work on your forked copy. 3. Fork the project ([Need help with forking a project?](https://help.github.com/articles/fork-a-repo/)). You'll do all of your work on your forked copy.
4. Create a branch specific to the issue or feature you are working on. Push your work to that branch. ([Need help with branching?](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches)) 4. Create a branch specific to the issue or feature you are working on. Push your work to that branch. ([Need help with branching?](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches))
5. Name the branch something like `user-xxx` where user is your username and xxx is the issue number you are addressing. 5. Name the branch something like `fix/xxx` or `feature/xxx` where `xxx` is a short description of the changes or feature you are attempting to add. For example `fix/email-login` would be a branch where I fix something specific to email login.
6. You should have [ESLint running in your editor](http://eslint.org/docs/user-guide/integrations.html), and it will highlight anything doesn't conform to [AirBnB's JavaScript Style Guide](https://github.com/airbnb/javascript). Please do not ignore any linting errors, as they are meant to **help** you. Make sure none of your JavaScript is longer than 80 characters per line. 6. You should have [ESLint running in your editor](http://eslint.org/docs/user-guide/integrations.html), and it will highlight anything doesn't conform to [Free Code Camp's JavaScript Style Guide](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Free-Code-Camp-JavaScript-Style-Guide) (you can find a summary of those rules [here](https://github.com/FreeCodeCamp/FreeCodeCamp/blob/staging/.eslintrc). Please do not ignore any linting errors, as they are meant to **help** you and to ensure a clean and simple code base. Make sure none of your JavaScript is longer than 80 characters per line.
7. Once your code is ready, submit a pull request from your branch to Free Code Camp's `staging` branch. We'll do a quick code review and give you feedback, then iterate from there. 7. Once your code is ready, submit a [pull request](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Pull-Request-Contribute) from your branch to Free Code Camp's `staging` branch. We'll do a quick code review and give you feedback, then iterate from there. It may also be helpful to read about git [rebasing](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/git-rebase).
8. Once we accept one of your pull requests, one of the project owners (currently @quincylarson, @terakilobyte, and @berkeleytrue) will add you to our camper contributor group.
Prerequisites Prerequisites
------------- -------------
@ -70,10 +69,9 @@ touch .env
npm install -g gulp npm install -g gulp
``` ```
Edit your .env file with the following API keys accordingly (if you only use email login, only the MONGOHQ_URL, SESSION_SECRET, MANDRILL_USER and MANDRILL_PASSWORD fields are necessary. Keep in mind if you want to use more services you'll have to get your own API keys for those services. Edit your `.env` file with the following API keys accordingly (if you only use email login, only the `MONGOHQ_URL`, `SESSION_SECRET`, `MANDRILL_USER` and `MANDRILL_PASSWORD` fields are necessary. Keep in mind if you want to use more services you'll have to get your own API keys for those services.
``` ```
MONGOHQ_URL='mongodb://localhost:27017/freecodecamp' MONGOHQ_URL='mongodb://localhost:27017/freecodecamp'
FACEBOOK_ID=stuff FACEBOOK_ID=stuff
@ -106,11 +104,9 @@ COOKIE_SECRET='this is a secret'
PEER=stuff PEER=stuff
DEBUG=true DEBUG=true
``` ```
```bash ```bash
# Start the mongo server # Start the mongo server
mongod mongod
@ -124,7 +120,6 @@ node seed/
# start the application # start the application
gulp gulp
``` ```
License License

View File

@ -26,6 +26,7 @@
"moment": "~2.10.2", "moment": "~2.10.2",
"angular-bootstrap": "~0.13.0", "angular-bootstrap": "~0.13.0",
"ramda": "~0.13.0", "ramda": "~0.13.0",
"jshint": "~2.7.0" "jshint": "~2.7.0",
"lightbox2": "~2.8.1"
} }
} }

File diff suppressed because one or more lines are too long

2
client/es6-shims.js Normal file
View File

@ -0,0 +1,2 @@
require('object.assign').shim();
require('es6-map/implement');

View File

@ -1,9 +1,10 @@
import unused from './es6-shims'; // eslint-disable-line
import Rx from 'rx'; import Rx from 'rx';
import React from 'react'; import React from 'react';
import Fetchr from 'fetchr'; import Fetchr from 'fetchr';
import debugFactory from 'debug'; import debugFactory from 'debug';
import { Router } from 'react-router'; import { Router } from 'react-router';
import { history } from 'react-router/lib/BrowserHistory'; import { createLocation, createHistory } from 'history';
import { hydrate } from 'thundercats'; import { hydrate } from 'thundercats';
import { Render } from 'thundercats-react'; import { Render } from 'thundercats-react';
@ -17,21 +18,29 @@ const services = new Fetchr({
}); });
Rx.config.longStackSupport = !!debug.enabled; Rx.config.longStackSupport = !!debug.enabled;
const history = createHistory();
const appLocation = createLocation(
location.pathname + location.search
);
// returns an observable // returns an observable
app$(history) app$({ history, location: appLocation })
.flatMap( .flatMap(
({ AppCat }) => { ({ AppCat }) => {
// instantiate the cat with service
const appCat = AppCat(null, services); const appCat = AppCat(null, services);
// hydrate the stores
return hydrate(appCat, catState) return hydrate(appCat, catState)
.map(() => appCat); .map(() => appCat);
}, },
({ initialState }, appCat) => ({ initialState, appCat }) // not using nextLocation at the moment but will be used for
// redirects in the future
({ nextLocation, props }, appCat) => ({ nextLocation, props, appCat })
) )
.flatMap(({ initialState, appCat }) => { .flatMap(({ props, appCat }) => {
props.history = history;
return Render( return Render(
appCat, appCat,
React.createElement(Router, initialState), React.createElement(Router, props),
DOMContianer DOMContianer
); );
}) })

View File

@ -107,7 +107,7 @@
@border-radius-small: 3px; @border-radius-small: 3px;
//** Global color for active items (e.g., navs or dropdowns). //** Global color for active items (e.g., navs or dropdowns).
@component-active-color: #eee; @component-active-color: @gray-lighter;
//** Global background color for active items (e.g., navs or dropdowns). //** Global background color for active items (e.g., navs or dropdowns).
@component-active-bg: @brand-primary; @component-active-bg: @brand-primary;
@ -145,26 +145,26 @@
@btn-font-weight: normal; @btn-font-weight: normal;
@btn-default-color: #333; @btn-default-color: #333;
@btn-default-bg: #eee; @btn-default-bg: @gray-lighter;
@btn-default-border: #ccc; @btn-default-border: #ccc;
@btn-primary-color: #eee; @btn-primary-color: @gray-lighter;
@btn-primary-bg: @brand-primary; @btn-primary-bg: @brand-primary;
@btn-primary-border: darken(@btn-primary-bg, 5%); @btn-primary-border: darken(@btn-primary-bg, 5%);
@btn-success-color: #eee; @btn-success-color: @gray-lighter;
@btn-success-bg: @brand-success; @btn-success-bg: @brand-success;
@btn-success-border: darken(@btn-success-bg, 5%); @btn-success-border: darken(@btn-success-bg, 5%);
@btn-info-color: #eee; @btn-info-color: @gray-lighter;
@btn-info-bg: @brand-info; @btn-info-bg: @brand-info;
@btn-info-border: darken(@btn-info-bg, 5%); @btn-info-border: darken(@btn-info-bg, 5%);
@btn-warning-color: #eee; @btn-warning-color: @gray-lighter;
@btn-warning-bg: @brand-warning; @btn-warning-bg: @brand-warning;
@btn-warning-border: darken(@btn-warning-bg, 5%); @btn-warning-border: darken(@btn-warning-bg, 5%);
@btn-danger-color: #eee; @btn-danger-color: @gray-lighter;
@btn-danger-bg: @brand-danger; @btn-danger-bg: @brand-danger;
@btn-danger-border: darken(@btn-danger-bg, 5%); @btn-danger-border: darken(@btn-danger-bg, 5%);
@ -176,7 +176,7 @@
//## //##
//** `<input>` background color //** `<input>` background color
@input-bg: #eee; @input-bg: @gray-lighter;
//** `<input disabled>` background color //** `<input disabled>` background color
@input-bg-disabled: @gray-lighter; @input-bg-disabled: @gray-lighter;
@ -223,7 +223,7 @@
//## Dropdown menu container and contents. //## Dropdown menu container and contents.
//** Background for the dropdown menu. //** Background for the dropdown menu.
@dropdown-bg: #eee; @dropdown-bg: @gray-lighter;
//** Dropdown menu `border-color`. //** Dropdown menu `border-color`.
@dropdown-border: rgba(0,0,0,.15); @dropdown-border: rgba(0,0,0,.15);
//** Dropdown menu `border-color` **for IE8**. //** Dropdown menu `border-color` **for IE8**.
@ -359,10 +359,10 @@
@navbar-default-border: darken(@navbar-default-bg, 6.5%); @navbar-default-border: darken(@navbar-default-bg, 6.5%);
// Navbar links // Navbar links
@navbar-default-link-color: #eee; @navbar-default-link-color: @gray-lighter;
@navbar-default-link-hover-color: #4a2b0f; @navbar-default-link-hover-color: #4a2b0f;
@navbar-default-link-hover-bg: #eee; @navbar-default-link-hover-bg: @gray-lighter;
@navbar-default-link-active-color: #eee; @navbar-default-link-active-color: @gray-lighter;
@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%); @navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
@navbar-default-link-disabled-color: #ccc; @navbar-default-link-disabled-color: #ccc;
@navbar-default-link-disabled-bg: transparent; @navbar-default-link-disabled-bg: transparent;
@ -386,7 +386,7 @@
// Inverted navbar links // Inverted navbar links
@navbar-inverse-link-color: @gray-light; @navbar-inverse-link-color: @gray-light;
@navbar-inverse-link-hover-color: #eee; @navbar-inverse-link-hover-color: @gray-lighter;
@navbar-inverse-link-hover-bg: transparent; @navbar-inverse-link-hover-bg: transparent;
@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color; @navbar-inverse-link-active-color: @navbar-inverse-link-hover-color;
@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%); @navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%);
@ -395,12 +395,12 @@
// Inverted navbar brand label // Inverted navbar brand label
@navbar-inverse-brand-color: @navbar-inverse-link-color; @navbar-inverse-brand-color: @navbar-inverse-link-color;
@navbar-inverse-brand-hover-color: #eee; @navbar-inverse-brand-hover-color: @gray-lighter;
@navbar-inverse-brand-hover-bg: transparent; @navbar-inverse-brand-hover-bg: transparent;
// Inverted navbar toggle // Inverted navbar toggle
@navbar-inverse-toggle-hover-bg: #333; @navbar-inverse-toggle-hover-bg: #333;
@navbar-inverse-toggle-icon-bar-bg: #eee; @navbar-inverse-toggle-icon-bar-bg: @gray-lighter;
@navbar-inverse-toggle-border-color: #333; @navbar-inverse-toggle-border-color: #333;
@ -415,7 +415,7 @@
@nav-disabled-link-color: @gray-light; @nav-disabled-link-color: @gray-light;
@nav-disabled-link-hover-color: @gray-light; @nav-disabled-link-hover-color: @gray-light;
@nav-open-link-hover-color: #eee; @nav-open-link-hover-color: @gray-lighter;
//== Tabs //== Tabs
@nav-tabs-border-color: #ddd; @nav-tabs-border-color: #ddd;
@ -440,19 +440,19 @@
//## //##
@pagination-color: @link-color; @pagination-color: @link-color;
@pagination-bg: #eee; @pagination-bg: @gray-lighter;
@pagination-border: #ddd; @pagination-border: #ddd;
@pagination-hover-color: @link-hover-color; @pagination-hover-color: @link-hover-color;
@pagination-hover-bg: @gray-lighter; @pagination-hover-bg: @gray-lighter;
@pagination-hover-border: #ddd; @pagination-hover-border: #ddd;
@pagination-active-color: #eee; @pagination-active-color: @gray-lighter;
@pagination-active-bg: @brand-primary; @pagination-active-bg: @brand-primary;
@pagination-active-border: @brand-primary; @pagination-active-border: @brand-primary;
@pagination-disabled-color: @gray-light; @pagination-disabled-color: @gray-light;
@pagination-disabled-bg: #eee; @pagination-disabled-bg: @gray-lighter;
@pagination-disabled-border: #ddd; @pagination-disabled-border: #ddd;
@ -511,7 +511,7 @@
//** Tooltip max width //** Tooltip max width
@tooltip-max-width: 200px; @tooltip-max-width: 200px;
//** Tooltip text color //** Tooltip text color
@tooltip-color: #eee; @tooltip-color: @gray-lighter;
//** Tooltip background color //** Tooltip background color
@tooltip-bg: #000; @tooltip-bg: #000;
@tooltip-opacity: .9; @tooltip-opacity: .9;
@ -527,7 +527,7 @@
//## //##
//** Popover body background color //** Popover body background color
@popover-bg: #eee; @popover-bg: @gray-lighter;
//** Popover maximum width //** Popover maximum width
@popover-max-width: 276px; @popover-max-width: 276px;
//** Popover border color //** Popover border color
@ -541,7 +541,7 @@
//** Popover arrow width //** Popover arrow width
@popover-arrow-width: 10px; @popover-arrow-width: 10px;
//** Popover arrow color //** Popover arrow color
@popover-arrow-color: #eee; @popover-arrow-color: @gray-lighter;
@popover-arrow-color: @popover-bg; @popover-arrow-color: @popover-bg;
//** Popover outer arrow width //** Popover outer arrow width
@ -570,9 +570,9 @@
@label-danger-bg: @brand-danger; @label-danger-bg: @brand-danger;
//** Default label text color //** Default label text color
@label-color: #eee; @label-color: @gray-lighter;
//** Default text color of a linked label //** Default text color of a linked label
@label-link-hover-color: #eee; @label-link-hover-color: @gray-lighter;
//== Modals //== Modals
@ -588,7 +588,7 @@
@modal-title-line-height: @line-height-base; @modal-title-line-height: @line-height-base;
//** Background color of modal content area //** Background color of modal content area
@modal-content-bg: #eee; @modal-content-bg: @gray-lighter;
//** Modal content border color //** Modal content border color
@modal-content-border-color: rgba(0,0,0,.2); @modal-content-border-color: rgba(0,0,0,.2);
//** Modal content border color **for IE8** //** Modal content border color **for IE8**
@ -640,7 +640,7 @@
//** Background color of the whole progress component //** Background color of the whole progress component
@progress-bg: #f5f5f5; @progress-bg: #f5f5f5;
//** Progress bar text color //** Progress bar text color
@progress-bar-color: #eee; @progress-bar-color: @gray-lighter;
//** Variable for setting rounded corners on progress bar. //** Variable for setting rounded corners on progress bar.
@progress-border-radius: @border-radius-base; @progress-border-radius: @border-radius-base;
@ -662,7 +662,7 @@
//## //##
//** Background color on `.list-group-item` //** Background color on `.list-group-item`
@list-group-bg: #eee; @list-group-bg: @gray-lighter;
//** `.list-group-item` border color //** `.list-group-item` border color
@list-group-border: #ddd; @list-group-border: #ddd;
//** List group border radius //** List group border radius
@ -695,7 +695,7 @@
// //
//## //##
@panel-bg: #eee; @panel-bg: @gray-lighter;
@panel-body-padding: 15px; @panel-body-padding: 15px;
@panel-heading-padding: 10px 15px; @panel-heading-padding: 10px 15px;
@panel-footer-padding: @panel-heading-padding; @panel-footer-padding: @panel-heading-padding;
@ -709,7 +709,7 @@
@panel-default-border: #ddd; @panel-default-border: #ddd;
@panel-default-heading-bg: #f5f5f5; @panel-default-heading-bg: #f5f5f5;
@panel-primary-text: #eee; @panel-primary-text: @gray-lighter;
@panel-primary-border: @brand-primary; @panel-primary-border: @brand-primary;
@panel-primary-heading-bg: @brand-primary; @panel-primary-heading-bg: @brand-primary;
@ -717,7 +717,7 @@
@panel-success-border: @state-success-border; @panel-success-border: @state-success-border;
@panel-success-heading-bg: @state-success-bg; @panel-success-heading-bg: @state-success-bg;
@panel-info-text: #eee; @panel-info-text: @gray-lighter;
@panel-info-border: darken(#4a2b0f, 5%); @panel-info-border: darken(#4a2b0f, 5%);
@panel-info-heading-bg: #4a2b0f; @panel-info-heading-bg: #4a2b0f;
@ -761,15 +761,15 @@
// //
//## //##
@badge-color: #eee; @badge-color: @gray-lighter;
//** Linked badge text color on hover //** Linked badge text color on hover
@badge-link-hover-color: #eee; @badge-link-hover-color: @gray-lighter;
@badge-bg: @gray-light; @badge-bg: @gray-light;
//** Badge text color in active nav link //** Badge text color in active nav link
@badge-active-color: @link-color; @badge-active-color: @link-color;
//** Badge background color in active nav link //** Badge background color in active nav link
@badge-active-bg: #eee; @badge-active-bg: @gray-lighter;
@badge-font-weight: bold; @badge-font-weight: bold;
@badge-line-height: 1; @badge-line-height: 1;
@ -798,15 +798,15 @@
@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6); @carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6);
@carousel-control-color: #eee; @carousel-control-color: @gray-lighter;
@carousel-control-width: 15%; @carousel-control-width: 15%;
@carousel-control-opacity: .5; @carousel-control-opacity: .5;
@carousel-control-font-size: 20px; @carousel-control-font-size: 20px;
@carousel-indicator-active-bg: #eee; @carousel-indicator-active-bg: @gray-lighter;
@carousel-indicator-border-color: #eee; @carousel-indicator-border-color: @gray-lighter;
@carousel-caption-color: #eee; @carousel-caption-color: @gray-lighter;
//== Close //== Close
@ -815,7 +815,7 @@
@close-font-weight: bold; @close-font-weight: bold;
@close-color: #000; @close-color: #000;
@close-text-shadow: 0 1px 0 #eee; @close-text-shadow: 0 1px 0 @gray-lighter;
//== Code //== Code
@ -825,7 +825,7 @@
@code-color: #c7254e; @code-color: #c7254e;
@code-bg: #f9f2f4; @code-bg: #f9f2f4;
@kbd-color: #eee; @kbd-color: @gray-lighter;
@kbd-bg: #333; @kbd-bg: #333;
@pre-bg: #f5f5f5; @pre-bg: #f5f5f5;

View File

@ -37,8 +37,7 @@ html {
overflow-x: hidden; overflow-x: hidden;
} }
input[type=checkbox] input[type=checkbox] {
{
/* Double-sized Checkboxes */ /* Double-sized Checkboxes */
-ms-transform: scale(2); /* IE */ -ms-transform: scale(2); /* IE */
-moz-transform: scale(2); /* FF */ -moz-transform: scale(2); /* FF */
@ -48,7 +47,7 @@ input[type=checkbox]
} }
body.full-screen-body-background { body.full-screen-body-background {
background-color: #eeeeee; background-color: @gray-lighter;
} }
@ -101,24 +100,10 @@ h1, h2, h3, h4, h5, h6, p, li {
margin: 0 auto; margin: 0 auto;
} }
.three-by-three {
height: 100px;
}
.darker-background {
background-color: #dedede;
}
/**/
.btn-cta { .btn-cta {
font-size: 40px; font-size: 40px;
} }
.nonprofit-cta {
font-size: 28px;
}
.btn, .shadow { .btn, .shadow {
white-space: normal; white-space: normal;
-webkit-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3);
@ -142,25 +127,6 @@ ul {
word-wrap: break-word; word-wrap: break-word;
} }
.img-center {
margin:0 auto;
}
.centered-iframe {
display:block;
}
@media (min-width: 767px) {
.landing-panel-body {
padding-left: 40px;
padding-right: 40px;
}
}
.landing-panel-heading {
font-size: 40px;
}
.panel-heading { .panel-heading {
font-size: 25px; font-size: 25px;
} }
@ -175,14 +141,6 @@ ul {
font-size: 26px; font-size: 26px;
} }
.five-pixel-break {
height: 5px;
}
.fifteen-pixel-break {
height: 15px;
}
.nav-height { .nav-height {
height: 50px; height: 50px;
border: none; border: none;
@ -197,51 +155,30 @@ ul {
font-size: 150px; font-size: 150px;
} }
.responsive-container { position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden; } .positive-15 {
.responsive-container iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } margin-top: 15px;
.positive-10 {
margin-top: 10px;
} }
.positive-15-bottom { .positive-15-bottom {
margin-bottom: 15px; margin-bottom: 15px;
} }
.positive-15 { .positive-10 {
margin-top: 15px; margin-top: 10px;
} }
.negative-45 { .positive-5 {
margin-top: -45px; margin-top: 5px;
margin-bottom: -45px;
}
.negative-55 {
margin-top: -55px;
margin-bottom: -55px;
}
.negative-10 {
margin-top: -10px;
}
.negative-28 {
margin-top: -28px;
}
.negative-35 {
margin-top: -35px;
}
.negative-30 {
margin-top: -30px;
} }
.negative-5 { .negative-5 {
margin-top: -5px; margin-top: -5px;
} }
.negative-10 {
margin-top: -10px;
}
.negative-15 { .negative-15 {
margin-top: -15px; margin-top: -15px;
} }
@ -250,14 +187,35 @@ ul {
margin-top: -20px; margin-top: -20px;
} }
.negative-bottom-margin-30 { .negative-28 {
margin-top: -28px;
}
.negative-30 {
margin-top: -30px;
}
.negative-30-bottom {
margin-bottom: -30px; margin-bottom: -30px;
} }
.negative-35 {
margin-top: -35px;
}
.negative-55 {
margin-top: -55px;
margin-bottom: -55px;
}
.large-p { .large-p {
font-size: 24px; font-size: 24px;
} }
.map-p {
font-size: 20px;
}
.large-li { .large-li {
font-size: 24px; font-size: 24px;
} }
@ -270,36 +228,11 @@ ul {
color: @brand-success; color: @brand-success;
} }
.delay-1 {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.delay-2 {
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.delay-4 {
-webkit-animation-delay: 4s;
animation-delay: 4s;
}
.delay-10 {
-webkit-animation-delay: 10s;
animation-delay: 10s;
}
.fast-animation { .fast-animation {
-webkit-animation-duration: 0.5s; -webkit-animation-duration: 0.5s;
animation-duration: 0.5s; animation-duration: 0.5s;
} }
.slow-animation {
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
}
.disabled { .disabled {
pointer-events: none; pointer-events: none;
cursor: default; cursor: default;
@ -310,10 +243,6 @@ ul {
display: none; display: none;
} }
.button-container {
height: 120px;
}
.nav-logo { .nav-logo {
height: 40px; height: 40px;
margin-top: -10px; margin-top: -10px;
@ -357,8 +286,8 @@ ul {
margin-bottom: -6px; margin-bottom: -6px;
} }
.strikethrough { .lb-container {
text-decoration: line-through; padding: 0px;
} }
.btn-social { .btn-social {
@ -377,7 +306,7 @@ ul {
} }
.navbar-nav > li > a { .navbar-nav > li > a {
color: #eee; color: @gray-lighter;
&:hover { &:hover {
color: #4a2b0f; color: #4a2b0f;
} }
@ -396,11 +325,6 @@ ul {
font-size: 63px; font-size: 63px;
} }
.scroll-lock {
overflow: hidden;
height: 100%;
}
.signup-btn.btn { .signup-btn.btn {
background-color: #ffac33; background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33); background-image: linear-gradient(#ffcc4d, #ffac33);
@ -421,41 +345,9 @@ ul {
background-image: none; background-image: none;
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3); box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
} }
.profile-image {
border-radius: 5px;
width: 200px;
height: 200px;
padding-left: 5px;
padding-right: 5px;
}
.team-member { *, *:before, *:after {
height: 420px; box-sizing: border-box !important;
}
*, *:before, *:after {box-sizing: border-box !important;}
.masonry-row {
-moz-column-width: 18em;
-webkit-column-width: 18em;
-moz-column-gap: 1em;
-webkit-column-gap:1em;
}
.masonry-block {
display: inline-block;
padding: .25rem;
width: 100%;
}
.masonry-relative {
position:relative;
display: block;
}
.next-challenge-button {
max-width: 1500px;
margin:0 auto;
} }
.btn-big { .btn-big {
@ -505,13 +397,13 @@ thead {
} }
.navbar-nav a { .navbar-nav a {
color: #eee; color: @gray-lighter;
font-size: 20px; font-size: 20px;
margin-top: -5px; margin-top: -5px;
margin-bottom: -5px; margin-bottom: -5px;
} }
.navbar-toggle { .navbar-toggle {
color: #eee; color: @gray-lighter;
} }
.navbar-right { .navbar-right {
@ -525,11 +417,6 @@ thead {
padding-bottom: 10px !important; padding-bottom: 10px !important;
} }
.nameline {
margin-top: -5px;
font-size: 40px;
}
.public-profile-img { .public-profile-img {
height: 200px; height: 200px;
width: 200px; width: 200px;
@ -543,23 +430,6 @@ thead {
border-color: #78FA89; border-color: #78FA89;
} }
.desktop-narrow {
@media (min-width: 767px) {
marign: 0 auto;
width: 80%;
}
}
.min650 {
min-height: 630px;
}
.portfolio-image {
height: 225px;
width: 300px;
border-radius: 5px;
}
.flat-top { .flat-top {
margin-top: -5px; margin-top: -5px;
} }
@ -573,7 +443,7 @@ thead {
} }
.points-on-top { .points-on-top {
color: #eee; color: @gray-lighter;
font-size: 35px; font-size: 35px;
z-index: 2; z-index: 2;
width: 60%; width: 60%;
@ -642,7 +512,7 @@ thead {
.challenge-list-header { .challenge-list-header {
background-color: #215f1e; background-color: #215f1e;
color: #eee; color: @gray-lighter;
font-size: 36px; font-size: 36px;
text-align: center; text-align: center;
margin-bottom: -30px; margin-bottom: -30px;
@ -650,19 +520,8 @@ thead {
padding-left: 50px; padding-left: 50px;
} }
.all-list-header {
background-color: #4A2B0F;
color: #eee;
font-size: 36px;
text-align: center;
margin-bottom: -30px;
border-radius: 5px 5px 0px 0px;
padding-left: 50px;
}
.closing-x { .closing-x {
color: #eee; color: @gray-lighter;
font-size: 50px; font-size: 50px;
text-align: right; text-align: right;
} }
@ -678,7 +537,7 @@ thead {
position: absolute; position: absolute;
a { a {
font-size: 20px; font-size: 20px;
color: #eee; color: @gray-lighter;
margin-left: 0px; margin-left: 0px;
margin-right: 0px; margin-right: 0px;
padding-left: 10px; padding-left: 10px;
@ -687,7 +546,7 @@ thead {
padding-bottom: 12px; padding-bottom: 12px;
&:hover { &:hover {
color: #4a2b0f; color: #4a2b0f;
background-color: #eee; background-color: @gray-lighter;
text-decoration: none; text-decoration: none;
} }
} }
@ -702,19 +561,6 @@ thead {
font-size: 15px; font-size: 15px;
} }
.jquery-exercises-well {
text-align: left;
height: 200px;
}
#exercise-directory {
font-size: 20px;
}
#current-exercise {
text-size: 250px;
}
.bonfire-instructions { .bonfire-instructions {
margin-bottom: 5px; margin-bottom: 5px;
} }
@ -764,16 +610,13 @@ form.code span {
.test-output { .test-output {
font-size: 15px; font-size: 15px;
font-family: "Ubuntu Mono"; font-family: "Ubuntu Mono";
margin-top: 8px;
} }
#mainEditorPanel .panel-body { #mainEditorPanel .panel-body {
padding-bottom: 0px; padding-bottom: 0px;
} }
.panel-bonfire {
height: 100%
}
div.CodeMirror-scroll { div.CodeMirror-scroll {
padding-bottom: 30px; padding-bottom: 30px;
} }
@ -812,11 +655,6 @@ iframe.iphone {
} }
} }
.nonprofit-help-select-text-height {
font-size: 40px;
padding-top: 20px;
}
// To adjust right margin, negative values bring the image closer to the edge of the screen // To adjust right margin, negative values bring the image closer to the edge of the screen
.iphone-position { .iphone-position {
position: absolute; position: absolute;
@ -829,25 +667,6 @@ iframe.iphone {
min-height: 650px; min-height: 650px;
} }
// This is used to give icons text for screen readers to read out, without needing the text to actually appear.
.icon-lock{
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;
}
.btn-primary-ghost { .btn-primary-ghost {
background: transparent; background: transparent;
color: @brand-primary; color: @brand-primary;
@ -918,38 +737,11 @@ iframe.iphone {
font-size: 18px; font-size: 18px;
} }
.tight-h3 {
margin-top: -4px;
margin-bottom: -4px;
}
.story-list { .story-list {
padding-bottom: 30px; padding-bottom: 30px;
margin-bottom: 30px; margin-bottom: 30px;
} }
.big-ion-up-arrow {
font-size: 45px;
margin-top: -10px;
margin-bottom: -15px;
text-align: center;
}
.big-ion-up-arrow #upvote, #reply-to-main-post {
cursor: pointer;
}
.story-up-votes {
padding-top: 0px;
margin-left: -5px;
text-align: center;
}
.img-story-post {
max-width: 110px;
max-height: 110px;
}
.button-spacer { .button-spacer {
padding: 5px 0 2px 0; padding: 5px 0 2px 0;
} }
@ -1057,11 +849,7 @@ hr {
} }
.cal-heatmap-container { .cal-heatmap-container {
background-color: #EEEEEE; background-color: @gray-lighter;
}
.checkbox-table label {
margin-left: 10px;
} }
.interested-camper-image { .interested-camper-image {
@ -1070,16 +858,6 @@ hr {
padding: 5px; padding: 5px;
} }
.svg-challenge-map {
fill: #333;
height: 40px;
}
.news-number {
font-size: 30px;
text-align: center;
}
.mobile-story-image { .mobile-story-image {
border-radius: 5px; border-radius: 5px;
width: 100%; width: 100%;
@ -1101,10 +879,6 @@ hr {
opacity: 0.5; opacity: 0.5;
} }
.same-line {
display: inline-block;
}
.padded-ionic-icon { .padded-ionic-icon {
padding-top: 5px; padding-top: 5px;
} }
@ -1126,6 +900,10 @@ hr {
color: @gray-light; color: @gray-light;
} }
code {
padding: 0;
}
@media only screen and (min-width: 993px) { @media only screen and (min-width: 993px) {
.iframe-scroll { .iframe-scroll {
position: fixed !important; position: fixed !important;
@ -1142,10 +920,6 @@ hr {
// Calculator styles // Calculator styles
.initially-hidden {
display: none;
}
.chart rect { .chart rect {
fill: steelblue; fill: steelblue;
} }

View File

@ -1,14 +1,45 @@
var mapShareKey = 'map-shares';
var lastCompleted = typeof lastCompleted !== 'undefined' ?
lastCompleted :
'';
function getMapShares() {
var alreadyShared = JSON.parse(localStorage.getItem(mapShareKey) || '[]');
if (!alreadyShared || !Array.isArray(alreadyShared)) {
localStorage.setItem(mapShareKey, JSON.stringify([]));
alreadyShared = [];
}
return alreadyShared;
}
function setMapShare(id) {
var alreadyShared = getMapShares();
var found = false;
alreadyShared.forEach(function(_id) {
if (_id === id) {
found = true;
}
});
if (!found) {
alreadyShared.push(id);
}
localStorage.setItem(mapShareKey, JSON.stringify(alreadyShared));
return alreadyShared;
}
$(document).ready(function() { $(document).ready(function() {
var challengeName = typeof challengeName !== undefined ? challengeName : 'Untitled';
var challengeName = typeof challengeName !== 'undefined' ?
challengeName :
'Untitled';
if (challengeName) { if (challengeName) {
ga('send', 'event', 'Challenge', 'load', challengeName); ga('send', 'event', 'Challenge', 'load', challengeName);
} }
$(document).ready(function() {
if (typeof editor !== 'undefined') { if (typeof editor !== 'undefined') {
$('#reset-button').on('click', resetEditor); $('#reset-button').on('click', resetEditor);
} }
});
var CSRF_HEADER = 'X-CSRF-Token'; var CSRF_HEADER = 'X-CSRF-Token';
@ -66,10 +97,64 @@ $(document).ready(function() {
}, 200); }, 200);
}); });
$('#search-issue').unbind('click');
$('#search-issue').on('click', function() {
var queryIssue = window.location.href.toString();
window.open('https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' +
'is:issue is:all ' + (challenge_Name || challengeName) + ' OR ' +
queryIssue.substr(queryIssue.lastIndexOf('challenges/') + 11)
.replace('/', ''), '_blank');
});
$('#help-ive-found-a-bug-wiki-article').unbind('click');
$('#help-ive-found-a-bug-wiki-article').on('click', function() {
window.open("https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Help-I've-Found-a-Bug", '_blank');
});
$('#report-issue').unbind('click'); $('#report-issue').unbind('click');
$('#report-issue').on('click', function() { $('#report-issue').on('click', function() {
var textMessage = [
'Challenge [',
(challenge_Name || challengeName || window.location.href),
'](',
window.location.href,
') has an issue.\n',
'User Agent is: <code>',
navigator.userAgent,
'</code>.\n',
'Please describe how to reproduce this issue, and include ',
'links to screenshots if possible.\n\n'
].join('');
if (editor.getValue().trim()) {
var type;
switch (challengeType) {
case challengeTypes.HTML_CSS_JQ:
type = 'html';
break;
case challengeTypes.JAVASCRIPT:
type = 'javascript';
break;
default:
type = '';
}
textMessage += [
'My code:\n```',
type,
'\n',
editor.getValue(),
'\n```\n\n'
].join('');
}
textMessage = encodeURIComponent(textMessage);
$('#issue-modal').modal('hide'); $('#issue-modal').modal('hide');
window.open('https://github.com/freecodecamp/freecodecamp/issues/new?&body=Challenge '+ window.location.href +' has an issue. Please describe how to reproduce it, and include links to screenshots if possible.', '_blank') window.open(
'https://github.com/freecodecamp/freecodecamp/issues/new?&body=' +
textMessage, '_blank'
);
}); });
$('#completed-courseware').unbind('click'); $('#completed-courseware').unbind('click');
@ -125,7 +210,7 @@ $(document).ready(function() {
}).success( }).success(
function(res) { function(res) {
if (res) { if (res) {
window.location.href = '/challenges/next-challenge'; window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
} }
}).fail( }).fail(
function() { function() {
@ -148,7 +233,7 @@ $(document).ready(function() {
} }
}).success( }).success(
function() { function() {
window.location.href = '/challenges/next-challenge'; window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
}).fail( }).fail(
function() { function() {
window.location.href = '/challenges'; window.location.href = '/challenges';
@ -171,25 +256,19 @@ $(document).ready(function() {
verified: false verified: false
} }
}).success(function() { }).success(function() {
window.location.href = '/challenges/next-challenge'; window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
}).fail(function() { }).fail(function() {
window.location.replace(window.location.href); window.location.replace(window.location.href);
}); });
break; break;
case challengeTypes.BONFIRE: case challengeTypes.BONFIRE:
window.location.href = '/challenges/next-challenge'; window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
default: default:
break; break;
} }
} }
}); });
$('.next-challenge-button').unbind('click');
$('.next-challenge-button').on('click', function() {
l = location.pathname.split('/');
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
});
$('#complete-courseware-dialog').on('hidden.bs.modal', function() { $('#complete-courseware-dialog').on('hidden.bs.modal', function() {
editor.focus(); editor.focus();
}); });
@ -333,6 +412,40 @@ $(document).ready(function() {
} }
}, false); }, false);
} }
// map sharing
var alreadyShared = getMapShares();
if (lastCompleted && alreadyShared.indexOf(lastCompleted) === -1) {
$('div[id="' + lastCompleted + '"]')
.parent()
.parent()
.removeClass('hidden');
}
// on map view
$('.map-challenge-block-share').on('click', function(e) {
e.preventDefault();
var challengeBlockName = $(this).children().attr('id');
var challengeBlockEscapedName = challengeBlockName.replace(/\s/, '%20');
var username = typeof window.username !== 'undefined' ?
window.username :
'';
var link = 'https://www.facebook.com/dialog/feed?' +
'app_id=1644598365767721' +
'&display=page&' +
'caption=I%20just%20completed%20the%20' +
challengeBlockEscapedName +
'%20section%20on%20Free%20Code%20Camp%2E' +
'&link=http%3A%2F%2Ffreecodecamp%2Ecom%2F' +
username +
'&redirect_uri=http%3A%2F%2Ffreecodecamp%2Ecom%2Fmap';
setMapShare(challengeBlockName);
window.location.href = link;
});
}); });
function defCheck(a){ function defCheck(a){

View File

@ -1,18 +1,17 @@
import Rx from 'rx'; import Rx from 'rx';
import assign from 'object.assign'; import { match } from 'react-router';
import { Router } from 'react-router';
import App from './App.jsx'; import App from './App.jsx';
import AppCat from './Cat'; import AppCat from './Cat';
import childRoutes from './routes'; import childRoutes from './routes';
const router$ = Rx.Observable.fromNodeCallback(Router.run, Router); const route$ = Rx.Observable.fromNodeCallback(match);
const routes = assign({ components: App }, childRoutes); const routes = Object.assign({ components: App }, childRoutes);
export default function app$(location) { export default function app$({ location, history }) {
return router$(routes, location) return route$({ routes, location, history })
.map(([initialState, transistion]) => { .map(([nextLocation, props]) => {
return { initialState, transistion, AppCat }; return { nextLocation, props, AppCat };
}); });
} }

View File

@ -1,5 +1,4 @@
import { Actions } from 'thundercats'; import { Actions } from 'thundercats';
import assign from 'object.assign';
import debugFactory from 'debug'; import debugFactory from 'debug';
const debug = debugFactory('freecc:hikes:actions'); const debug = debugFactory('freecc:hikes:actions');
@ -45,7 +44,7 @@ export default Actions({
dashedName, dashedName,
oldState.currentHike oldState.currentHike
); );
return assign({}, oldState, { currentHike }); return Object.assign({}, oldState, { currentHike });
} }
}); });
} }

View File

@ -0,0 +1,43 @@
import React, { PropTypes } from 'react';
import { History } from 'react-router';
import { Button, Modal } from 'react-bootstrap';
export default React.createClass({
displayName: 'CreateJobsModal',
propTypes: {
onHide: PropTypes.func,
showModal: PropTypes.bool
},
mixins: [History],
goToNewJob(onHide) {
onHide();
this.history.pushState(null, '/jobs/new');
},
render() {
const {
showModal,
onHide
} = this.props;
return (
<Modal
onHide={ onHide }
show={ showModal }>
<Modal.Body>
<h4>Welcome to Free Code Camp's board</h4>
<p>We post jobs specifically target to our junior developers.</p>
<Button
block={ true }
className='signup-btn'
onClick={ () => this.goToNewJob(onHide) }>
Post a Job
</Button>
</Modal.Body>
</Modal>
);
}
});

View File

@ -1,23 +1,43 @@
import React, { cloneElement, PropTypes } from 'react'; import React, { cloneElement, PropTypes } from 'react';
import { contain } from 'thundercats-react'; import { contain } from 'thundercats-react';
import { History } from 'react-router';
import { Button, Jumbotron, Row } from 'react-bootstrap'; import { Button, Jumbotron, Row } from 'react-bootstrap';
import CreateJobModal from './CreateJobModal.jsx';
import ListJobs from './List.jsx'; import ListJobs from './List.jsx';
export default contain( export default contain(
{ {
store: 'jobsStore', store: 'jobsStore',
fetchAction: 'jobActions.getJobs' fetchAction: 'jobActions.getJobs',
actions: 'jobActions'
}, },
React.createClass({ React.createClass({
displayName: 'Jobs', displayName: 'Jobs',
mixins: [History],
propTypes: { propTypes: {
children: PropTypes.element, children: PropTypes.element,
jobs: PropTypes.array jobActions: PropTypes.object,
jobs: PropTypes.array,
showModal: PropTypes.bool
}, },
renderList(jobs) { handleJobClick(id) {
const { jobActions } = this.props;
if (!id) {
return null;
}
jobActions.findJob(id);
this.history.pushState(null, `/jobs/${id}`);
},
renderList(handleJobClick, jobs) {
return ( return (
<ListJobs jobs={ jobs }/> <ListJobs
handleClick={ handleJobClick }
jobs={ jobs }/>
); );
}, },
@ -32,7 +52,12 @@ export default contain(
}, },
render() { render() {
const { children, jobs } = this.props; const {
children,
jobs,
showModal,
jobActions
} = this.props;
return ( return (
<div> <div>
@ -46,15 +71,19 @@ export default contain(
</p> </p>
<Button <Button
bsSize='large' bsSize='large'
className='signup-btn'> className='signup-btn'
onClick={ jobActions.openModal }>
Try the first month 20% off! Try the first month 20% off!
</Button> </Button>
</Jumbotron> </Jumbotron>
</Row> </Row>
<Row> <Row>
{ this.renderChild(children, jobs) || { this.renderChild(children, jobs) ||
this.renderList(jobs) } this.renderList(this.handleJobClick, jobs) }
</Row> </Row>
<CreateJobModal
onHide={ jobActions.closeModal }
showModal={ showModal } />
</div> </div>
); );
} }

View File

@ -1,29 +1,28 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { contain } from 'thundercats-react';
import { PanelGroup, Thumbnail, Panel, Well } from 'react-bootstrap'; import { PanelGroup, Thumbnail, Panel, Well } from 'react-bootstrap';
import moment from 'moment'; import moment from 'moment';
export default contain( export default React.createClass({
{
},
React.createClass({
displayName: 'ListJobs', displayName: 'ListJobs',
propTypes: { propTypes: {
handleClick: PropTypes.func,
jobs: PropTypes.array jobs: PropTypes.array
}, },
renderJobs(jobs =[]) { renderJobs(handleClick, jobs =[]) {
const thumbnailStyle = { const thumbnailStyle = {
backgroundColor: 'white', backgroundColor: 'white',
maxHeight: '100px', maxHeight: '100px',
maxWidth: '100px' maxWidth: '100px'
}; };
return jobs.map(( return jobs.map((
{ {
id, id,
company, company,
position, position,
isHighlighted,
description, description,
logo, logo,
city, city,
@ -46,13 +45,15 @@ export default contain(
); );
return ( return (
<Panel <Panel
bsStyle={ isHighlighted ? 'warning' : 'default' }
collapsible={ true } collapsible={ true }
eventKey={ index } eventKey={ index }
header={ header } header={ header }
key={ id }> key={ id }>
<Well> <Well>
<Thumbnail <Thumbnail
alt='200x200' src={ logo } alt={ company + 'company logo' }
src={ logo }
style={ thumbnailStyle } /> style={ thumbnailStyle } />
<Panel> <Panel>
Position: { position } Position: { position }
@ -62,7 +63,7 @@ export default contain(
<br /> <br />
Posted On: { moment(postedOn).format('MMMM Do, YYYY') } Posted On: { moment(postedOn).format('MMMM Do, YYYY') }
</Panel> </Panel>
<p>{ description }</p> <p onClick={ () => handleClick(id) }>{ description }</p>
</Well> </Well>
</Panel> </Panel>
); );
@ -70,12 +71,15 @@ export default contain(
}, },
render() { render() {
const { jobs } = this.props; const {
handleClick,
jobs
} = this.props;
return ( return (
<PanelGroup> <PanelGroup>
{ this.renderJobs(jobs) } { this.renderJobs(handleClick, jobs) }
</PanelGroup> </PanelGroup>
); );
} }
}) });
);

View File

@ -0,0 +1,319 @@
import React, { PropTypes } from 'react';
import { History } from 'react-router';
import { contain } from 'thundercats-react';
import debugFactory from 'debug';
import { getDefaults } from '../utils';
import {
inHTMLData,
uriInSingleQuotedAttr
} from 'xss-filters';
import {
Button,
Col,
Input,
Row,
Well
} from 'react-bootstrap';
import {
isAscii,
isEmail,
isMobilePhone,
isURL
} from 'validator';
const debug = debugFactory('freecc:jobs:newForm');
const checkValidity = [
'position',
'locale',
'description',
'email',
'phone',
'url',
'logo',
'name',
'highlight'
];
function formatValue(value, validator, type = 'string') {
const formated = getDefaults(type);
if (validator && type === 'string') {
formated.valid = validator(value);
}
if (value) {
formated.value = value;
formated.bsStyle = formated.valid ? 'success' : 'error';
}
return formated;
}
function isValidURL(data) {
return isURL(data, { 'require_protocol': true });
}
function isValidPhone(data) {
return isMobilePhone(data, 'en-US');
}
export default contain({
actions: 'jobActions',
store: 'jobsStore',
map({ form = {} }) {
const {
position,
locale,
description,
email,
phone,
url,
logo,
name,
highlight
} = form;
return {
position: formatValue(position, isAscii),
locale: formatValue(locale, isAscii),
description: formatValue(description, isAscii),
email: formatValue(email, isEmail),
phone: formatValue(phone, isValidPhone),
url: formatValue(url, isValidURL),
logo: formatValue(logo, isValidURL),
name: formatValue(name, isAscii),
highlight: formatValue(highlight, null, 'bool')
};
},
subscribeOnWillMount() {
return typeof window !== 'undefined';
}
},
React.createClass({
displayName: 'NewJob',
propTypes: {
jobActions: PropTypes.object,
position: PropTypes.object,
locale: PropTypes.object,
description: PropTypes.object,
email: PropTypes.object,
phone: PropTypes.object,
url: PropTypes.object,
logo: PropTypes.object,
name: PropTypes.object,
highlight: PropTypes.object
},
mixins: [History],
handleSubmit(e) {
e.preventDefault();
const props = this.props;
let valid = true;
checkValidity.forEach((prop) => {
// if value exist, check if it is valid
if (props[prop].value && props[prop].type !== 'boolean') {
valid = valid && !!props[prop].valid;
}
});
if (!valid) {
debug('form not valid');
return;
}
const {
position,
locale,
description,
email,
phone,
url,
logo,
name,
highlight,
jobActions
} = this.props;
// sanitize user output
const jobValues = {
position: inHTMLData(position.value),
location: inHTMLData(locale.value),
description: inHTMLData(description.value),
email: inHTMLData(email.value),
phone: inHTMLData(phone.value),
url: uriInSingleQuotedAttr(url.value),
logo: uriInSingleQuotedAttr(logo.value),
name: inHTMLData(name.value),
highlight: !!highlight.value
};
const job = Object.keys(jobValues).reduce((accu, prop) => {
if (jobValues[prop]) {
accu[prop] = jobValues[prop];
}
return accu;
}, {});
job.postedOn = new Date();
debug('job sanitized', job);
jobActions.saveForm(job);
this.history.pushState(null, '/jobs/new/preview');
},
componentDidMount() {
const { jobActions } = this.props;
jobActions.getSavedForm();
},
handleChange(name, { target: { value } }) {
const { jobActions: { handleForm } } = this.props;
handleForm({ [name]: value });
},
render() {
const {
position,
locale,
description,
email,
phone,
url,
logo,
name,
highlight,
jobActions: { handleForm }
} = this.props;
const { handleChange } = this;
const labelClass = 'col-sm-offset-1 col-sm-2';
const inputClass = 'col-sm-6';
return (
<div>
<Row>
<Col>
<Well className='text-center'>
<h1>Create Your Job Post</h1>
<form
className='form-horizontal'
onSubmit={ this.handleSubmit }>
<div className='spacer'>
<h2>Job Information</h2>
</div>
<Input
bsStyle={ position.bsStyle }
label='Position'
labelClassName={ labelClass }
onChange={ (e) => handleChange('position', e) }
placeholder='Position'
type='text'
value={ position.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ locale.bsStyle }
label='Location'
labelClassName={ labelClass }
onChange={ (e) => handleChange('locale', e) }
placeholder='Location'
type='text'
value={ locale.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ description.bsStyle }
label='Description'
labelClassName={ labelClass }
onChange={ (e) => handleChange('description', e) }
placeholder='Description'
rows='10'
type='textarea'
value={ description.value }
wrapperClassName={ inputClass } />
<div className='divider'>
<h2>Company Information</h2>
</div>
<Input
bsStyle={ name.bsStyle }
label='Company Name'
labelClassName={ labelClass }
onChange={ (e) => handleChange('name', e) }
placeholder='Foo, INC'
type='text'
value={ name.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ email.bsStyle }
label='Email'
labelClassName={ labelClass }
onChange={ (e) => handleChange('email', e) }
placeholder='Email'
type='email'
value={ email.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ phone.bsStyle }
label='Phone'
labelClassName={ labelClass }
onChange={ (e) => handleChange('phone', e) }
placeholder='555-123-1234'
type='tel'
value={ phone.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ url.bsStyle }
label='URL'
labelClassName={ labelClass }
onChange={ (e) => handleChange('url', e) }
placeholder='http://freecatphotoapp.com'
type='url'
value={ url.value }
wrapperClassName={ inputClass } />
<Input
bsStyle={ logo.bsStyle }
label='Logo'
labelClassName={ labelClass }
onChange={ (e) => handleChange('logo', e) }
placeholder='http://freecatphotoapp.com/logo.png'
type='url'
value={ logo.value }
wrapperClassName={ inputClass } />
<div className='divider'>
<h2>Make it stand out</h2>
</div>
<Input
checked={ highlight.value }
label='Highlight your ad'
labelClassName={ 'col-sm-offset-1 col-sm-6'}
onChange={
({ target: { checked } }) => handleForm({
highlight: !!checked
})
}
type='checkbox' />
<div className='spacer' />
<Row>
<Col
lg={ 6 }
lgOffset={ 3 }>
<Button
block={ true }
bsSize='large'
bsStyle='primary'
type='submit'>
Preview My Ad
</Button>
</Col>
</Row>
</form>
</Well>
</Col>
</Row>
</div>
);
}
})
);

View File

@ -0,0 +1,14 @@
// import React, { PropTypes } from 'react';
import { contain } from 'thundercats-react';
import ShowJob from './ShowJob.jsx';
export default contain(
{
store: 'JobsStore',
actions: 'JobActions',
map({ form: job = {} }) {
return { job };
}
},
ShowJob
);

View File

@ -1,59 +1,24 @@
import React, { PropTypes } from 'react'; import { contain } from 'thundercats-react';
import { Thumbnail, Panel, Well } from 'react-bootstrap'; import ShowJob from './ShowJob.jsx';
import moment from 'moment';
const thumbnailStyle = { export default contain(
backgroundColor: 'white', {
maxHeight: '100px', store: 'jobsStore',
maxWidth: '100px' fetchAction: 'jobActions.getJob',
map({ currentJob }) {
return { job: currentJob };
},
getPayload({ params: { id }, job = {} }) {
return {
id,
isPrimed: job.id === id
}; };
export default React.createClass({
displayName: 'ShowJob',
propTypes: {
job: PropTypes.object
}, },
// using es6 destructuring
renderHeader({ company, position }) { shouldContainerFetch({ job = {} }, { params: { id } }
return ( ) {
<div> return job.id !== id;
<h4 style={{ display: 'inline-block' }}>{ company }</h4>
<h5
className='pull-right hidden-xs hidden-md'
style={{ display: 'inline-block' }}>
{ position }
</h5>
</div>
);
},
render() {
const { job } = this.props;
const {
logo,
position,
city,
state,
email,
phone,
postedOn,
description
} = job;
return (
<Well>
<Thumbnail
alt='200x200' src={ logo }
style={ thumbnailStyle } />
<Panel>
Position: { position }
Location: { city }, { state }
<br />
Contact: { email || phone || 'N/A' }
<br />
Posted On: { moment(postedOn).format('MMMM Do, YYYY') }
</Panel>
<p>{ description }</p>
</Well>
);
} }
}); },
ShowJob
);

View File

@ -0,0 +1,67 @@
import React, { PropTypes } from 'react';
import { Row, Thumbnail, Panel, Well } from 'react-bootstrap';
import moment from 'moment';
const thumbnailStyle = {
backgroundColor: 'white',
maxHeight: '100px',
maxWidth: '100px'
};
export default React.createClass({
displayName: 'ShowJob',
propTypes: {
job: PropTypes.object,
params: PropTypes.object
},
renderHeader({ company, position }) {
return (
<div>
<h4 style={{ display: 'inline-block' }}>{ company }</h4>
<h5
className='pull-right hidden-xs hidden-md'
style={{ display: 'inline-block' }}>
{ position }
</h5>
</div>
);
},
render() {
const { job = {} } = this.props;
const {
logo,
position,
city,
company,
state,
email,
phone,
postedOn,
description
} = job;
return (
<div>
<Row>
<Well>
<Thumbnail
alt={ company + 'company logo' }
src={ logo }
style={ thumbnailStyle } />
<Panel>
Position: { position }
Location: { city }, { state }
<br />
Contact: { email || phone || 'N/A' }
<br />
Posted On: { moment(postedOn).format('MMMM Do, YYYY') }
</Panel>
<p>{ description }</p>
</Well>
</Row>
</div>
);
}
});

View File

@ -1,27 +1,104 @@
import { Actions } from 'thundercats'; import { Actions } from 'thundercats';
import store from 'store';
import debugFactory from 'debug'; import debugFactory from 'debug';
const debug = debugFactory('freecc:jobs:actions'); const debug = debugFactory('freecc:jobs:actions');
const assign = Object.assign;
export default Actions({ export default Actions({
setJobs: null, setJobs: null,
getJob(id) { // findJob assumes that the job is already in the list of jobs
return { id }; findJob(id) {
return oldState => {
const { currentJob = {}, jobs = [] } = oldState;
// currentJob already set
// do nothing
if (currentJob.id === id) {
return null;
}
const foundJob = jobs.reduce((newJob, job) => {
if (job.id === id) {
return job;
}
return newJob;
}, null);
// if no job found this will be null which is a op noop
return foundJob ?
assign({}, oldState, { currentJob: foundJob }) :
null;
};
}, },
setError: null,
getJob: null,
getJobs(params) { getJobs(params) {
return { params }; return { params };
},
openModal() {
return { showModal: true };
},
closeModal() {
return { showModal: false };
},
handleForm(value) {
return {
transform(oldState) {
const { form } = oldState;
const newState = assign({}, oldState);
newState.form = assign(
{},
form,
value
);
return newState;
}
};
},
saveForm: null,
getSavedForm: null,
setForm(form) {
return { form };
} }
}) })
.refs({ displayName: 'JobActions' }) .refs({ displayName: 'JobActions' })
.init(({ instance: jobActions, args: [services] }) => { .init(({ instance: jobActions, args: [services] }) => {
jobActions.getJobs.subscribe(() => { jobActions.getJobs.subscribe(() => {
services.read('job', null, null, (err, jobs) => { services.read('jobs', null, null, (err, jobs) => {
if (err) { if (err) {
debug('job services experienced an issue', err); debug('job services experienced an issue', err);
jobActions.setJobs({ jobs: [] }); return jobActions.setError({ err });
} }
jobActions.setJobs({ jobs }); jobActions.setJobs({ jobs });
}); });
}); });
jobActions.getJob.subscribe(({ id, isPrimed }) => {
// job is already set, do nothing.
if (isPrimed) {
debug('job is primed');
return;
}
services.read('jobs', { id }, null, (err, job) => {
if (err) {
debug('job services experienced an issue', err);
return jobActions.setError({ err });
}
if (job) {
jobActions.setJobs({ currentJob: job });
}
jobActions.setJobs({});
});
});
jobActions.saveForm.subscribe((form) => {
store.set('newJob', form);
});
jobActions.getSavedForm.subscribe(() => {
const job = store.get('newJob');
if (job && !Array.isArray(job) && typeof job === 'object') {
jobActions.setForm(job);
}
});
return jobActions; return jobActions;
}); });

View File

@ -1,10 +1,30 @@
import { Store } from 'thundercats'; import { Store } from 'thundercats';
const { setter } = Store; const {
createRegistrar,
setter,
transformer
} = Store;
export default Store() export default Store({ showModal: false })
.refs({ displayName: 'JobsStore' }) .refs({ displayName: 'JobsStore' })
.init(({ instance: jobsStore, args: [cat] }) => { .init(({ instance: jobsStore, args: [cat] }) => {
let jobActions = cat.getActions('JobActions'); const {
jobsStore.register(setter(jobActions.setJobs)); setJobs,
findJob,
setError,
openModal,
closeModal,
handleForm,
setForm
} = cat.getActions('JobActions');
const register = createRegistrar(jobsStore);
register(setter(setJobs));
register(setter(setError));
register(setter(openModal));
register(setter(closeModal));
register(setter(setForm));
register(transformer(findJob));
register(handleForm);
}); });

View File

@ -1,14 +1,26 @@
import Jobs from './components/Jobs.jsx'; import Jobs from './components/Jobs.jsx';
import NewJob from './components/NewJob.jsx';
import Show from './components/Show.jsx';
import Preview from './components/Preview.jsx';
/* /*
* show: /jobs * index: /jobs list jobs
* showOne: /jobs/:id * show: /jobs/:id show one job
* edit /jobs/:id * create /jobs/new create a new job
* delete /jobs/:id
* createOne /jobs/new
*/ */
export default { export default {
path: 'jobs', childRoutes: [{
path: '/jobs',
component: Jobs component: Jobs
}, {
path: 'jobs/new',
component: NewJob
}, {
path: 'jobs/new/preview',
component: Preview
}, {
path: 'jobs/:id',
component: Show
}]
}; };

View File

@ -0,0 +1,22 @@
const defaults = {
'string': {
value: '',
valid: false,
pristine: true,
type: 'string'
},
bool: {
value: false,
type: 'boolean'
}
};
export function getDefaults(type, value) {
if (!type) {
return defaults['string'];
}
if (value) {
return Object.assign({}, defaults[type], { value });
}
return Object.assign({}, defaults[type]);
}

View File

@ -3,12 +3,8 @@ import Hikes from './Hikes';
export default { export default {
path: '/', path: '/',
getChildRoutes(locationState, cb) { childRoutes: [
setTimeout(() => {
cb(null, [
Jobs, Jobs,
Hikes Hikes
]); ]
}, 0);
}
}; };

View File

@ -1,6 +1,7 @@
{ {
"name": "job", "name": "job",
"base": "PersistedModel", "base": "PersistedModel",
"strict": true,
"idInjection": true, "idInjection": true,
"trackChanges": false, "trackChanges": false,
"properties": { "properties": {
@ -29,6 +30,9 @@
"state": { "state": {
"type": "string" "type": "string"
}, },
"url": {
"type": "string"
},
"country": { "country": {
"type": "string" "type": "string"
}, },
@ -38,7 +42,7 @@
"description": { "description": {
"type": "string" "type": "string"
}, },
"isApproverd": { "isApproved": {
"type": "boolean" "type": "boolean"
}, },
"isHighlighted": { "isHighlighted": {

View File

@ -34,10 +34,6 @@
"description": { "description": {
"type": "string" "type": "string"
}, },
"originalStoryAuthorEmail": {
"type": "string",
"default": ""
},
"rank": { "rank": {
"type": "number", "type": "number",
"default": 0 "default": 0

View File

@ -88,39 +88,6 @@
"google": { "google": {
"type": "string" "type": "string"
}, },
"completedBonfires": {
"type": [
{
"id": "string",
"name": "string",
"completedWith": "string",
"completedDate": "string",
"solution": "string"
}
],
"default": []
},
"uncompletedCoursewares": {
"type": "array",
"default": []
},
"completedCoursewares": {
"type": [
{
"completedDate": {
"type": "string",
"defaultFn": "now"
},
"id": "string",
"name": "string",
"completedWith": "string",
"solution": "string",
"githubLink": "string",
"verified": "boolean"
}
],
"default": []
},
"currentStreak": { "currentStreak": {
"type": "number", "type": "number",
"default": 0 "default": 0
@ -133,13 +100,22 @@
"type": "boolean", "type": "boolean",
"default": true "default": true
}, },
"isLocked": {
"type": "boolean",
"default": false
},
"currentChallenge": { "currentChallenge": {
"type": {} "type": {}
}, },
"isUniqMigrated": {
"type": "boolean",
"default": false
},
"completedChallenges": { "completedChallenges": {
"type": [ "type": [
{ {
"completedDate": "number", "completedDate": "number",
"lastUpdated": "number",
"id": "string", "id": "string",
"name": "string", "name": "string",
"completedWith": "string", "completedWith": "string",
@ -157,6 +133,9 @@
"rand": { "rand": {
"type": "number", "type": "number",
"index": true "index": true
},
"tshirtVote": {
"type": "number"
} }
}, },
"validations": [], "validations": [],

View File

@ -1,3 +1,6 @@
// enable debug for gulp
process.env.DEBUG = process.env.DEBUG || 'freecc:*';
require('babel-core/register'); require('babel-core/register');
var Rx = require('rx'), var Rx = require('rx'),
gulp = require('gulp'), gulp = require('gulp'),
@ -6,6 +9,7 @@ var Rx = require('rx'),
// utils // utils
plumber = require('gulp-plumber'), plumber = require('gulp-plumber'),
notify = require('gulp-notify'), notify = require('gulp-notify'),
gutil = require('gulp-util'),
reduce = require('gulp-reduce-file'), reduce = require('gulp-reduce-file'),
sortKeys = require('sort-keys'), sortKeys = require('sort-keys'),
debug = require('debug')('freecc:gulp'), debug = require('debug')('freecc:gulp'),
@ -25,6 +29,7 @@ var Rx = require('rx'),
// rev // rev
rev = require('gulp-rev'), rev = require('gulp-rev'),
revReplace = require('gulp-rev-replace'), revReplace = require('gulp-rev-replace'),
revDel = require('rev-del'),
// lint // lint
jsonlint = require('gulp-jsonlint'), jsonlint = require('gulp-jsonlint'),
@ -33,6 +38,7 @@ var Rx = require('rx'),
Rx.config.longStackSupport = true; Rx.config.longStackSupport = true;
var __DEV__ = process.env.NODE_ENV !== 'production';
var reloadDelay = 1000; var reloadDelay = 1000;
var reload = sync.reload; var reload = sync.reload;
var paths = { var paths = {
@ -43,6 +49,8 @@ var paths = {
'!public/js/bundle*', '!public/js/bundle*',
'node_modules/', 'node_modules/',
'client/', 'client/',
'seed',
'server/manifests/*.json',
'server/rev-manifest.json' 'server/rev-manifest.json'
], ],
@ -67,8 +75,7 @@ var paths = {
], ],
dependents: [ dependents: [
'client/commonFramework.js', 'client/commonFramework.js'
'client/sandbox.js'
], ],
less: './client/less/main.less', less: './client/less/main.less',
@ -107,11 +114,22 @@ function errorHandler() {
this.emit('end'); this.emit('end');
} }
function delRev(dest, manifestName) {
// in production do not delete old revisions
if (!__DEV__) {
return gutil.noop();
}
return revDel({
oldManifest: path.join(paths.manifest, manifestName),
dest: dest
});
}
gulp.task('serve', function(cb) { gulp.task('serve', function(cb) {
var called = false; var called = false;
nodemon({ nodemon({
script: paths.server, script: paths.server,
ext: '.js .json', ext: '.jsx .js .json',
ignore: paths.serverIgnore, ignore: paths.serverIgnore,
exec: path.join(__dirname, 'node_modules/.bin/babel-node'), exec: path.join(__dirname, 'node_modules/.bin/babel-node'),
env: { env: {
@ -143,7 +161,7 @@ var syncDepenedents = [
'js', 'js',
'less', 'less',
'dependents', 'dependents',
'pack-client', 'pack-watch',
'build-manifest' 'build-manifest'
]; ];
@ -173,6 +191,9 @@ gulp.task('lint-json', function() {
gulp.task('test-challenges', ['lint-json']); gulp.task('test-challenges', ['lint-json']);
gulp.task('pack-client', function() { gulp.task('pack-client', function() {
var manifestName = 'react-manifest.json';
var dest = webpackConfig.output.path;
return gulp.src(webpackConfig.entry) return gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler })) .pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign( .pipe(webpack(Object.assign(
@ -180,30 +201,73 @@ gulp.task('pack-client', function() {
webpackConfig, webpackConfig,
webpackOptions webpackOptions
))) )))
.pipe(gulp.dest(webpackConfig.output.path)) .pipe(gulp.dest(dest))
.pipe(rev()) .pipe(rev())
// copy files to public // copy files to public
.pipe(gulp.dest(webpackConfig.output.path)) .pipe(gulp.dest(dest))
// create and merge manifest // create manifest
.pipe(rev.manifest('react-manifest.json')) .pipe(rev.manifest(manifestName))
// delete old rev
.pipe(delRev(
dest,
manifestName
))
.pipe(gulp.dest(paths.manifest)); .pipe(gulp.dest(paths.manifest));
}); });
gulp.task('pack-watch', function() { var defaultStatsOptions = {
return gulp.src(webpackConfig.entry) colors: gutil.colors.supportsColor,
hash: false,
timings: false,
chunks: false,
chunkModules: false,
modules: false,
children: true,
version: true,
cached: false,
cachedAssets: false,
reasons: false,
source: false,
errorDetails: false
};
gulp.task('pack-watch', function(cb) {
var called = false;
gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler })) .pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign( .pipe(webpack(Object.assign(
{}, {},
webpackConfig, webpackConfig,
webpackOptions, webpackOptions,
{ watch: true } { watch: true }
))) ), null, function(notUsed, stats) {
.pipe(gulp.dest(webpackConfig.output.path)) if (stats) {
gutil.log(stats.toString(defaultStatsOptions));
}
if (!called) {
debug('webpack watch completed');
called = true;
cb();
}
}))
.pipe(gulp.dest(webpackConfig.output.path));
});
gulp.task('pack-watch-manifest', function() {
var manifestName = 'react-manifest.json';
var dest = webpackConfig.output.path;
return gulp.src(dest + '/bundle.js')
.pipe(rev()) .pipe(rev())
// copy files to public // copy files to public
.pipe(gulp.dest(webpackConfig.output.path)) .pipe(gulp.dest(dest))
// create manifest // create manifest
.pipe(rev.manifest('react-manifest.json')) .pipe(rev.manifest(manifestName))
.pipe(delRev(
dest,
manifestName
))
.pipe(gulp.dest(paths.manifest)); .pipe(gulp.dest(paths.manifest));
}); });
@ -217,32 +281,45 @@ gulp.task('pack-node', function() {
gulp.task('pack', ['pack-client', 'pack-node']); gulp.task('pack', ['pack-client', 'pack-node']);
gulp.task('less', function() { gulp.task('less', function() {
var manifestName = 'css-manifest.json';
var dest = paths.css;
return gulp.src(paths.less) return gulp.src(paths.less)
.pipe(plumber({ errorHandler: errorHandler })) .pipe(plumber({ errorHandler: errorHandler }))
// copile // copile
.pipe(less({ .pipe(less({
paths: [ path.join(__dirname, 'less', 'includes') ] paths: [ path.join(__dirname, 'less', 'includes') ]
})) }))
.pipe(gulp.dest(paths.css)) .pipe(gulp.dest(dest))
// add revision // add revision
.pipe(rev()) .pipe(rev())
// copy files to public // copy files to public
.pipe(gulp.dest(paths.css)) .pipe(gulp.dest(dest))
// create and merge manifest // create and merge manifest
.pipe(rev.manifest('css-manifest.json')) .pipe(rev.manifest(manifestName))
.pipe(delRev(
dest,
manifestName
))
.pipe(gulp.dest(paths.manifest)); .pipe(gulp.dest(paths.manifest));
}); });
gulp.task('js', function() { gulp.task('js', function() {
var manifestName = 'js-manifest.json';
var dest = paths.publicJs;
return gulp.src(paths.js) return gulp.src(paths.js)
.pipe(plumber({ errorHandler: errorHandler })) .pipe(plumber({ errorHandler: errorHandler }))
.pipe(gulp.dest(paths.publicJs)) .pipe(gulp.dest(dest))
// create registry file // create registry file
.pipe(rev()) .pipe(rev())
// copy revisioned assets to dest // copy revisioned assets to dest
.pipe(gulp.dest(paths.publicJs)) .pipe(gulp.dest(dest))
// create manifest file // create manifest file
.pipe(rev.manifest('js-manifest.json')) .pipe(rev.manifest(manifestName))
.pipe(delRev(
dest,
manifestName
))
// copy manifest file to dest // copy manifest file to dest
.pipe(gulp.dest(paths.manifest)); .pipe(gulp.dest(paths.manifest));
}); });
@ -250,6 +327,9 @@ gulp.task('js', function() {
// commonFramework depend on iFrameScripts // commonFramework depend on iFrameScripts
// sandbox depends on plugin // sandbox depends on plugin
gulp.task('dependents', ['js'], function() { gulp.task('dependents', ['js'], function() {
var manifestName = 'dependents-manifest.json';
var dest = paths.publicJs;
var manifest = gulp.src( var manifest = gulp.src(
path.join(__dirname, paths.manifest, 'js-manifest.json') path.join(__dirname, paths.manifest, 'js-manifest.json')
); );
@ -257,9 +337,14 @@ gulp.task('dependents', ['js'], function() {
return gulp.src(paths.dependents) return gulp.src(paths.dependents)
.pipe(plumber({ errorHandler: errorHandler })) .pipe(plumber({ errorHandler: errorHandler }))
.pipe(revReplace({ manifest: manifest })) .pipe(revReplace({ manifest: manifest }))
.pipe(gulp.dest(dest))
.pipe(rev()) .pipe(rev())
.pipe(gulp.dest(paths.publicJs)) .pipe(gulp.dest(dest))
.pipe(rev.manifest('dependents-manifest.json')) .pipe(rev.manifest(manifestName))
.pipe(delRev(
dest,
manifestName
))
.pipe(gulp.dest(paths.manifest)); .pipe(gulp.dest(paths.manifest));
}); });
@ -301,7 +386,9 @@ var watchDependents = [
'dependents', 'dependents',
'serve', 'serve',
'sync', 'sync',
'build-manifest' 'build-manifest',
'pack-watch',
'pack-watch-manifest'
]; ];
gulp.task('watch', watchDependents, function() { gulp.task('watch', watchDependents, function() {
@ -311,7 +398,15 @@ gulp.task('watch', watchDependents, function() {
gulp.watch(paths.js, ['js', 'dependents']); gulp.watch(paths.js, ['js', 'dependents']);
gulp.watch(paths.dependents, ['dependents']); gulp.watch(paths.dependents, ['dependents']);
gulp.watch(paths.manifest + '/*.json', ['build-manifest-watch']); gulp.watch(paths.manifest + '/*.json', ['build-manifest-watch']);
gulp.watch(webpackConfig.output.path + '/bundle.js', ['pack-watch-manifest']);
}); });
gulp.task('default', ['less', 'serve', 'sync', 'watch', 'pack-watch']); gulp.task('default', [
'less',
'serve',
'pack-watch',
'pack-watch-manifest',
'watch',
'sync'
]);

View File

@ -11,25 +11,15 @@
"prestart-production": "bower cache clean && bower install && gulp build", "prestart-production": "bower cache clean && bower install && gulp build",
"start-production": "node pm2Start", "start-production": "node pm2Start",
"lint": "eslint --ext=.js,.jsx .", "lint": "eslint --ext=.js,.jsx .",
"test": "mocha --compilers js:babel/register" "test": "gulp test-challenges"
}, },
"license": "(BSD-3-Clause AND CC-BY-SA-4.0)", "license": "(BSD-3-Clause AND CC-BY-SA-4.0)",
"contributors": [
{
"name": "Quincy Larson",
"url": "https://github.com/QuincyLarson"
},
{
"name": "Nathan Leniz",
"url": "https://github.com/terakilobyte"
}
],
"dependencies": { "dependencies": {
"accepts": "~1.2.5", "accepts": "~1.2.5",
"async": "~0.9.0", "async": "~0.9.0",
"babel": "5.6.14", "babel": "5.8.23",
"babel-core": "5.6.15", "babel-core": "5.8.23",
"babel-eslint": "^4.0.5", "babel-eslint": "4.1.1",
"babel-loader": "5.2.2", "babel-loader": "5.2.2",
"bcrypt-nodejs": "~0.0.3", "bcrypt-nodejs": "~0.0.3",
"body-parser": "^1.13.2", "body-parser": "^1.13.2",
@ -46,6 +36,7 @@
"dedent": "^0.4.0", "dedent": "^0.4.0",
"dotenv": "~0.4.0", "dotenv": "~0.4.0",
"errorhandler": "~1.3.0", "errorhandler": "~1.3.0",
"es6-map": "^0.1.1",
"eslint": "^1.1.0", "eslint": "^1.1.0",
"eslint-plugin-react": "^3.2.1", "eslint-plugin-react": "^3.2.1",
"express": "~4.10.4", "express": "~4.10.4",
@ -63,13 +54,14 @@
"gulp-reduce-file": "0.0.1", "gulp-reduce-file": "0.0.1",
"gulp-rev": "^6.0.1", "gulp-rev": "^6.0.1",
"gulp-rev-replace": "^0.4.2", "gulp-rev-replace": "^0.4.2",
"gulp-util": "^3.0.6",
"gulp-webpack": "^1.5.0", "gulp-webpack": "^1.5.0",
"helmet": "~0.9.0", "helmet": "~0.9.0",
"helmet-csp": "^0.2.3", "helmet-csp": "^0.2.3",
"history": "^1.9.0",
"jade": "~1.8.0", "jade": "~1.8.0",
"json-loader": "^0.5.2", "json-loader": "^0.5.2",
"less": "~1.7.5", "less": "~2.5.1",
"less-middleware": "~2.0.1",
"lodash": "^3.9.3", "lodash": "^3.9.3",
"loopback": "https://github.com/FreeCodeCamp/loopback.git#fix/no-password", "loopback": "https://github.com/FreeCodeCamp/loopback.git#fix/no-password",
"loopback-boot": "2.8.2", "loopback-boot": "2.8.2",
@ -95,33 +87,33 @@
"pmx": "^0.3.16", "pmx": "^0.3.16",
"ramda": "~0.10.0", "ramda": "~0.10.0",
"react": "^0.13.3", "react": "^0.13.3",
"react-bootstrap": "^0.23.7", "react-bootstrap": "~0.23.7",
"react-motion": "~0.1.0", "react-motion": "~0.1.0",
"react-router": "https://github.com/BerkeleyTrue/react-router#freecodecamp", "react-router": "^1.0.0-rc1",
"react-vimeo": "^0.0.3", "react-vimeo": "^0.0.3",
"request": "~2.53.0", "request": "~2.53.0",
"rev-del": "^1.0.5",
"rx": "^2.5.3", "rx": "^2.5.3",
"sanitize-html": "~1.6.1", "sanitize-html": "~1.6.1",
"sort-keys": "^1.1.1", "sort-keys": "^1.1.1",
"source-map-support": "^0.3.2", "source-map-support": "^0.3.2",
"store": "https://github.com/berkeleytrue/store.js.git#feature/noop-server",
"thundercats": "^2.1.0", "thundercats": "^2.1.0",
"thundercats-react": "^0.1.0", "thundercats-react": "^0.1.0",
"twit": "~1.1.20", "twit": "~1.1.20",
"uglify-js": "~2.4.15", "uglify-js": "~2.4.15",
"validator": "~3.22.1", "validator": "^3.22.1",
"webpack": "^1.9.12", "webpack": "^1.9.12",
"xss-filters": "^1.2.6",
"yui": "~3.18.1" "yui": "~3.18.1"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^3.1.7",
"blessed": "~0.0.37", "blessed": "~0.0.37",
"bower-main-files": "~0.0.4", "bower-main-files": "~0.0.4",
"browser-sync": "~1.8.1", "browser-sync": "~1.8.1",
"browserify": "^10.2.4", "browserify": "^10.2.4",
"chai": "~1.10.0", "chai": "~1.10.0",
"envify": "^3.4.0", "envify": "^3.4.0",
"eslint": "^0.21.2",
"eslint-plugin-react": "^2.3.0",
"gulp": "~3.8.8", "gulp": "~3.8.8",
"gulp-eslint": "~0.9.0", "gulp-eslint": "~0.9.0",
"gulp-inject": "~1.0.2", "gulp-inject": "~1.0.2",

9
public/css/lato.css Normal file
View File

@ -0,0 +1,9 @@
@font-face {
font-family: "Lato";
src: url(/fonts/Lato-Regular.ttf) format("truetype");
}
@font-face {
font-family: "Lato Light";
src: url(/fonts/Lato-Light.ttf) format("truetype");
}

9
public/css/ubuntu.css Normal file
View File

@ -0,0 +1,9 @@
@font-face {
font-family: "Ubuntu";
src: url(/fonts/Ubuntu-Regular.ttf) format("truetype");
}
@font-face {
font-family: "Ubuntu Mono";
src: url(/fonts/UbuntuMono-Regular.ttf) format("truetype");
}

0
public/fonts/Lato-Light.ttf Executable file → Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

0
public/fonts/ionicons.eot Executable file → Normal file
View File

0
public/fonts/ionicons.svg Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 326 KiB

0
public/fonts/ionicons.ttf Executable file → Normal file
View File

0
public/fonts/ionicons.woff Executable file → Normal file
View File

View File

@ -1,19 +1,20 @@
// MDN Links /**
* MDN Links
*
* These links are for Bonfires. Each key/value pair is used to render a Bonfire with appropriate links.
* The text of the key is what the link text will be, e.g. <a href="https://developer ...">Global Array Object</a>
* General convention is to use the page title of the MDN reference page.
*
**/
/* These links are for Bonfires. Each key/value pair is used to render a Bonfire with appropriate links. var links = {
The text of the key is what the link text will be, e.g. <a href="https://developer ...">Global Array Object</a>
General convention is to use the page title of the MDN reference page.
*/
var links =
{
// ========= NON MDN REFS // ========= NON MDN REFS
"Currying": "https://leanpub.com/javascript-allonge/read#pabc", "Currying": "https://leanpub.com/javascript-allonge/read#pabc",
"Smallest Common Multiple": "https://www.mathsisfun.com/least-common-multiple.html", "Smallest Common Multiple": "https://www.mathsisfun.com/least-common-multiple.html",
"Permutations": "https://www.mathsisfun.com/combinatorics/combinations-permutations.html", "Permutations": "https://www.mathsisfun.com/combinatorics/combinations-permutations.html",
"HTML Entities": "http://dev.w3.org/html5/html-author/charref", "HTML Entities": "http://dev.w3.org/html5/html-author/charref",
"Symmetric Difference": "https://www.youtube.com/watch?v=PxffSUQRkG4", "Symmetric Difference": "https://www.youtube.com/watch?v=PxffSUQRkG4",
"Roman Numerals": "http://www.mathsisfun.com/roman-numerals.html",
// ========= GLOBAL OBJECTS // ========= GLOBAL OBJECTS
"Global Array Object": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array", "Global Array Object": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array",
@ -56,6 +57,7 @@ var links =
"String.toLowerCase()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase", "String.toLowerCase()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase",
"String.toString()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toString", "String.toString()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toString",
"String.toUpperCase()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase", "String.toUpperCase()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase",
// ======== ARRAY METHODS // ======== ARRAY METHODS
"Array.concat()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat", "Array.concat()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat",
"Array.every()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every", "Array.every()": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every",

View File

@ -1,41 +1,45 @@
{ {
"name": "Advanced Algorithm Scripting", "name": "Advanced Algorithm Scripting",
"order": 0.013, "order": 15,
"challenges": [ "challenges": [
{ {
"id": "aff0395860f5d3034dc0bfc9", "id": "aff0395860f5d3034dc0bfc9",
"title": "Validate US Telephone Numbers", "title": "Validate US Telephone Numbers",
"difficulty": "4.01",
"description": [ "description": [
"Return true if the passed string is a valid US phone number", "Return true if the passed string is a valid US phone number",
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:", "The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
"555-555-5555, (555)555-5555, (555) 555-5555, 555 555 5555, 5555555555, 1 555 555 5555", "<code>555-555-5555</code>",
"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.", "<code>(555)555-5555</code>",
"<code>(555) 555-5555</code>",
"<code>555 555 5555</code>",
"<code>5555555555</code>",
"<code>1 555 555 5555</code>",
"For this challenge you will be presented with a string such as <code>800-692-7753</code> or <code>8oo-six427676;laskdjf</code>. 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 <code>1</code>. Return true if the string is a valid US phone number; otherwise false.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
], ],
"tests": [ "tests": [
"expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");", "assert.isBoolean(telephoneCheck(\"555-555-5555\"), 'message: should return a boolean.');",
"assert.deepEqual(telephoneCheck(\"1 555-555-5555\"), true);", "assert(telephoneCheck(\"1 555-555-5555\") === true, 'message: <code>telephoneCheck(\"1 555-555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"1 (555) 555-5555\"), true);", "assert(telephoneCheck(\"1 (555) 555-5555\") === true, 'message: <code>telephoneCheck(\"1 (555) 555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"5555555555\"), true);", "assert(telephoneCheck(\"5555555555\") === true, 'message: <code>telephoneCheck(\"5555555555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);", "assert(telephoneCheck(\"555-555-5555\") === true, 'message: <code>telephoneCheck(\"555-555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"(555)555-5555\"), true);", "assert(telephoneCheck(\"(555)555-5555\") === true, 'message: <code>telephoneCheck(\"(555)555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"1(555)555-5555\"), true);", "assert(telephoneCheck(\"1(555)555-5555\") === true, 'message: <code>telephoneCheck(\"1(555)555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"1 555 555 5555\"), true);", "assert(telephoneCheck(\"1 555 555 5555\") === true, 'message: <code>telephoneCheck(\"1 555 555 5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);", "assert(telephoneCheck(\"555-555-5555\") === true, 'message: <code>telephoneCheck(\"555-555-5555\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);", "assert(telephoneCheck(\"1 456 789 4444\") === true, 'message: <code>telephoneCheck(\"1 456 789 4444\")</code> should return true.');",
"assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);", "assert(telephoneCheck(\"123**&!!asdf#\") === false, 'message: <code>telephoneCheck(\"123**&!!asdf#\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"55555555\"), false);", "assert(telephoneCheck(\"55555555\") === false, 'message: <code>telephoneCheck(\"55555555\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);", "assert(telephoneCheck(\"(6505552368)\") === false, 'message: <code>telephoneCheck(\"(6505552368)\")</code> should return false');",
"assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);", "assert(telephoneCheck(\"2 (757) 622-7382\") === false, 'message: <code>telephoneCheck(\"2 (757) 622-7382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);", "assert(telephoneCheck(\"0 (757) 622-7382\") === false, 'message: <code>telephoneCheck(\"0 (757) 622-7382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);", "assert(telephoneCheck(\"-1 (757) 622-7382\") === false, 'message: <code>telephoneCheck(\"-1 (757) 622-7382\")</code> should return false');",
"assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);", "assert(telephoneCheck(\"2 757 622-7382\") === false, 'message: <code>telephoneCheck(\"2 757 622-7382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);", "assert(telephoneCheck(\"10 (757) 622-7382\") === false, 'message: <code>telephoneCheck(\"10 (757) 622-7382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"27576227382\"), false);", "assert(telephoneCheck(\"27576227382\") === false, 'message: <code>telephoneCheck(\"27576227382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);", "assert(telephoneCheck(\"(275)76227382\") === false, 'message: <code>telephoneCheck(\"(275)76227382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);", "assert(telephoneCheck(\"2(757)6227382\") === false, 'message: <code>telephoneCheck(\"2(757)6227382\")</code> should return false.');",
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);" "assert(telephoneCheck(\"2(757)622-7382\") === false, 'message: <code>telephoneCheck(\"2(757)622-7382\")</code> should return false.');"
], ],
"challengeSeed": [ "challengeSeed": [
"function telephoneCheck(str) {", "function telephoneCheck(str) {",
@ -66,7 +70,6 @@
{ {
"id": "a3f503de51cf954ede28891d", "id": "a3f503de51cf954ede28891d",
"title": "Symmetric Difference", "title": "Symmetric Difference",
"difficulty": "4.02",
"description": [ "description": [
"Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.", "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.", "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.",
@ -74,16 +77,16 @@
], ],
"challengeSeed": [ "challengeSeed": [
"function sym(args) {", "function sym(args) {",
" return arguments;", " return args;",
"}", "}",
"", "",
"sym([1, 2, 3], [5, 2, 1, 4]);" "sym([1, 2, 3], [5, 2, 1, 4]);"
], ],
"tests": [ "tests": [
"assert.deepEqual(sym([1, 2, 3], [5, 2, 1, 4]), [3, 5, 4], 'should return an array of unique values');", "assert.sameMembers(sym([1, 2, 3], [5, 2, 1, 4]), [3, 5, 4], 'message: <code>sym([1, 2, 3], [5, 2, 1, 4])</code> should return <code>[3, 5, 4]</code>.');",
"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.sameMembers(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'message: <code>sym([1, 2, 5], [2, 3, 5], [3, 4, 5])</code> should return <code>[1, 4, 5]</code>');",
"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.sameMembers(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], 'message: <code>sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])</code> should return <code>[1, 4, 5]</code>.');",
"assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');" "assert.sameMembers(sym([1, 1]), [1], 'message: <code>sym([1, 1])</code> should return <code>[1]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.reduce()", "Array.reduce()",
@ -105,7 +108,6 @@
{ {
"id": "aa2e6f85cab2ab736c9a9b24", "id": "aa2e6f85cab2ab736c9a9b24",
"title": "Exact Change", "title": "Exact Change",
"difficulty": "4.03",
"description": [ "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.", "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.", "cid is a 2d array listing available currency.",
@ -121,26 +123,26 @@
"}", "}",
"", "",
"// Example cash-in-drawer array:", "// Example cash-in-drawer array:",
"// [['PENNY', 1.01],", "// [[\"PENNY\", 1.01],",
"// ['NICKEL', 2.05],", "// [\"NICKEL\", 2.05],",
"// ['DIME', 3.10],", "// [\"DIME\", 3.10],",
"// ['QUARTER', 4.25],", "// [\"QUARTER\", 4.25],",
"// ['ONE', 90.00],", "// [\"ONE\", 90.00],",
"// ['FIVE', 55.00],", "// [\"FIVE\", 55.00],",
"// ['TEN', 20.00],", "// [\"TEN\", 20.00],",
"// ['TWENTY', 60.00],", "// [\"TWENTY\", 60.00],",
"// ['ONE HUNDRED', 100.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]]);" "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": [ "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');", "assert.isArray(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]]), 'message: <code>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]])</code> should return an 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');", "assert.isString(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]]), 'message: <code>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]])</code> should return 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.isString(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]]), 'message: <code>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]])</code> should return 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(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]], 'message: <code>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]])</code> should return <code>[[\"QUARTER\", 0.50]]</code>.');",
"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(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]], 'message: <code>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]])</code> should return <code>[[\"TWENTY\", 60.00], [\"TEN\", 20.00], [\"FIVE\", 15], [\"ONE\", 1], [\"QUARTER\", 0.50], [\"DIME\", 0.20], [\"PENNY\", 0.04]]</code>.');",
"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.01], [\"NICKEL\", 0], [\"DIME\", 0], [\"QUARTER\", 0], [\"ONE\", 0], [\"FIVE\", 0], [\"TEN\", 0], [\"TWENTY\", 0], [\"ONE HUNDRED\", 0]]), \"Insufficient Funds\", 'message: <code>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]])</code> should return \"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');" "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\", 'message: <code>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]])</code> should return \"Closed\".');"
], ],
"MDNlinks": [ "MDNlinks": [
"Global Object" "Global Object"
@ -161,7 +163,6 @@
{ {
"id": "a56138aff60341a09ed6c480", "id": "a56138aff60341a09ed6c480",
"title": "Inventory Update", "title": "Inventory Update",
"difficulty": "4.04",
"description": [ "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.", "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.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -174,28 +175,28 @@
"", "",
"// Example inventory lists", "// Example inventory lists",
"var curInv = [", "var curInv = [",
" [21, 'Bowling Ball'],", " [21, \"Bowling Ball\"],",
" [2, 'Dirty Sock'],", " [2, \"Dirty Sock\"],",
" [1, 'Hair Pin'],", " [1, \"Hair Pin\"],",
" [5, 'Microphone']", " [5, \"Microphone\"]",
"];", "];",
"", "",
"var newInv = [", "var newInv = [",
" [2, 'Hair Pin'],", " [2, \"Hair Pin\"],",
" [3, 'Half-Eaten Apple'],", " [3, \"Half-Eaten Apple\"],",
" [67, 'Bowling Ball'],", " [67, \"Bowling Ball\"],",
" [7, 'Toothpaste']", " [7, \"Toothpaste\"]",
"];", "];",
"", "",
"inventory(curInv, newInv);" "inventory(curInv, newInv);"
], ],
"tests": [ "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.isArray(inventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]), 'message: <code>inventory()</code> should return an 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.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, 'message: <code>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</code> should return an array with a length of 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\"]], [[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\"]], 'message: <code>inventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]])</code> should return <code>[[88, \"Bowling Ball\"], [2, \"Dirty Sock\"], [3, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [5, \"Microphone\"], [7, \"Toothpaste\"]]</code>.');",
"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([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], []), [[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], 'message: <code>inventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [])</code> should return <code>[[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]]</code>.');",
"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([], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]), [[67, \"Bowling Ball\"], [2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [7, \"Toothpaste\"]], 'message: <code>inventory([], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]])</code> should return <code>[[67, \"Bowling Ball\"], [2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [7, \"Toothpaste\"]]</code>.');",
"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']]);" "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\"]], 'message: <code>inventory([[0, \"Bowling Ball\"], [0, \"Dirty Sock\"], [0, \"Hair Pin\"], [0, \"Microphone\"]], [[1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [1, \"Bowling Ball\"], [1, \"Toothpaste\"]])</code> should return <code>[[1, \"Bowling Ball\"], [0, \"Dirty Sock\"], [1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [0, \"Microphone\"], [1, \"Toothpaste\"]]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Global Array Object" "Global Array Object"
@ -216,7 +217,6 @@
{ {
"id": "a7bf700cd123b9a54eef01d5", "id": "a7bf700cd123b9a54eef01d5",
"title": "No repeats please", "title": "No repeats please",
"difficulty": "4.05",
"description": [ "description": [
"Return the number of total permutations of the provided string that don't have repeated consecutive letters.", "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.", "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.",
@ -230,13 +230,13 @@
"permAlone('aab');" "permAlone('aab');"
], ],
"tests": [ "tests": [
"expect(permAlone('aab')).to.be.a('number');", "assert.isNumber(permAlone('aab'), 'message: <code>permAlone()</code> should return a number.');",
"expect(permAlone('aab')).to.equal(2);", "assert.strictEqual(permAlone('aab'), 2, 'message: <code>permAlone(aab)</code> should return 2.');",
"expect(permAlone('aaa')).to.equal(0);", "assert.strictEqual(permAlone('aaa'), 0, 'message: <code>permAlone(aaa)</code> should return 0.');",
"expect(permAlone('aabb')).to.equal(8);", "assert.strictEqual(permAlone('aabb'), 8, 'message: <code>permAlone(aabb)</code> should return 8.');",
"expect(permAlone('abcdefa')).to.equal(3600);", "assert.strictEqual(permAlone('abcdefa'), 3600, 'message: <code>permAlone(abcdefa)</code> should return 3600.');",
"expect(permAlone('abfdefa')).to.equal(2640);", "assert.strictEqual(permAlone('abfdefa'), 2640, 'message: <code>permAlone(abfdefa)</code> should return 2640.');",
"expect(permAlone('zzzzzzzz')).to.equal(0);" "assert.strictEqual(permAlone('zzzzzzzz'), 0, 'message: <code>permAlone(zzzzzzzz)</code> should return 0.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Permutations", "Permutations",
@ -259,7 +259,6 @@
"id": "a19f0fbe1872186acd434d5a", "id": "a19f0fbe1872186acd434d5a",
"title": "Friendly Date Ranges", "title": "Friendly Date Ranges",
"dashedName": "bonfire-friendly-date-ranges", "dashedName": "bonfire-friendly-date-ranges",
"difficulty": "4.06",
"description": [ "description": [
"Implement a way of converting two dates into a more friendly date range that could be presented to a user.", "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.", "It must not show any redundant information in the date range.",
@ -276,12 +275,12 @@
"friendly(['2015-07-01', '2015-07-04']);" "friendly(['2015-07-01', '2015-07-04']);"
], ],
"tests": [ "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-07-01', '2015-07-04']), ['July 1st','4th'], 'message: <code>friendly([\"2015-07-01\", \"2015-07-04\"])</code> should return <code>[\"July 1st\",\"4th\"]</code>.');",
"assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'two months apart can be inferred if it is the next year');", "assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'message: <code>friendly([\"2015-12-01\", \"2016-02-03\"])</code> should return <code>[\"December 1st\",\"February 3rd\"]</code>.');",
"assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);", "assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017'], 'message: <code>friendly([\"2015-12-01\", \"2017-02-03\"])</code> should return <code>[\"December 1st, 2015\",\"February 3rd, 2017\"]</code>.');",
"assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'one month apart can be inferred it is the same year');", "assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'message: <code>friendly([\"2016-03-01\", \"2016-05-05\"])</code> should return <code>[\"March 1st\",\"May 5th\"]</code>');",
"assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');", "assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'message: <code>friendly([\"2017-01-01\", \"2017-01-01\"])</code> should return <code>[\"January 1st, 2017\"]</code>.');",
"assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);" "assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023'], 'message: <code>friendly([\"2022-09-05\", \"2023-09-04\"])</code> should return <code>[\"September 5th, 2022\",\"September 4th, 2023\"]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.split()", "String.split()",

View File

@ -1,11 +1,10 @@
{ {
"name": "AngularJS", "name": "AngularJS",
"order": 0.014, "order": 16,
"challenges": [ "challenges": [
{ {
"id": "bd7154d8c441eddfaeb5bdef", "id": "bd7154d8c441eddfaeb5bdef",
"title": "Get Started with Angular.js", "title": "Get Started with Angular.js",
"difficulty": 0.34,
"challengeSeed": ["114684726"], "challengeSeed": ["114684726"],
"description": [ "description": [
"Code School has a short, free Angular.js course. This will give us a quick tour of Angular.js's mechanics and features.", "Code School has a short, free Angular.js course. This will give us a quick tour of Angular.js's mechanics and features.",
@ -29,7 +28,6 @@
{ {
"id": "bd7155d8c441eddfaeb5bdef", "id": "bd7155d8c441eddfaeb5bdef",
"title": "Apply Angular.js Directives", "title": "Apply Angular.js Directives",
"difficulty": 0.35,
"challengeSeed": ["114684727"], "challengeSeed": ["114684727"],
"description": [ "description": [
"Directives serve as markers in your HTML. When Angular.js compiles your HTML, it will alter the behavior of DOM elements based on the directives you've used.", "Directives serve as markers in your HTML. When Angular.js compiles your HTML, it will alter the behavior of DOM elements based on the directives you've used.",
@ -53,7 +51,6 @@
{ {
"id": "bd7156d8c441eddfaeb5bdef", "id": "bd7156d8c441eddfaeb5bdef",
"title": "Power Forms with Angular.js", "title": "Power Forms with Angular.js",
"difficulty": 0.36,
"challengeSeed": ["114684729"], "challengeSeed": ["114684729"],
"description": [ "description": [
"One area where Angular.js really shines is its powerful web forms.", "One area where Angular.js really shines is its powerful web forms.",
@ -77,7 +74,6 @@
{ {
"id": "bd7157d8c441eddfaeb5bdef", "id": "bd7157d8c441eddfaeb5bdef",
"title": "Customize Angular.js Directives", "title": "Customize Angular.js Directives",
"difficulty": 0.37,
"challengeSeed": ["114685062"], "challengeSeed": ["114685062"],
"description": [ "description": [
"Now we'll learn how to modify existing Angular.js directives, and even build directives of your own.", "Now we'll learn how to modify existing Angular.js directives, and even build directives of your own.",
@ -100,7 +96,6 @@
{ {
"id": "bd7158d8c441eddfaeb5bdef", "id": "bd7158d8c441eddfaeb5bdef",
"title": "Create Angular.js Services", "title": "Create Angular.js Services",
"difficulty": 0.38,
"challengeSeed": ["114685060"], "challengeSeed": ["114685060"],
"description": [ "description": [
"Services are functions that you can use and reuse throughout your Angular.js app to get things done.", "Services are functions that you can use and reuse throughout your Angular.js app to get things done.",

View File

@ -1,6 +1,6 @@
{ {
"name": "Automated Testing and Debugging", "name": "Automated Testing and Debugging",
"order": 0.012, "order": 14,
"challenges": [ "challenges": [
{ {
"id":"cf1111c1c16feddfaeb6bdef", "id":"cf1111c1c16feddfaeb6bdef",
@ -13,7 +13,7 @@
"<code>console.log('Hello world!')</code>" "<code>console.log('Hello world!')</code>"
], ],
"tests":[ "tests":[
"assert(editor.getValue().match(/console\\.log\\(/gi), 'You should use the console.log method to log \"Hello world!\" to your JavaScript console.');" "assert(editor.getValue().match(/console\\.log\\(/gi), 'message: You should use the console.log method to log \"Hello world!\" to your JavaScript console.');"
], ],
"challengeSeed":[ "challengeSeed":[
"", "",
@ -28,19 +28,19 @@
"title":"Using typeof", "title":"Using typeof",
"difficulty":0, "difficulty":0,
"description":[ "description":[
"<code>typeof</code> is a useful method that we can use to check the type of a variable.", "You can use <code>typeof</code> to check the <code>data structure</code>, or type, of a variable.",
"One thing to be careful of is that an array has the type objects.", "Note that in JavaScript, arrays are technically a type of object.",
"Try using each of these to see the types they have.", "Try using <code>typeof</code> on each of the following to see which types they have.",
"<code>console.log(typeof(\"\"));</code>", "<code>console.log(typeof(\"\"));</code>",
"<code>console.log(typeof(0));</code>", "<code>console.log(typeof(0));</code>",
"<code>console.log(typeof([]));</code>", "<code>console.log(typeof([]));</code>",
"<code>console.log(typeof({}));</code>" "<code>console.log(typeof({}));</code>"
], ],
"tests":[ "tests":[
"assert(editor.getValue().match(/console\\.log\\(typeof\\(\"\"\\)\\);/gi), 'You should <code>console.log</code> the <code>typeof</code> a string.');", "assert(editor.getValue().match(/console\\.log\\(typeof\\(\"\"\\)\\);/gi), 'message: You should <code>console.log</code> the <code>typeof</code> a string.');",
"assert(editor.getValue().match(/console\\.log\\(typeof\\(0\\)\\);/gi), 'You should <code>console.log</code> the <code>typeof</code> a number.');", "assert(editor.getValue().match(/console\\.log\\(typeof\\(0\\)\\);/gi), 'message: You should <code>console.log</code> the <code>typeof</code> a number.');",
"assert(editor.getValue().match(/console\\.log\\(typeof\\(\\[\\]\\)\\);/gi), 'You should <code>console.log</code> the <code>typeof</code> an array.');", "assert(editor.getValue().match(/console\\.log\\(typeof\\(\\[\\]\\)\\);/gi), 'message: You should <code>console.log</code> the <code>typeof</code> an array.');",
"assert(editor.getValue().match(/console\\.log\\(typeof\\(\\{\\}\\)\\);/gi), 'You should <code>console.log</code> the <code>typeof</code> a object.');" "assert(editor.getValue().match(/console\\.log\\(typeof\\(\\{\\}\\)\\);/gi), 'message: You should <code>console.log</code> the <code>typeof</code> a object.');"
], ],
"challengeSeed":[ "challengeSeed":[
"", "",

View File

@ -1,11 +1,10 @@
{ {
"name": "Full Stack JavaScript Projects", "name": "Full Stack JavaScript Projects",
"order": 0.019, "order": 20,
"challenges": [ "challenges": [
{ {
"id": "bd7158d8c443eddfaeb5bcef", "id": "bd7158d8c443eddfaeb5bcef",
"title": "Get Set for Basejumps", "title": "Get Set for Basejumps",
"difficulty": 2.00,
"challengeSeed": ["128451852"], "challengeSeed": ["128451852"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Get the MEAN stack running on Cloud 9, push your code to GitHub, and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Get the MEAN stack running on Cloud 9, push your code to GitHub, and deploy it to Heroku.",
@ -13,11 +12,11 @@
"If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.", "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
"Now let's get your development environment ready for a new Angular-Fullstack application provided by Yeoman.", "Now let's get your development environment ready for a new Angular-Fullstack application provided by Yeoman.",
"Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.", "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> 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.", "Click on the \"+\" icon at the top right of the c9.io page to create a new workspace.",
"Give your workspace a name.", "Give your workspace a name and an optional description.",
"Choose Node.js in the selection area below the name field.", "Choose Node.js in the selection area below the name field.",
"Click the Create button. Then click into your new workspace.", "Click the \"Create workspace\" 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.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. 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: <code>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</code>", "Never run this command on your local machine. But in your Cloud 9 terminal window, run: <code>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</code>",
"Yeoman will prompt you to answer some questions. Answer them like this:", "Yeoman will prompt you to answer some questions. Answer them like this:",
"What would you like to write scripts with? <span class='text-success'>JavaScript</span>", "What would you like to write scripts with? <span class='text-success'>JavaScript</span>",
@ -54,7 +53,7 @@
"Run the following command in a Cloud9 terminal prompt tab: <code>npm install grunt-contrib-imagemin --save-dev && npm install --save-dev && heroku login</code>. At this point, the terminal will prompt you to log in to Heroku from the command line.", "Run the following command in a Cloud9 terminal prompt tab: <code>npm install grunt-contrib-imagemin --save-dev && npm install --save-dev && heroku login</code>. At this point, the terminal will prompt you to log in to Heroku from the command line.",
"Now run <code>yo angular-fullstack:heroku</code>. 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.", "Now run <code>yo angular-fullstack:heroku</code>. 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: <code>cd ~/workspace/dist && heroku config:set NODE_ENV=production && heroku addons:create mongolab</code>.", "Set the config flag for your Heroku environment and add MongoLab for your MongoDB instance by running the following command: <code>cd ~/workspace/dist && heroku config:set NODE_ENV=production && heroku addons:create mongolab</code>.",
"As you build your app, you should frequently commit changes to your codebase. Make sure you're in the <code>~/workspace</code> directory by running <code>cd ~/workspace</code>. Then you can this code to stage the changes to your changes and commit them: <code>git commit -am \"your commit message\"</code>. 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\".", "As you build your app, you should frequently commit changes to your codebase. Make sure you're in the <code>~/workspace</code> directory by running <code>cd ~/workspace</code>. Then you can use this code to stage the changes to your changes and commit them: <code>git commit -am \"your commit message\"</code>. 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 <code>git push origin master</code>, and to Heroku by running <code>grunt --force && grunt buildcontrol:heroku</code>.", "You can push these new commits to GitHub by running <code>git push origin master</code>, and to Heroku by running <code>grunt --force && grunt buildcontrol:heroku</code>.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"Now you're ready to move on to your first Basejump. Click the \"I've completed this challenge\" and move on." "Now you're ready to move on to your first Basejump. Click the \"I've completed this challenge\" and move on."
@ -66,7 +65,6 @@
{ {
"id": "bd7158d8c443eddfaeb5bdef", "id": "bd7158d8c443eddfaeb5bdef",
"title": "Build a Voting App", "title": "Build a Voting App",
"difficulty": 2.01,
"challengeSeed": ["133315786"], "challengeSeed": ["133315786"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://votingapp.herokuapp.com/' target='_blank'>http://votingapp.herokuapp.com/</a> and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://votingapp.herokuapp.com/' target='_blank'>http://votingapp.herokuapp.com/</a> and deploy it to Heroku.",
@ -79,14 +77,14 @@
"<span class='text-info'>User Story:</span> As an authenticated user, I can see the aggregate results of my polls.", "<span class='text-info'>User Story:</span> As an authenticated user, I can see the aggregate results of my polls.",
"<span class='text-info'>User Story:</span> As an authenticated user, I can delete polls that I decide I don't want anymore.", "<span class='text-info'>User Story:</span> As an authenticated user, I can delete polls that I decide I don't want anymore.",
"<span class='text-info'>User Story:</span> As an authenticated user, I can create a poll with any number of possible items.", "<span class='text-info'>User Story:</span> As an authenticated user, I can create a poll with any number of possible items.",
"<span class='text-info'>Bonus User Story:</span> As an unauthenticated user, I can see everyone's polls, but I can't vote on anything.", "<span class='text-info'>Bonus User Story:</span> As an unauthenticated or authenticated user, I can see and vote on everyone's polls.",
"<span class='text-info'>Bonus User Story:</span> 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.)", "<span class='text-info'>Bonus User Story:</span> 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.)",
"<span class='text-info'>Bonus User Story:</span> As an authenticated user, if I don't like the options on a poll, I can create a new option.", "<span class='text-info'>Bonus User Story:</span> As an authenticated user, if I don't like the options on a poll, I can create a new option.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "basejumps", "type": "basejump",
"challengeType": 4, "challengeType": 4,
"tests": [], "tests": [],
"nameCn": "", "nameCn": "",
@ -103,7 +101,6 @@
{ {
"id": "bd7158d8c443eddfaeb5bdff", "id": "bd7158d8c443eddfaeb5bdff",
"title": "Build a Nightlife Coordination App", "title": "Build a Nightlife Coordination App",
"difficulty": 2.02,
"challengeSeed": ["133315781"], "challengeSeed": ["133315781"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://whatsgoinontonight.herokuapp.com/' target='_blank'>http://whatsgoinontonight.herokuapp.com/</a> and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://whatsgoinontonight.herokuapp.com/' target='_blank'>http://whatsgoinontonight.herokuapp.com/</a> and deploy it to Heroku.",
@ -118,9 +115,9 @@
"<span class='text-info'>Hint:</span> Try using the <a href='https://www.yelp.com/developers/documentation/v2/overview' target='_blank'>Yelp API</a> to find venues in the cities your users search for.", "<span class='text-info'>Hint:</span> Try using the <a href='https://www.yelp.com/developers/documentation/v2/overview' target='_blank'>Yelp API</a> to find venues in the cities your users search for.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "basejumps", "type": "basejump",
"challengeType": 4, "challengeType": 4,
"tests": [], "tests": [],
"nameCn": "", "nameCn": "",
@ -137,7 +134,6 @@
{ {
"id": "bd7158d8c443eddfaeb5bd0e", "id": "bd7158d8c443eddfaeb5bd0e",
"title": "Chart the Stock Market", "title": "Chart the Stock Market",
"difficulty": 2.03,
"challengeSeed": ["133315787"], "challengeSeed": ["133315787"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://stockstream.herokuapp.com/' target='_blank'>http://stockstream.herokuapp.com/</a> and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://stockstream.herokuapp.com/' target='_blank'>http://stockstream.herokuapp.com/</a> and deploy it to Heroku.",
@ -151,9 +147,9 @@
"<span class='text-info'>Bonus User Story:</span> As a user, I can see changes in real-time when any other user adds or removes a stock.", "<span class='text-info'>Bonus User Story:</span> As a user, I can see changes in real-time when any other user adds or removes a stock.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "basejumps", "type": "basejump",
"challengeType": 4, "challengeType": 4,
"tests": [], "tests": [],
"nameCn": "", "nameCn": "",
@ -170,7 +166,6 @@
{ {
"id": "bd7158d8c443eddfaeb5bd0f", "id": "bd7158d8c443eddfaeb5bd0f",
"title": "Manage a Book Trading Club", "title": "Manage a Book Trading Club",
"difficulty": 2.04,
"challengeSeed": ["133316032"], "challengeSeed": ["133316032"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://bookjump.herokuapp.com/' target='_blank'>http://bookjump.herokuapp.com/</a> and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://bookjump.herokuapp.com/' target='_blank'>http://bookjump.herokuapp.com/</a> and deploy it to Heroku.",
@ -184,9 +179,9 @@
"<span class='text-info'>Bonus User Story:</span> As an authenticated user, I can propose a trade and wait for the other user to accept the trade.", "<span class='text-info'>Bonus User Story:</span> As an authenticated user, I can propose a trade and wait for the other user to accept the trade.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "basejumps", "type": "basejump",
"challengeType": 4, "challengeType": 4,
"tests": [], "tests": [],
"nameCn": "", "nameCn": "",
@ -203,7 +198,6 @@
{ {
"id": "bd7158d8c443eddfaeb5bdee", "id": "bd7158d8c443eddfaeb5bdee",
"title": "Build a Pinterest Clone", "title": "Build a Pinterest Clone",
"difficulty": 2.05,
"challengeSeed": ["133315784"], "challengeSeed": ["133315784"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://stark-lowlands-3680.herokuapp.com/' target='_blank'>http://stark-lowlands-3680.herokuapp.com/</a> and deploy it to Heroku.", "<span class='text-info'>Objective:</span> Build a full stack JavaScript app that successfully reverse-engineers this: <a href='http://stark-lowlands-3680.herokuapp.com/' target='_blank'>http://stark-lowlands-3680.herokuapp.com/</a> and deploy it to Heroku.",
@ -220,9 +214,9 @@
"<span class='text-info'>Hint:</span> <a href='http://masonry.desandro.com/' target='_blank'>Masonry.js</a> is a library that allows for Pinterest-style image grids.", "<span class='text-info'>Hint:</span> <a href='http://masonry.desandro.com/' target='_blank'>Masonry.js</a> is a library that allows for Pinterest-style image grids.",
"If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.", "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "basejumps", "type": "basejump",
"challengeType": 4, "challengeType": 4,
"tests": [], "tests": [],
"nameCn": "", "nameCn": "",

View File

@ -1,20 +1,19 @@
{ {
"name": "Basic Algorithm Scripting", "name": "Basic Algorithm Scripting",
"order": 0.006, "order": 7,
"challenges": [ "challenges": [
{ {
"id": "ad7123c8c441eddfaeb5bdef", "id": "ad7123c8c441eddfaeb5bdef",
"title": "Meet Bonfire", "title": "Meet Bonfire",
"difficulty": "0",
"description": [ "description": [
"Your goal is to fix the failing test.", "Your goal is to fix the failing test.",
"First, run all the tests by clicking \"Run code\" or by pressing Control + Enter.", "First, run all the tests by clicking \"Run tests\" 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.", "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." "Make this function return true no matter what."
], ],
"tests": [ "tests": [
"expect(meetBonfire()).to.be.a(\"boolean\");", "assert(typeof(meetBonfire()) === \"boolean\", 'message: <code>meetBonfire()</code> should return a boolean value.');",
"expect(meetBonfire()).to.be.true;" "assert(meetBonfire() === true, 'message: <code>meetBonfire()</code> should return true.');"
], ],
"challengeSeed": [ "challengeSeed": [
"function meetBonfire(argument) {", "function meetBonfire(argument) {",
@ -44,25 +43,24 @@
{ {
"id": "a202eed8fc186c8434cb6d61", "id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String", "title": "Reverse a String",
"difficulty": "1.01",
"tests": [ "tests": [
"expect(reverseString('hello')).to.be.a('String');", "assert(typeof(reverseString(\"hello\")) === \"string\", 'message: <code>reverseString()</code> should return a string.');",
"expect(reverseString('hello')).to.equal('olleh');", "assert(reverseString(\"hello\") === \"olleh\", 'message: <code>reverseString(\"hello\")</code> should become <code>\"olleh\"</code>.');",
"expect(reverseString('Howdy')).to.equal('ydwoH');", "assert(reverseString(\"Howdy\") === \"ydwoH\", 'message: <code>reverseString(\"Howdy\")</code> should become <code>\"ydwoH\"</code>.');",
"expect(reverseString('Greetings from Earth')).to.equal('htraE morf sgniteerG');" "assert(reverseString(\"Greetings from Earth\") === \"htraE morf sgniteerG\", 'message: <code>reverseString(\"Greetings from Earth\")</code> should return <code>\"htraE morf sgniteerG\"</code>.');"
], ],
"description": [ "description": [
"Reverse the provided string.", "Reverse the provided string.",
"You may need to turn the string into an array before you can reverse it.", "You may need to turn the string into an array before you can reverse it.",
"Your result must be a string.", "Your result must be a string.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function reverseString(str) {", "function reverseString(str) {",
" return str;", " return str;",
"}", "}",
"", "",
"reverseString('hello');" "reverseString(\"hello\", \"\");"
], ],
"MDNlinks": [ "MDNlinks": [
"Global String Object", "Global String Object",
@ -87,25 +85,25 @@
"id": "a302f7aae1aa3152a5b413bc", "id": "a302f7aae1aa3152a5b413bc",
"title": "Factorialize a Number", "title": "Factorialize a Number",
"tests": [ "tests": [
"expect(factorialize(5)).to.be.a(\"Number\");", "assert(typeof(factorialize(5)) === \"number\", 'message: <code>factorialize()</code> should return a number.');",
"expect(factorialize(5)).to.equal(120);", "assert(factorialize(5) === 120, 'message: <code>factorialize(5)</code> should return 120.');",
"expect(factorialize(10)).to.equal(3628800);", "assert(factorialize(10) === 3628800, 'message: <code>factorialize(10)</code> should return 3628800.');",
"expect(factorialize(20)).to.equal(2432902008176640000);" "assert(factorialize(20) === 2432902008176640000, 'message: <code>factorialize(20)</code> should return 2432902008176640000.');",
"assert(factorialize(0) === 1, 'message: <code>factorialize(0)</code> should return 1.');"
], ],
"difficulty": "1.02",
"description": [ "description": [
"Return the factorial of the provided integer.", "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.", "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!", "Factorials are often represented with the shorthand notation <code>n!</code>",
"For example: 5! = 1 * 2 * 3 * 4 * 5 = 120f", "For example: <code>5! = 1 * 2 * 3 * 4 * 5 = 120</code>",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function factorialize(num) {", "function factorialize(num) {",
" return num;", " return num;",
"}", "}",
"", "",
"factorialize(5);" "factorialize(5, '');"
], ],
"MDNlinks": [ "MDNlinks": [
"Arithmetic Operators" "Arithmetic Operators"
@ -126,23 +124,25 @@
{ {
"id": "aaa48de84e1ecc7c742e1124", "id": "aaa48de84e1ecc7c742e1124",
"title": "Check for Palindromes", "title": "Check for Palindromes",
"difficulty": "1.03",
"description": [ "description": [
"Return true if the given string is a palindrome. Otherwise, return false.", "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.", "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.", "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.", "We'll pass strings with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"tests": [ "tests": [
"expect(palindrome(\"eye\")).to.be.a(\"boolean\");", "assert(typeof(palindrome(\"eye\")) === \"boolean\", 'message: <code>palindrome()</code> should return a boolean.');",
"assert.deepEqual(palindrome(\"eye\"), true);", "assert(palindrome(\"eye\") === true, 'message: <code>palindrome(\"eye\")</code> should return true.');",
"assert.deepEqual(palindrome(\"race car\"), true);", "assert(palindrome(\"race car\") === true, 'message: <code>palindrome(\"race car\")</code> should return true.');",
"assert.deepEqual(palindrome(\"not a palindrome\"), false);", "assert(palindrome(\"not a palindrome\") === false, 'message: <code>palindrome(\"not a palindrome\")</code> should return false.');",
"assert.deepEqual(palindrome(\"A man, a plan, a canal. Panama\"), true);", "assert(palindrome(\"A man, a plan, a canal. Panama\") === true, 'message: <code>palindrome(\"A man, a plan, a canal. Panama\")</code> should return true.');",
"assert.deepEqual(palindrome(\"never odd or even\"), true);", "assert(palindrome(\"never odd or even\") === true, 'message: <code>palindrome(\"never odd or even\")</code> should return true.');",
"assert.deepEqual(palindrome(\"nope\"), false);", "assert(palindrome(\"nope\") === false, 'message: <code>palindrome(\"nope\")</code> should return false.');",
"assert.deepEqual(palindrome(\"almostomla\"), false);" "assert(palindrome(\"almostomla\") === false, 'message: <code>palindrome(\"almostomla\")</code> should return false.');",
"assert(palindrome(\"My age is 0, 0 si ega ym.\") === true, 'message: <code>palindrome(\"My age is 0, 0 si ega ym.\")</code> should return true.');",
"assert(palindrome(\"1 eye for of 1 eye.\") === false, 'message: <code>palindrome(\"1 eye for of 1 eye.\")</code> should return false.');",
"assert(palindrome(\"0_0 (: /-\\ :) 0-0\") === true, 'message: <code>palindrome(\"0_0 (: /-\\\\ :) 0-0\")</code> should return true.');"
], ],
"challengeSeed": [ "challengeSeed": [
"function palindrome(str) {", "function palindrome(str) {",
@ -174,26 +174,25 @@
{ {
"id": "a26cbbe9ad8655a977e1ceb5", "id": "a26cbbe9ad8655a977e1ceb5",
"title": "Find the Longest Word in a String", "title": "Find the Longest Word in a String",
"difficulty": "1.04",
"description": [ "description": [
"Return the length of the longest word in the provided sentence.", "Return the length of the longest word in the provided sentence.",
"Your response should be a number.", "Your response should be a number.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function findLongestWord(str) {", "function findLongestWord(str) {",
" return str.length;", " return str.length;",
"}", "}",
"", "",
"findLongestWord('The quick brown fox jumped over the lazy dog');" "findLongestWord(\"The quick brown fox jumped over the lazy dog\");"
], ],
"tests": [ "tests": [
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.be.a('Number');", "assert(typeof(findLongestWord(\"The quick brown fox jumped over the lazy dog\")) === \"number\", 'message: <code>findLongestWord()</code> should return a number.');",
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);", "assert(findLongestWord(\"The quick brown fox jumped over the lazy dog\") === 6, 'message: <code>findLongestWord(\"The quick brown fox jumped over the lazy dog\")</code> should return 6.');",
"expect(findLongestWord('May the force be with you')).to.equal(5);", "assert(findLongestWord(\"May the force be with you\") === 5, 'message: <code>findLongestWord(\"May the force be with you\")</code> should return 5.');",
"expect(findLongestWord('Google do a barrel roll')).to.equal(6);", "assert(findLongestWord(\"Google do a barrel roll\") === 6, 'message: <code>findLongestWord(\"Google do a barrel roll\")</code> should return 6.');",
"expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);", "assert(findLongestWord(\"What is the average airspeed velocity of an unladen swallow\") === 8, 'message: <code>findLongestWord(\"What is the average airspeed velocity of an unladen swallow\")</code> should return 8.');",
"expect(findLongestWord('What if we try a super-long word such as otorhinolaryngology')).to.equal(19);" "assert(findLongestWord(\"What if we try a super-long word such as otorhinolaryngology\") === 19, 'message: <code>findLongestWord(\"What if we try a super-long word such as otorhinolaryngology\")</code> should return 19.');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.split()", "String.split()",
@ -215,24 +214,23 @@
{ {
"id": "ab6137d4e35944e21037b769", "id": "ab6137d4e35944e21037b769",
"title": "Title Case a Sentence", "title": "Title Case a Sentence",
"difficulty": "1.05",
"description": [ "description": [
"Return the provided string with the first letter of each word capitalized.", "Return the provided string with the first letter of each word capitalized. Make sure the rest of the word is in lower case.",
"For the purpose of this exercise, you should also capitalize connecting words like 'the' and 'of'.", "For the purpose of this exercise, you should also capitalize connecting words like \"the\" and \"of\".",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function titleCase(str) {", "function titleCase(str) {",
" return str;", " return str;",
"}", "}",
"", "",
"titleCase(\"I'm a little tea pot\");" "titleCase(\"I'm a little tea pot\", \"\");"
], ],
"tests": [ "tests": [
"expect(titleCase(\"I'm a little tea pot\")).to.be.a('String');", "assert(typeof(titleCase(\"I&#39;m a little tea pot\")) === \"string\", 'message: <code>titleCase()</code> should return a string.');",
"expect(titleCase(\"I'm a little tea pot\")).to.equal(\"I'm A Little Tea Pot\");", "assert(titleCase(\"I&#39;m a little tea pot\") === \"I&#39;m A Little Tea Pot\", 'message: <code>titleCase(\"I&#39;m a little tea pot\")</code> should return \"I&#39;m A Little Tea Pot\".');",
"expect(titleCase(\"sHoRt AnD sToUt\")).to.equal(\"Short And Stout\");", "assert(titleCase(\"sHoRt AnD sToUt\") === \"Short And Stout\", 'message: <code>titleCase(\"sHoRt AnD sToUt\")</code> should return \"Short And Stout\".');",
"expect(titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\")).to.equal(\"Here Is My Handle Here Is My Spout\");" "assert(titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\") === \"Here Is My Handle Here Is My Spout\", 'message: <code>titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\")</code> should return \"Here Is My Handle Here Is My Spout\".');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.charAt()" "String.charAt()"
@ -253,12 +251,11 @@
{ {
"id": "a789b3483989747d63b0e427", "id": "a789b3483989747d63b0e427",
"title": "Return Largest Numbers in Arrays", "title": "Return Largest Numbers in Arrays",
"difficulty": "1.06",
"description": [ "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.", "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] .", "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.", "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.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function largestOfFour(arr) {", "function largestOfFour(arr) {",
@ -269,9 +266,9 @@
"largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);" "largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);"
], ],
"tests": [ "tests": [
"expect( largestOfFour( [[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]) ).to.be.a('array');", "assert(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]).constructor === Array, 'message: <code>largestOfFour()</code> should return an array.');",
"assert.deepEqual( largestOfFour( [[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]), [27,5,39,1001], 'arrays should match.');", "assert.deepEqual(largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]), [27,5,39,1001], 'message: <code>largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]])</code> should return <code>[27,5,39,1001]</code>.');",
"assert.deepEqual( largestOfFour( [[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]), [9,35,97,1000000], 'arrays should match.');" "assert.deepEqual(largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]), [9,35,97,1000000], 'message: <code>largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]])</code> should return <code>[9, 35, 97, 1000000]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Comparison Operators" "Comparison Operators"
@ -292,10 +289,9 @@
{ {
"id": "acda2fb1324d9b0fa741e6b5", "id": "acda2fb1324d9b0fa741e6b5",
"title": "Confirm the Ending", "title": "Confirm the Ending",
"difficulty": "1.07",
"description": [ "description": [
"Check if a string (first argument) ends with the given target string (second argument).", "Check if a string (first argument) ends with the given target string (second argument).",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function end(str, target) {", "function end(str, target) {",
@ -304,14 +300,14 @@
" return str;", " return str;",
"}", "}",
"", "",
"end('Bastian', 'n');" "end(\"Bastian\", \"n\", \"\");"
], ],
"tests": [ "tests": [
"assert.strictEqual(end('Bastian', 'n'), true, 'should equal true if target equals end of string');", "assert(end(\"Bastian\", \"n\") === true, 'message: <code>end(\"Bastian\", \"n\")</code> should return true.');",
"assert.strictEqual(end('Connor', 'n'), false, 'should equal false if target does not equal end of string');", "assert(end(\"Connor\", \"n\") === false, 'message: <code>end(\"Connor\", \"n\")</code> should return false.');",
"assert.strictEqual(end('Walking on water and developing software from a specification are easy if both are frozen.', 'specification'), false, 'should equal false if target does not equal end of string');", "assert(end(\"Walking on water and developing software from a specification are easy if both are frozen.\", \"specification\") === false, 'message: <code>end(\"Walking on water and developing software from a specification are easy if both are frozen.\", \"specification\")</code> should return false.');",
"assert.strictEqual(end('He has to give me a new name', 'name'), true, 'should equal true if target equals end of string');", "assert(end(\"He has to give me a new name\", \"name\") === true, 'message: <code>end(\"He has to give me a new name\", \"name\")</code> should return true.');",
"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');" "assert(end(\"If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing\", \"mountain\") === false, 'message: <code>end(\"If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing\", \"mountain\")</code> should return false.');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.substr()" "String.substr()"
@ -332,10 +328,9 @@
{ {
"id": "afcc8d540bea9ea2669306b6", "id": "afcc8d540bea9ea2669306b6",
"title": "Repeat a string repeat a string", "title": "Repeat a string repeat a string",
"difficulty": "1.08",
"description": [ "description": [
"Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number.", "Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function repeat(str, num) {", "function repeat(str, num) {",
@ -343,12 +338,12 @@
" return str;", " return str;",
"}", "}",
"", "",
"repeat('abc', 3);" "repeat(\"abc\", 3, \"\");"
], ],
"tests": [ "tests": [
"assert.strictEqual(repeat('*', 3), '***', 'should repeat a string n times');", "assert(repeat(\"*\", 3) === \"***\", 'message: <code>repeat(\"*\", 3)</code> should return <code>\"***\"</code>.');",
"assert.strictEqual(repeat('abc', 3), 'abcabcabc', 'should repeat a string n times');", "assert(repeat(\"abc\", 3) === \"abcabcabc\", 'message: <code>repeat(\"abc\", 3)</code> should return <code>\"abcabcabc\"</code>.');",
"assert.strictEqual(repeat('abc', -2), '', 'should return an empty string for negative numbers');" "assert(repeat(\"abc\", -2) === \"\", 'message: <code>repeat(\"abc\", -2)</code> should return <code>\"\"</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Global String Object" "Global String Object"
@ -369,11 +364,10 @@
{ {
"id": "ac6993d51946422351508a41", "id": "ac6993d51946422351508a41",
"title": "Truncate a string", "title": "Truncate a string",
"difficulty": "1.09",
"description": [ "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.", "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.", "Note that the three dots at the end add to the string length.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function truncate(str, num) {", "function truncate(str, num) {",
@ -381,13 +375,13 @@
" return str;", " return str;",
"}", "}",
"", "",
"truncate('A-tisket a-tasket A green and yellow basket', 11);" "truncate(\"A-tisket a-tasket A green and yellow basket\", 11, \"\");"
], ],
"tests": [ "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\", 11) === \"A-tisket...\", 'message: <code>truncate(\"A-tisket a-tasket A green and yellow basket\", 1)</code> should return \"A-tisket...\".');",
"expect(truncate('Peter Piper picked a peck of pickled peppers', 14)).to.eqls('Peter Piper...');", "assert(truncate(\"Peter Piper picked a peck of pickled peppers\", 14) === \"Peter Piper...\", 'message: <code>truncate(\"Peter Piper picked a peck of pickled peppers\", 14)</code> should return \"Peter Piper...\".');",
"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(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\", 'message: <code>truncate(\"A-tisket a-tasket A green and yellow basket\", \"A-tisket a-tasket A green and yellow basket\".length)</code> should return \"A-tisket a-tasket A green and yellow basket\".');",
"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');" "assert(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', 'message: <code>truncate(\"A-tisket a-tasket A green and yellow basket\", \"A-tisket a-tasket A green and yellow basket\".length + 2)</code> should return \"A-tisket a-tasket A green and yellow basket\".');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.slice()" "String.slice()"
@ -408,10 +402,9 @@
{ {
"id": "a9bd25c716030ec90084d8a1", "id": "a9bd25c716030ec90084d8a1",
"title": "Chunky Monkey", "title": "Chunky Monkey",
"difficulty": "1.10",
"description": [ "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.", "Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a multidimensional array.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function chunk(arr, size) {", "function chunk(arr, size) {",
@ -419,13 +412,13 @@
" return arr;", " return arr;",
"}", "}",
"", "",
"chunk(['a', 'b', 'c', 'd'], 2);" "chunk([\"a\", \"b\", \"c\", \"d\"], 2, \"\");"
], ],
"tests": [ "tests": [
"assert.deepEqual(chunk(['a', 'b', 'c', 'd'], 2), [['a', 'b'], ['c', 'd']], 'should return chunked arrays');", "assert.deepEqual(chunk([\"a\", \"b\", \"c\", \"d\"], 2), [[\"a\", \"b\"], [\"c\", \"d\"]], 'message: <code>chunk([\"a\", \"b\", \"c\", \"d\"], 2)</code> should return <code>[[\"a\", \"b\"], [\"c\", \"d\"]]</code>.');",
"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], 3), [[0, 1, 2], [3, 4, 5]], 'message: <code>chunk([0, 1, 2, 3, 4, 5], 3)</code> should return <code>[[0, 1, 2], [3, 4, 5]]</code>.');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 2), [[0, 1], [2, 3], [4, 5]], 'should return chunked arrays');", "assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 2), [[0, 1], [2, 3], [4, 5]], 'message: <code>chunk([0, 1, 2, 3, 4, 5], 2)</code> should return <code>[[0, 1], [2, 3], [4, 5]]</code>.');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'should return the last chunk as remaining elements');" "assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'message: <code>chunk([0, 1, 2, 3, 4, 5], 4)</code> should return <code>[[0, 1, 2, 3], [4, 5]]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.push()" "Array.push()"
@ -446,10 +439,10 @@
{ {
"id": "ab31c21b530c0dafa9e241ee", "id": "ab31c21b530c0dafa9e241ee",
"title": "Slasher Flick", "title": "Slasher Flick",
"difficulty": "1.11",
"description": [ "description": [
"Return the remaining elements of an array after chopping off n elements from the head.", "Return the remaining elements of an array after chopping off n elements from the head.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "The head meaning the beginning of the array, or the zeroth index",
"Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function slasher(arr, howMany) {", "function slasher(arr, howMany) {",
@ -457,12 +450,12 @@
" return arr;", " return arr;",
"}", "}",
"", "",
"slasher([1, 2, 3], 2);" "slasher([1, 2, 3], 2, \"\");"
], ],
"tests": [ "tests": [
"assert.deepEqual(slasher([1, 2, 3], 2), [3], 'should drop the first two elements');", "assert.deepEqual(slasher([1, 2, 3], 2), [3], 'message: <code>slasher([1, 2, 3], 2, [3])</code> should return <code>[3]</code>.');",
"assert.deepEqual(slasher([1, 2, 3], 0), [1, 2, 3], 'should return all elements');", "assert.deepEqual(slasher([1, 2, 3], 0), [1, 2, 3], 'message: <code>slasher([1, 2, 3], 0)</code> should return <code>[1, 2, 3]</code>.');",
"assert.deepEqual(slasher([1, 2, 3], 9), [], 'should return an empty array');" "assert.deepEqual(slasher([1, 2, 3], 9), [], 'message: <code>slasher([1, 2, 3], 9)</code> should return <code>[]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.slice()", "Array.slice()",
@ -484,30 +477,29 @@
{ {
"id": "af2170cad53daa0770fabdea", "id": "af2170cad53daa0770fabdea",
"title": "Mutations", "title": "Mutations",
"difficulty": "1.12",
"description": [ "description": [
"Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array.", "Return true if the string in the first element of the array contains all of 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.", "For example, <code>[\"hello\", \"Hello\"]</code>, 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'.", "The arguments <code>[\"hello\", \"hey\"]</code> should return false because the string \"hello\" does not contain a \"y\".",
"Lastly, ['Alien', 'line'], should return true because all of the letters in 'line' are present in 'Alien'.", "Lastly, <code>[\"Alien\", \"line\"]</code>, should return true because all of the letters in \"line\" are present in \"Alien\".",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function mutation(arr) {", "function mutation(arr) {",
" return arr;", " return arr;",
"}", "}",
"", "",
"mutation(['hello', 'hey']);" "mutation([\"hello\", \"hey\"], \"\");"
], ],
"tests": [ "tests": [
"expect(mutation(['hello', 'hey'])).to.be.false;", "assert(mutation([\"hello\", \"hey\"]) === false, 'message: <code>mutation([\"hello\", \"hey\"])</code> should return false.');",
"expect(mutation(['hello', 'Hello'])).to.be.true;", "assert(mutation([\"hello\", \"Hello\"]) === true, 'message: <code>mutation([\"hello\", \"Hello\"])</code> should return true.');",
"expect(mutation(['zyxwvutsrqponmlkjihgfedcba', 'qrstu'])).to.be.true;", "assert(mutation([\"zyxwvutsrqponmlkjihgfedcba\", \"qrstu\"]) === true, 'message: <code>mutation([\"zyxwvutsrqponmlkjihgfedcba\", \"qrstu\"])</code> should return true.');",
"expect(mutation(['Mary', 'Army'])).to.be.true;", "assert(mutation([\"Mary\", \"Army\"]) === true, 'message: <code>mutation([\"Mary\", \"Army\"])</code> should return true.');",
"expect(mutation(['Mary', 'Aarmy'])).to.be.true;", "assert(mutation([\"Mary\", \"Aarmy\"]) === true, 'message: <code>mutation([\"Mary\", \"Aarmy\"])</code> should return true.');",
"expect(mutation(['Alien', 'line'])).to.be.true;", "assert(mutation([\"Alien\", \"line\"]) === true, 'message: <code>mutation([\"Alien\", \"line\"])</code> should return true.');",
"expect(mutation(['floor', 'for'])).to.be.true;", "assert(mutation([\"floor\", \"for\"]) === true, 'message: <code>mutation([\"floor\", \"for\"])</code> should return true.');",
"expect(mutation(['hello', 'neo'])).to.be.false;" "assert(mutation([\"hello\", \"neo\"]) === false, 'message: <code>mutation([\"hello\", \"neo\"])</code> should return false.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.indexOf()" "Array.indexOf()"
@ -527,12 +519,11 @@
}, },
{ {
"id": "adf08ec01beb4f99fc7a68f2", "id": "adf08ec01beb4f99fc7a68f2",
"title": "Falsey Bouncer", "title": "Falsy Bouncer",
"difficulty": "1.50",
"description": [ "description": [
"Remove all falsey values from an array.", "Remove all falsy values from an array.",
"Falsey values in javascript are false, null, 0, \"\", undefined, and NaN.", "Falsy values in javascript are <code>false</code>, <code>null</code>, <code>0</code>, <code>\"\"</code>, <code>undefined</code>, and <code>NaN</code>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function bouncer(arr) {", "function bouncer(arr) {",
@ -540,12 +531,12 @@
" return arr;", " return arr;",
"}", "}",
"", "",
"bouncer([7, 'ate', '', false, 9]);" "bouncer([7, \"ate\", \"\", false, 9], \"\");"
], ],
"tests": [ "tests": [
"assert.deepEqual(bouncer([7, 'ate', '', false, 9]), [7, 'ate', 9], 'should remove falsey values');", "assert.deepEqual(bouncer([7, \"ate\", \"\", false, 9]), [7, \"ate\", 9], 'message: <code>bouncer([7, \"ate\", \"\", false, 9])</code> should return <code>[7, \"ate\", 9]</code>.');",
"assert.deepEqual(bouncer(['a', 'b', 'c']), ['a', 'b', 'c'], 'should return full array if no falsey elements');", "assert.deepEqual(bouncer([\"a\", \"b\", \"c\"]), [\"a\", \"b\", \"c\"], 'message: <code>bouncer([\"a\", \"b\", \"c\"])</code> should return <code>[\"a\", \"b\", \"c\"]</code>.');",
"assert.deepEqual(bouncer([false, null, 0]), [], 'should return empty array if all elements are falsey');" "assert.deepEqual(bouncer([false, null, 0, NaN, undefined, \"\"]), [], 'message: <code>bouncer([false, null, 0, NaN, undefined, \"\"])</code> should return <code>[]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Boolean Objects", "Boolean Objects",
@ -564,55 +555,12 @@
"namePt": "", "namePt": "",
"descriptionPt": [] "descriptionPt": []
}, },
{
"id": "a8e512fbe388ac2f9198f0fa",
"title": "Where art thou",
"difficulty": "1.55",
"description": [
"Make a function that looks through an array (first argument) and returns an array of all objects that have equivalent property and value pair (second argument).",
"For example, if the first argument is <code>[{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }]</code>, and the second argument is <code>{ last: 'Capulet' }</code>, then you must return the the third object from the array (the first argument), because it contains the property and it's value, that was passed on as the second argument.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code."
],
"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');",
"assert.deepEqual(where([{ 'a': 1, 'b': 2 }, { 'a': 1 }, { 'a': 1, 'b': 2, 'c': 2 }], { 'a': 1, 'b': 2 }), [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2, 'c': 2 }], 'should return two objects in array');",
"assert.deepEqual(where([{ 'a': 5 }, { 'a': 5 }, { 'a': 5, 'b': 10 }], { 'a': 5, 'b': 10 }), [{ 'a': 5, 'b': 10 }], 'should return a single object in array');"
],
"MDNlinks": [
"Global Object",
"Object.hasOwnProperty()",
"Object.keys()"
],
"type": "bonfire",
"challengeType": 5,
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{ {
"id": "a39963a4c10bc8b4d4f06d7e", "id": "a39963a4c10bc8b4d4f06d7e",
"title": "Seek and Destroy", "title": "Seek and Destroy",
"difficulty": "1.60",
"description": [ "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.", "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.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function destroyer(arr) {", "function destroyer(arr) {",
@ -620,14 +568,14 @@
" return arr;", " return arr;",
"}", "}",
"", "",
"destroyer([1, 2, 3, 1, 2, 3], 2, 3);" "destroyer([1, 2, 3, 1, 2, 3], 2, 3, \"\");"
], ],
"tests": [ "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, 1, 2, 3], 2, 3), [1, 1], 'message: <code>destroyer([1, 2, 3, 1, 2, 3], 2, 3)</code> should return <code>[1, 1]</code>.');",
"assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');", "assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'message: <code>destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3)</code> should return <code>[1, 5, 1]</code>.');",
"assert.deepEqual(destroyer([3, 5, 1, 2, 2], 2, 3, 5), [1], 'should accept more than two additional arguments');", "assert.deepEqual(destroyer([3, 5, 1, 2, 2], 2, 3, 5), [1], 'message: <code>destroyer([3, 5, 1, 2, 2], 2, 3, 5)</code> should return <code>[1]</code>.');",
"assert.deepEqual(destroyer([2, 3, 2, 3], 2, 3), [], 'should remove correct values from an array');", "assert.deepEqual(destroyer([2, 3, 2, 3], 2, 3), [], 'message: <code>destroyer([2, 3, 2, 3], 2, 3)</code> should return <code>[]</code>.');",
"assert.deepEqual(destroyer(['tree', 'hamburger', 53], 'tree', 53), ['hamburger'], 'should handle NaN-elements');" "assert.deepEqual(destroyer([\"tree\", \"hamburger\", 53], \"tree\", 53), [\"hamburger\"], 'message: <code>destroyer([\"tree\", \"hamburger\", 53], \"tree\", 53)</code> should return <code>[\"hamburger\"]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Arguments object", "Arguments object",
@ -649,11 +597,10 @@
{ {
"id": "a24c1a4622e3c05097f71d67", "id": "a24c1a4622e3c05097f71d67",
"title": "Where do I belong", "title": "Where do I belong",
"difficulty": "1.61",
"description": [ "description": [
"Return the lowest index at which a value (second argument) should be inserted into a sorted array (first argument).", "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).", "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).",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code." "Remember to use <a href=\"//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function where(arr, num) {", "function where(arr, num) {",
@ -661,18 +608,18 @@
" return num;", " return num;",
"}", "}",
"", "",
"where([40, 60], 50);" "where([40, 60], 50, \"\");"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.sort()" "Array.sort()"
], ],
"tests": [ "tests": [
"assert.strictEqual(where([10, 20, 30, 40, 50], 35), 3, '35 should be placed at index 3');", "assert(where([10, 20, 30, 40, 50], 35) === 3, 'message: <code>where([10, 20, 30, 40, 50], 35)</code> should return <code>3</code>.');",
"assert.strictEqual(where([10, 20, 30, 40, 50], 30), 2, '30 should be placed at index 2');", "assert(where([10, 20, 30, 40, 50], 30) === 2, 'message: <code>where([10, 20, 30, 40, 50], 30)</code> should return <code>2</code>.');",
"assert.strictEqual(where([40, 60], 50), 1, '50 should be placed at index 1');", "assert(where([40, 60], 50) === 1, 'message: <code>where([40, 60,], 50)</code> should return <code>1</code>.');",
"assert.strictEqual(where([5, 3, 20, 3], 3), 0, '3 should be placed at index 0');", "assert(where([5, 3, 20, 3], 3) === 0, 'message: <code>where([5, 3, 20, 3], 3)</code> should return <code>0</code>.');",
"assert.strictEqual(where([2, 20, 10], 1), 0, '1 should be placed at index 0');", "assert(where([2, 20, 10], 1) === 0, 'message: <code>where([2, 20, 10], 1)</code> should return <code>0</code>.');",
"assert.strictEqual(where([2, 5, 10], 15), 3, '15 should be placed at index 3');" "assert(where([2, 5, 10], 15) === 3, 'message: <code>where([2, 5, 10], 15)</code> should return <code>3</code>.');"
], ],
"type": "bonfire", "type": "bonfire",
"challengeType": 5, "challengeType": 5,

View File

@ -1,6 +1,6 @@
{ {
"name": "Basic JavaScript", "name": "Basic JavaScript",
"order": 0.005, "order": 5,
"challenges": [ "challenges": [
{ {
"id":"bd7123c9c441eddfaeb4bdef", "id":"bd7123c9c441eddfaeb4bdef",
@ -17,9 +17,9 @@
"And one more thing you need to notice. Starting at this waypoint in JavaScript related challenges (except AngularJS, all Ziplines, Git, Node.js and Express.js, MongoDB and Full Stack JavaScript Projects) you can see contents of <code>assert()</code> functions (in some challenges <code>except()</code>, <code>assert.equal()</code> and so on) which are used to test your code. It's part of these challenges that you are able to see the tests that are running against your code." "And one more thing you need to notice. Starting at this waypoint in JavaScript related challenges (except AngularJS, all Ziplines, Git, Node.js and Express.js, MongoDB and Full Stack JavaScript Projects) you can see contents of <code>assert()</code> functions (in some challenges <code>except()</code>, <code>assert.equal()</code> and so on) which are used to test your code. It's part of these challenges that you are able to see the tests that are running against your code."
], ],
"tests":[ "tests":[
"assert(editor.getValue().match(/(\\/\\/)...../g), 'Create a <code>//</code> style comment that contains at least five letters');", "assert(editor.getValue().match(/(\\/\\/)...../g), 'message: Create a <code>//</code> style comment that contains at least five letters');",
"assert(editor.getValue().match(/(\\/\\*)...../g), 'Create a <code>/* */</code> style comment that contains at least five letters.');", "assert(editor.getValue().match(/(\\/\\*)[\\w\\W]{5,}(?=\\*\\/)/gm), 'message: Create a <code>/* */</code> style comment that contains at least five letters.');",
"assert(editor.getValue().match(/(\\*\\/)/g), 'Make sure that you close the comment with a <code>*/</code>');" "assert(editor.getValue().match(/(\\*\\/)/g), 'message: Make sure that you close the comment with a <code>*/</code>');"
], ],
"challengeSeed":[ "challengeSeed":[
], ],
@ -29,20 +29,19 @@
{ {
"id": "bd7123c9c441eddfaeb5bdef", "id": "bd7123c9c441eddfaeb5bdef",
"title": "Understand Boolean Values", "title": "Understand Boolean Values",
"difficulty": "9.98001",
"description": [ "description": [
"In computer science, <code>data structures</code> are things that hold data. JavaScript has seven of these. For example, the <code>Number</code> data structure holds numbers.", "In computer science, <code>data structures</code> are things that hold data. JavaScript has seven of these. For example, the <code>Number</code> data structure holds numbers.",
"Let's learn about the most basic data structure of all: the <code>Boolean</code>. Booleans can only hold the value of either true or false. They are basically little on-off switches.", "Let's learn about the most basic data structure of all: the <code>Boolean</code>. Booleans can only hold the value of either true or false. They are basically little on-off switches.",
"Let's modify our <code>welcomeToBooleans</code>function so that it will return <code>true</code>instead of <code>false</code>when the run button is clicked." "Let's modify our <code>welcomeToBooleans</code>function so that it will return <code>true</code>instead of <code>false</code>when the run button is clicked."
], ],
"tests": [ "tests": [
"assert(typeof(welcomeToBooleans()) === 'boolean', 'The <code>welcomeToBooleans()</code> function should return a boolean &#40;true/false&#41; value.');", "assert(typeof(welcomeToBooleans()) === 'boolean', 'message: The <code>welcomeToBooleans()</code> function should return a boolean &#40;true/false&#41; value.');",
"assert(welcomeToBooleans() === true, '<code>welcomeToBooleans()</code> should return true.');" "assert(welcomeToBooleans() === true, 'message: <code>welcomeToBooleans()</code> should return true.');"
], ],
"challengeSeed": [ "challengeSeed": [
"function welcomeToBooleans() {", "function welcomeToBooleans() {",
"", "",
"// don't change code above here", "// Only change code below this line.",
"", "",
" return false;", " return false;",
"", "",
@ -57,7 +56,6 @@
{ {
"id": "bd7123c9c443eddfaeb5bdef", "id": "bd7123c9c443eddfaeb5bdef",
"title": "Declare JavaScript Variables", "title": "Declare JavaScript Variables",
"difficulty": "9.9801",
"description": [ "description": [
"When we store data in a <code>data structure</code>, we call it a <code>variable</code>. These variables are no different from the x and y variables you use in math.", "When we store data in a <code>data structure</code>, we call it a <code>variable</code>. These variables are no different from the x and y variables you use in math.",
"Let's create our first variable and call it \"myName\".", "Let's create our first variable and call it \"myName\".",
@ -66,7 +64,7 @@
"Look at the <code>ourName</code> example if you get stuck." "Look at the <code>ourName</code> example if you get stuck."
], ],
"tests": [ "tests": [
"assert((function(){/**/if(typeof(myName) !== \"undefined\" && typeof(myName) === \"string\" && myName.length > 0){return true;}else{return false;}/**/})(), 'myName should be a string that contains at least one character in it');" "assert((function(){if(typeof(myName) !== \"undefined\" && typeof(myName) === \"string\" && myName.length > 0){return true;}else{return false;}})(), 'message: <code>myName</code> should be a string that contains at least one character in it.');"
], ],
"challengeSeed": [ "challengeSeed": [
"// var ourName = \"Free Code Camp\";", "// var ourName = \"Free Code Camp\";",
@ -84,17 +82,16 @@
{ {
"id": "bd7123c9c444eddfaeb5bdef", "id": "bd7123c9c444eddfaeb5bdef",
"title": "Declare String Variables", "title": "Declare String Variables",
"difficulty": "9.9802",
"description": [ "description": [
"In the previous challenge, we used the code <code>var myName = \"your name\"</code>. This is what we call a <code>String</code> variable. It is nothing more than a \"string\" of characters. JavaScript strings are always wrapped in quotes.", "In the previous challenge, we used the code <code>var myName = \"your name\"</code>. This is what we call a <code>String</code> variable. It is nothing more than a \"string\" of characters. JavaScript strings are always wrapped in quotes.",
"Now let's create two new string variables: <code>myFirstName</code>and <code>myLastName</code> and assign them the values of your first and last name, respectively." "Now let's create two new string variables: <code>myFirstName</code>and <code>myLastName</code> and assign them the values of your first and last name, respectively."
], ],
"tests": [ "tests": [
"assert((function(){if(typeof(myFirstName) !== \"undefined\" && typeof(myFirstName) === \"string\" && myFirstName.length > 0){return true;}else{return false;}})(), 'myFirstName should be a string with a least one character in it');", "assert((function(){if(typeof(myFirstName) !== \"undefined\" && typeof(myFirstName) === \"string\" && myFirstName.length > 0){return true;}else{return false;}})(), 'message: <code>myFirstName</code> should be a string with at least one character in it.');",
"assert((function(){if(typeof(myLastName) !== \"undefined\" && typeof(myLastName) === \"string\" && myLastName.length > 0){return true;}else{return false;}})(), 'myLastName should be a string with a least one character in it');" "assert((function(){if(typeof(myLastName) !== \"undefined\" && typeof(myLastName) === \"string\" && myLastName.length > 0){return true;}else{return false;}})(), 'message: <code>myLastName</code> should be a string with at least one character in it.');"
], ],
"challengeSeed": [ "challengeSeed": [
"// name = \"Alan Turing\";", "// var name = \"Alan Turing\";",
"// var firstName = \"Alan\";", "// var firstName = \"Alan\";",
"// var lastName = \"Turing\";", "// var lastName = \"Turing\";",
"", "",
@ -110,15 +107,14 @@
{ {
"id": "bd7123c9c448eddfaeb5bdef", "id": "bd7123c9c448eddfaeb5bdef",
"title": "Check the Length Property of a String Variable", "title": "Check the Length Property of a String Variable",
"difficulty": "9.9809",
"description": [ "description": [
"<code>data structures</code> have <code>properties</code>. For example, <code>strings</code> have a property called <code>.length</code> that will tell you how many characters are in the string.", "<code>Data structures</code> have <code>properties</code>. For example, <code>strings</code> have a property called <code>.length</code> that will tell you how many characters are in the string.",
"For example, if we created a variable <code>var firstName = \"Charles\"</code>, we could find out how long the string \"Charles\" is by using the <code>firstName.length</code> property.", "For example, if we created a variable <code>var firstName = \"Charles\"</code>, we could find out how long the string \"Charles\" is by using the <code>firstName.length</code> property.",
"Use the <code>.length</code> property to count the number of characters in the <code>lastName</code> variable." "Use the <code>.length</code> property to count the number of characters in the <code>lastName</code> variable."
], ],
"tests": [ "tests": [
"assert((function(){if(typeof(lastNameLength) !== \"undefined\" && typeof(lastNameLength) === \"number\" && lastNameLength === 8){return true;}else{return false;}})(), 'lastNameLength should be equal to eight.');", "assert((function(){if(typeof(lastNameLength) !== \"undefined\" && typeof(lastNameLength) === \"number\" && lastNameLength === 8){return true;}else{return false;}})(), 'message: <code>lastNameLength</code> should be equal to eight.');",
"assert((function(){if(editor.getValue().match(/\\.length/gi) && editor.getValue().match(/\\.length/gi).length >= 2 && editor.getValue().match(/var lastNameLength \\= 0;/gi) && editor.getValue().match(/var lastNameLength \\= 0;/gi).length >= 1){return true;}else{return false;}})(), 'You should be getting the length of <code>lastName</code> by using <code>.length</code> like this: <code>lastName.length</code>');" "assert((function(){if(editor.getValue().match(/\\.length/gi) && editor.getValue().match(/\\.length/gi).length >= 2 && editor.getValue().match(/var lastNameLength \\= 0;/gi) && editor.getValue().match(/var lastNameLength \\= 0;/gi).length >= 1){return true;}else{return false;}})(), 'message: You should be getting the length of <code>lastName</code> by using <code>.length</code> like this: <code>lastName.length</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var firstNameLength = 0;", "var firstNameLength = 0;",
@ -129,7 +125,7 @@
"", "",
"var lastName = \"Lovelace\";", "var lastName = \"Lovelace\";",
"", "",
"// don't change code above here", "// Only change code below this line.",
"", "",
"lastNameLength = lastName;", "lastNameLength = lastName;",
"", "",
@ -146,7 +142,6 @@
{ {
"id": "bd7123c9c549eddfaeb5bdef", "id": "bd7123c9c549eddfaeb5bdef",
"title": "Use Bracket Notation to Find the First Character in a String", "title": "Use Bracket Notation to Find the First Character in a String",
"difficulty": "9.9810",
"description": [ "description": [
"<code>Bracket notation</code> is a way to get a character at a specific <code>index</code> within a string.", "<code>Bracket notation</code> is a way to get a character at a specific <code>index</code> within a string.",
"Computers don't start counting at 1 like humans do. They start at 0.", "Computers don't start counting at 1 like humans do. They start at 0.",
@ -155,7 +150,7 @@
"Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck." "Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck."
], ],
"tests": [ "tests": [
"assert((function(){if(typeof(firstLetterOfLastName) !== \"undefined\" && editor.getValue().match(/\\[0\\]/gi) && typeof(firstLetterOfLastName) === \"string\" && firstLetterOfLastName === \"L\"){return true;}else{return false;}})(), 'The first letter of firstLetterOfLastName should be a L');" "assert((function(){if(typeof(firstLetterOfLastName) !== \"undefined\" && editor.getValue().match(/\\[0\\]/gi) && typeof(firstLetterOfLastName) === \"string\" && firstLetterOfLastName === \"L\"){return true;}else{return false;}})(), 'message: The first letter of <code>firstLetterOfLastName</code> should be a <code>\"L\"</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var firstLetterOfFirstName = \"\";", "var firstLetterOfFirstName = \"\";",
@ -181,7 +176,6 @@
{ {
"id": "bd7123c9c450eddfaeb5bdef", "id": "bd7123c9c450eddfaeb5bdef",
"title": "Use Bracket Notation to Find the Nth Character in a String", "title": "Use Bracket Notation to Find the Nth Character in a String",
"difficulty": "9.9811",
"description": [ "description": [
"You can also use <code>bracket Notation</code>to get the character at other positions within a string.", "You can also use <code>bracket Notation</code>to get the character at other positions within a string.",
"Remember that computers start counting at 0, so the first character is actually the zeroth character.", "Remember that computers start counting at 0, so the first character is actually the zeroth character.",
@ -189,7 +183,7 @@
"Try looking at the <code>secondLetterOfFirstName</code> variable declaration if you get stuck." "Try looking at the <code>secondLetterOfFirstName</code> variable declaration if you get stuck."
], ],
"tests": [ "tests": [
"assert(thirdLetterOfLastName === 'v', 'The third letter of lastName should be a \"v\"');" "assert(thirdLetterOfLastName === 'v', 'message: The third letter of <code>lastName</code> should be a \"v\".');"
], ],
"challengeSeed": [ "challengeSeed": [
"var firstName = \"Ada\";", "var firstName = \"Ada\";",
@ -212,7 +206,6 @@
{ {
"id": "bd7123c9c451eddfaeb5bdef", "id": "bd7123c9c451eddfaeb5bdef",
"title": "Use Bracket Notation to Find the Last Character in a String", "title": "Use Bracket Notation to Find the Last Character in a String",
"difficulty": "9.9812",
"description": [ "description": [
"In order to get the last letter of a string, you can subtract one from the string's length.", "In order to get the last letter of a string, you can subtract one from the string's length.",
"For example, if <code>var firstName = \"Charles\"</code>, you can get the value of the last letter of the string by using <code>firstName[firstName.length - 1]</code>.", "For example, if <code>var firstName = \"Charles\"</code>, you can get the value of the last letter of the string by using <code>firstName[firstName.length - 1]</code>.",
@ -220,8 +213,8 @@
"Try looking at the <code>lastLetterOfFirstName</code> variable declaration if you get stuck." "Try looking at the <code>lastLetterOfFirstName</code> variable declaration if you get stuck."
], ],
"tests": [ "tests": [
"assert(lastLetterOfLastName === \"e\", 'lastLetterOfLastName should be \"e\"');", "assert(lastLetterOfLastName === \"e\", 'message: <code>lastLetterOfLastName</code> should be \"e\".');",
"assert(editor.getValue().match(/\\.length/g), 'You have to use <code>.length</code> to get the last letter');" "assert(editor.getValue().match(/\\.length/g).length === 2, 'message: You have to use <code>.length</code> to get the last letter.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var firstName = \"Ada\";", "var firstName = \"Ada\";",
@ -244,16 +237,15 @@
{ {
"id": "bd7123c9c452eddfaeb5bdef", "id": "bd7123c9c452eddfaeb5bdef",
"title": "Use Bracket Notation to Find the Nth-to-Last Character in a String", "title": "Use Bracket Notation to Find the Nth-to-Last Character in a String",
"difficulty": "9.9813",
"description": [ "description": [
"In order to get the last letter of a string, you can subtract one from the string's length.", "In order to get the last letter of a string, you can subtract one from the string's length.",
"For example, you can get the value of the third-to-last letter of the <code>var firstName = \"Charles\"</code> string by using <code>firstName[firstName.length - 3]</code>.", "For example, you can get the value of the third-to-last letter of the <code>var firstName = \"Charles\"</code> string by using <code>firstName[firstName.length - 3]</code>.",
"Use <code>bracket notation</code> to find the second-to-last character in the <code>lastName</code> string.", "Use <code>bracket notation</code> to find the second-to-last character in the <code>lastName</code> string.",
"Try looking at the <code>lastLetterOfLastName</code> variable declaration if you get stuck." "Try looking at the <code>thirdToLastLetterOfFirstName</code> variable declaration if you get stuck."
], ],
"tests": [ "tests": [
"assert(secondToLastLetterOfLastName === 'c', 'secondToLastLetterOfLastName should be \"c\".');", "assert(secondToLastLetterOfLastName === 'c', 'message: <code>secondToLastLetterOfLastName</code> should be \"c\".');",
"assert(editor.getValue().match(/\\.length/g), 'You have to use .length to get the third last letter.');" "assert(editor.getValue().match(/\\.length/g).length === 2, 'message: You have to use <code>.length</code> to get the second last letter.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var firstName = \"Ada\";", "var firstName = \"Ada\";",
@ -276,14 +268,13 @@
{ {
"id": "cf1111c1c11feddfaeb3bdef", "id": "cf1111c1c11feddfaeb3bdef",
"title": "Add Two Numbers with JavaScript", "title": "Add Two Numbers with JavaScript",
"difficulty": "9.98141",
"description": [ "description": [
"Let's try to add two numbers using JavaScript.", "Let's try to add two numbers using JavaScript.",
"JavaScript uses the <code>+</code> symbol for addition.", "JavaScript uses the <code>+</code> symbol for addition.",
"Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment." "Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment."
], ],
"tests": [ "tests": [
"assert((function(){if(sum === 20 && editor.getValue().match(/\\+/g)){return true;}else{return false;}})(), 'Make the variable <code>sum</code> equal 20');" "assert((function(){if(sum === 20 && editor.getValue().match(/\\+/g).length >= 2){return true;}else{return false;}})(), 'message: Make the variable <code>sum</code> equal 20.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var sum = 10 + 0; //make this equal to 20 by changing the 0 into the appropriate number.", "var sum = 10 + 0; //make this equal to 20 by changing the 0 into the appropriate number.",
@ -299,14 +290,13 @@
{ {
"id": "cf1111c1c11feddfaeb4bdef", "id": "cf1111c1c11feddfaeb4bdef",
"title": "Subtract One Number from Another with JavaScript", "title": "Subtract One Number from Another with JavaScript",
"difficulty": "9.98142",
"description": [ "description": [
"We can also subtract one number from another.", "We can also subtract one number from another.",
"JavaScript uses use the <code>-</code> symbol for subtraction.", "JavaScript uses the <code>-</code> symbol for subtraction.",
"Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment." "Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment."
], ],
"tests": [ "tests": [
"assert((function(){if(difference === 12 && editor.getValue().match(/\\-/g)){return true;}else{return false;}})(), 'Make the variable <code>difference</code> equal 12');" "assert((function(){if(difference === 12 && editor.getValue().match(/\\-/g)){return true;}else{return false;}})(), 'message: Make the variable <code>difference</code> equal 12.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var difference = 45 - 0; //make this equal to 12 by changing the 0 into the appropriate number.", "var difference = 45 - 0; //make this equal to 12 by changing the 0 into the appropriate number.",
@ -322,17 +312,16 @@
{ {
"id": "cf1231c1c11feddfaeb5bdef", "id": "cf1231c1c11feddfaeb5bdef",
"title": "Multiply Two Numbers with JavaScript", "title": "Multiply Two Numbers with JavaScript",
"difficulty": "9.98143",
"description": [ "description": [
"We can also multiply one number by another.", "We can also multiply one number by another.",
"JavaScript uses use the <code>*</code> symbol for multiplication.", "JavaScript uses the <code>*</code> symbol for multiplication.",
"Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment." "Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment."
], ],
"tests": [ "tests": [
"assert((function(){if(product === 80 && editor.getValue().match(/\\*/g)){return true;}else{return false;}})(), 'Make the variable <code>product</code> equal 80.');" "assert((function(){if(product === 80 && editor.getValue().match(/\\*/g)){return true;}else{return false;}})(), 'message: Make the variable <code>product</code> equal 80.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var product = 8 * 0; //make this equal to 80 by changing the 0 into the appropriate number.", "var product = 8 * 0; // Make this equal to 80 by changing the 0 into the appropriate number.",
"", "",
"// Only change code above this line.", "// Only change code above this line.",
"// We use this function to show you the value of your variable in your output box.", "// We use this function to show you the value of your variable in your output box.",
@ -345,14 +334,13 @@
{ {
"id": "cf1111c1c11feddfaeb6bdef", "id": "cf1111c1c11feddfaeb6bdef",
"title": "Divide One Number by Another with JavaScript", "title": "Divide One Number by Another with JavaScript",
"difficulty": "9.9814",
"description": [ "description": [
"We can also divide one number by another.", "We can also divide one number by another.",
"JavaScript uses use the <code>/</code> symbol for division.", "JavaScript uses the <code>/</code> symbol for division.",
"Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment." "Replace the <code>0</code> with the correct number so you can get the result mentioned in the comment."
], ],
"tests": [ "tests": [
"assert((function(){if(quotient === 2 && editor.getValue().match(/\\//g)){return true;}else{return false;}})(), 'Make the variable <code>quotient</code> equal 2.');" "assert((function(){if(quotient === 2 && editor.getValue().match(/var\\s*?quotient\\s*?\\=\\s*?\\d+\\s*?\\/\\s*?\\d+\\s*?;/g)){return true;}else{return false;}})(), 'message: Make the variable <code>quotient</code> equal 2.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var quotient = 66 / 0; //make this equal to 2 by changing the 0 into the appropriate number.", "var quotient = 66 / 0; //make this equal to 2 by changing the 0 into the appropriate number.",
@ -368,13 +356,12 @@
{ {
"id": "cf1391c1c11feddfaeb4bdef", "id": "cf1391c1c11feddfaeb4bdef",
"title": "Create Decimal Numbers with JavaScript", "title": "Create Decimal Numbers with JavaScript",
"difficulty": "9.9815",
"description": [ "description": [
"JavaScript number variables can also have decimals.", "JavaScript number variables can also have decimals.",
"Let's create a variable <code>myDecimal</code> and give it a decimal value." "Let's create a variable <code>myDecimal</code> and give it a decimal value."
], ],
"tests": [ "tests": [
"assert((function(){if(typeof(myDecimal) !== \"undefined\" && typeof(myDecimal) === \"number\" && editor.getValue().match(/\\./g).length >=2){return true;}else{return false;}})(), 'myDecimal should be a decimal point number.');" "assert((function(){if(typeof(myDecimal) !== \"undefined\" && typeof(myDecimal) === \"number\" && editor.getValue().match(/\\./g).length >=2){return true;}else{return false;}})(), 'message: <code>myDecimal</code> should be a decimal point number.');"
], ],
"challengeSeed": [ "challengeSeed": [
"// var ourDecimal = 5.7;", "// var ourDecimal = 5.7;",
@ -393,14 +380,13 @@
{ {
"id": "bd7993c9c69feddfaeb7bdef", "id": "bd7993c9c69feddfaeb7bdef",
"title": "Perform Arithmetic Operations on Decimals with JavaScript", "title": "Perform Arithmetic Operations on Decimals with JavaScript",
"difficulty": "9.98151",
"description": [ "description": [
"In JavaScript, you can also perform calculations with decimal numbers, just like whole numbers.", "In JavaScript, you can also perform calculations with decimal numbers, just like whole numbers.",
"Replace the <code>0.0</code> with the correct number so that you get the result mentioned in the comments." "Replace the <code>0.0</code> with the correct number so that you get the result mentioned in the comments."
], ],
"tests": [ "tests": [
"assert((function(){if(product === 5.0 && editor.getValue().match(/\\*/g)){return true;}else{return false;}})(), 'Make the variable <code>product</code> equal 5.0.');", "assert((function(){if(product === 5.0 && editor.getValue().match(/\\*/g)){return true;}else{return false;}})(), 'message: Make the variable <code>product</code> equal 5.0.');",
"assert((function(){if(quotient === 2.2 && editor.getValue().match(/\\//g)){return true;}else{return false;}})(), 'Make the variable <code>quotient</code> equal 2.2.');" "assert((function(){if(quotient === 2.2 && editor.getValue().match(/\\//g)){return true;}else{return false;}})(), 'message: Make the variable <code>quotient</code> equal 2.2.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var quotient = 4.4 / 2.0; // equals 2.2", "var quotient = 4.4 / 2.0; // equals 2.2",
@ -418,17 +404,16 @@
{ {
"id": "bd7993c9c69feddfaeb8bdef", "id": "bd7993c9c69feddfaeb8bdef",
"title": "Store Multiple Values in one Variable using JavaScript Arrays", "title": "Store Multiple Values in one Variable using JavaScript Arrays",
"difficulty": "9.9816",
"description": [ "description": [
"With JavaScript <code>array</code> variables, we can store several pieces of data in one place.", "With JavaScript <code>array</code> variables, we can store several pieces of data in one place.",
"You start an array declaration with an opening bracket, end it with a closing bracket, and put a comma between each entry, like this: <code>var sandwich = [\"peanut butter\", \"jelly\", \"bread\"]</code>.", "You start an array declaration with an opening square bracket, end it with a closing square bracket, and put a comma between each entry, like this: <code>var sandwich = [\"peanut butter\", \"jelly\", \"bread\"]</code>.",
"Now let's create a new array called <code>myArray</code> that contains both a <code>string</code> and a <code>number</code>.", "Now let's create a new array called <code>myArray</code> that contains both a <code>string</code> and a <code>number</code> (in that order).",
"Refer to the comments if you get stuck." "Refer to the commented code in the text editor if you get stuck."
], ],
"tests": [ "tests": [
"assert(typeof(myArray) == 'object', 'myArray should be an array');", "assert(typeof(myArray) == 'object', 'message: <code>myArray</code> should be an <code>array</code>.');",
"assert(typeof(myArray[0]) !== 'undefined' && typeof(myArray[0]) == 'string', 'The first item in myArray should be a string');", "assert(typeof(myArray[0]) !== 'undefined' && typeof(myArray[0]) == 'string', 'message: The first item in <code>myArray</code> should be a <code>string</code>.');",
"assert(typeof(myArray[1]) !== 'undefined' && typeof(myArray[1]) == 'number', 'The second item in myArray should be a number');" "assert(typeof(myArray[1]) !== 'undefined' && typeof(myArray[1]) == 'number', 'message: The second item in <code>myArray</code> should be a <code>number</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"// var array = [\"John\", 23];", "// var array = [\"John\", 23];",
@ -450,11 +435,11 @@
"title": "Nest one Array within Another Array", "title": "Nest one Array within Another Array",
"difficulty":"9.98161", "difficulty":"9.98161",
"description":[ "description":[
"You can also nest arrays within other arrays, like this: <code>[[\"Bulls\", 43]]</code>.", "You can also nest arrays within other arrays, like this: <code>[[\"Bulls\", 23]]</code>.",
"Let's now go create a nested array called <code>myArray</code>." "Let's now go create a nested array called <code>myArray</code>."
], ],
"tests":[ "tests":[
"assert(Array.isArray(myArray) && myArray.some(Array.isArray), '<code>myArray</code> should have at least one array nested within another array.');" "assert(Array.isArray(myArray) && myArray.some(Array.isArray), 'message: <code>myArray</code> should have at least one array nested within another array.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var ourArray = [[\"the universe\", \"everything\", 42]];", "var ourArray = [[\"the universe\", \"everything\", 42]];",
@ -484,7 +469,7 @@
"Create a variable called <code>myData</code> and set it to equal the first value of <code>myArray</code>." "Create a variable called <code>myData</code> and set it to equal the first value of <code>myArray</code>."
], ],
"tests":[ "tests":[
"assert((function(){if(typeof(myArray) != 'undefined' && typeof(myData) != 'undefined' && myArray[0] == myData){return true;}else{return false;}})(), 'The variable <code>myData</code> should equal the first value of myArray');" "assert((function(){if(typeof(myArray) != 'undefined' && typeof(myData) != 'undefined' && myArray[0] == myData){return true;}else{return false;}})(), 'message: The variable <code>myData</code> should equal the first value of <code>myArray</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"// var ourArray = [1,2,3];", "// var ourArray = [1,2,3];",
@ -514,13 +499,13 @@
"Now modify the data stored at index 0 of <code>myArray</code> to the value of 3." "Now modify the data stored at index 0 of <code>myArray</code> to the value of 3."
], ],
"tests":[ "tests":[
"assert((function(){if(typeof(myArray) != 'undefined' && myArray[0] == 3 && myArray[1] == 2 && myArray[2] == 3){return true;}else{return false;}})(), 'myArray should now be [3,2,3]');", "assert((function(){if(typeof(myArray) != 'undefined' && myArray[0] == 3 && myArray[1] == 2 && myArray[2] == 3){return true;}else{return false;}})(), 'message: <code>myArray</code> should now be [3,2,3].');",
"assert((function(){if(editor.getValue().match(/myArray\\[0\\]\\s?=\\s?/g)){return true;}else{return false;}})(), 'You should be using correct index to modify the value in myArray');" "assert((function(){if(editor.getValue().match(/myArray\\[0\\]\\s?=\\s?/g)){return true;}else{return false;}})(), 'message: You should be using correct index to modify the value in <code>myArray</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var ourArray = [1,2,3];", "var ourArray = [1,2,3];",
"ourArray[1] = 3;", "ourArray[1] = 3;",
"// ourArray[1] now equals [1,3,3].", "// ourArray now equals [1,3,3].",
"var myArray = [1,2,3];", "var myArray = [1,2,3];",
"// Only change code below this line.", "// Only change code below this line.",
"", "",
@ -536,16 +521,15 @@
{ {
"id": "bg9994c9c69feddfaeb9bdef", "id": "bg9994c9c69feddfaeb9bdef",
"title": "Manipulate Arrays With pop()", "title": "Manipulate Arrays With pop()",
"difficulty": "9.9818",
"description": [ "description": [
"Another way to change the data in an array is with the <code>.pop()</code> function.", "Another way to change the data in an array is with the <code>.pop()</code> function.",
"<code>.pop()</code>is used to \"pop\" a value off of the end of an array. We can retrieve this value by performing <code>pop()</code> in a variable declaration.", "<code>.pop()</code>is used to \"pop\" a value off of the end of an array. We can retrieve this value by performing <code>pop()</code> in a variable declaration.",
"Any type of variable can be \"popped\" off of an array.", "Any type of variable can be \"popped\" off of an array.",
"Use the <code>.pop()</code> function to remove the last item from myArray." "Use the <code>.pop()</code> function to remove the last item from <code>myArray</code>."
], ],
"tests": [ "tests": [
"assert((function(d){if(d[0] == 'John' && d[1] == 23 && d[2] == undefined){return true;}else{return false;}})(myArray), 'myArray should only have the first two values left([\"John\", 23])');", "assert((function(d){if(d[0] == 'John' && d[1] == 23 && d[2] == undefined){return true;}else{return false;}})(myArray), 'message: <code>myArray</code> should only contain <code>[\"John\", 23]</code>.');",
"assert((function(d){if(d[0] == 'cat' && d[1] == 2 && d[2] == undefined){return true;}else{return false;}})(removed), 'myArray should only have the first two values left([\"cat\"], 2)');" "assert((function(d){if(d[0] == 'cat' && d[1] == 2 && d[2] == undefined){return true;}else{return false;}})(removed), 'message: <code>removed</code> should only contain <code>[\"cat\"], 2</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"// var numbers = [1,2,3];", "// var numbers = [1,2,3];",
@ -570,23 +554,22 @@
{ {
"id": "bg9995c9c69feddfaeb9bdef", "id": "bg9995c9c69feddfaeb9bdef",
"title": "Manipulate Arrays With push()", "title": "Manipulate Arrays With push()",
"difficulty": "9.9818",
"description": [ "description": [
"Not only can you <code>pop()</code> data off of the end of an array, you can also <code>push()</code> data onto the end of an array.", "Not only can you <code>pop()</code> data off of the end of an array, you can also <code>push()</code> data onto the end of an array.",
"Take the myArray array and <code>push()</code> this value to the end of it: <code>[\"dog\", 3]</code>." "Take the <code>myArray</code> array and <code>push()</code> this value to the end of it: <code>[\"dog\", 3]</code>."
], ],
"tests": [ "tests": [
"assert((function(d){if(d[2] != undefined && d[0] == 'John' && d[1] == 23 && d[2][0] == 'dog' && d[2][1] == 3 && d[2].length == 2){return true;}else{return false;}})(myArray), 'myArray should only have the first two values left([\"John\", 23, [\"dog\", 3]])');" "assert((function(d){if(d[2] != undefined && d[0] == 'John' && d[1] == 23 && d[2][0] == 'dog' && d[2][1] == 3 && d[2].length == 2){return true;}else{return false;}})(myArray), 'message: <code>myArray</code> should now equal <code>[\"John\", 23, [\"dog\", 3]]</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];", "var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];",
"ourArray.pop();", "ourArray.pop();",
"ourArray.push([\"happy\", \"joy\"]);", "ourArray.push([\"happy\", \"joy\"]);",
"// ourArray now equals [\"Stimpson\", \"J\", [\"happy\", \"joy\"]]", "// ourArray now equals [\"Stimpson\", \"J\", [\"happy\", \"joy\"]].",
"", "",
"var myArray = [\"John\", 23, [\"cat\", 2]];", "var myArray = [\"John\", 23, [\"cat\", 2]];",
"myArray.pop();", "myArray.pop();",
"//Add a [\"dog\", 3] to the end of myArray using push()", "// Add a [\"dog\", 3] to the end of myArray using push().",
"// Only change code below this line.", "// Only change code below this line.",
"", "",
"", "",
@ -601,24 +584,23 @@
{ {
"id": "bg9996c9c69feddfaeb9bdef", "id": "bg9996c9c69feddfaeb9bdef",
"title": "Manipulate Arrays With shift()", "title": "Manipulate Arrays With shift()",
"difficulty": "9.9817",
"description": [ "description": [
"<code>pop()</code> always removes the last element of an array. What if you want to remove the first? That's where <code>.shift()</code> comes in.", "<code>pop()</code> always removes the last element of an array. What if you want to remove the first? That's where <code>.shift()</code> comes in.",
"Take the myArray array and <code>shift()</code> the first value off of it." "Take the <code>myArray</code> array and <code>shift()</code> the first value off of it. Set <code>myRemoved</code> to the first value of <code>myArray</code> using <code>shift()</code>."
], ],
"tests": [ "tests": [
"assert((function(d){if(d[0] == 23 && d[1][0] == 'dog' && d[1][1] == 3 && d[2] == undefined){return true;}else{return false;}})(myArray), 'myArray should only have the last two values left([23, [\"dog\", 3]])');", "assert((function(d){if(d[0] == 23 && d[1][0] == 'dog' && d[1][1] == 3 && d[2] == undefined){return true;}else{return false;}})(myArray), 'message: <code>myArray</code> should now equal <code>[23, [\"dog\", 3]]</code>.');",
"assert((function(d){if(d === 'John' && typeof(myRemoved) === 'string'){return true;}else{return false;}})(myRemoved), 'myRemoved should contain \"John\"');" "assert((function(d){if(d === 'John' && typeof(myRemoved) === 'string'){return true;}else{return false;}})(myRemoved), 'message: <code>myRemoved</code> should contain <code>\"John\"</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];", "var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];",
"ourRemoved = ourArray.shift();", "ourRemoved = ourArray.shift();",
"// ourArray now equals [\"J\", [\"cat\"]]", "// ourArray now equals [\"J\", [\"cat\"]].",
"", "",
"var myArray = [\"John\", 23, [\"dog\", 3]];", "var myArray = [\"John\", 23, [\"dog\", 3]];",
"// Only change code below this line.", "// Only change code below this line.",
"", "",
"var myRemoved = myArray; // This should be [\"John\"] and myArray should now be [23, [\"dog\", 3]]", "var myRemoved = myArray; // This should be [\"John\"] and myArray should now be [23, [\"dog\", 3]].",
"", "",
"// Only change code above this line.", "// Only change code above this line.",
"", "",
@ -632,24 +614,24 @@
{ {
"id": "bg9997c9c69feddfaeb9bdef", "id": "bg9997c9c69feddfaeb9bdef",
"title": "Manipulate Arrays With unshift()", "title": "Manipulate Arrays With unshift()",
"difficulty": "9.9818",
"description": [ "description": [
"Now that we've learned how to <code>shift</code>things from the start of the array, we need to learn how to <code>unshift</code>stuff back to the start", "Now that we've learned how to <code>shift</code>things from the start of the array, we need to learn how to <code>unshift</code>stuff back to the start.",
"Let's take the code we had last time and <code>unshift</code>this value to the start: <code>\"Paul\" </code>" "Let's take the code we had last time and <code>unshift</code>this value to the start: <code>\"Paul\"</code>."
], ],
"tests": [ "tests": [
"assert((function(d){if(d[0].toLowerCase() == 'paul' && d[1] == 23 && d[2][0] != undefined && d[2][0] == 'dog' && d[2][1] != undefined && d[2][1] == 3){return true;}else{return false;}})(myArray), 'myArray should now have [\"Paul\", 23, [\"dog\", 3]])');" "assert((function(d){if(typeof(d[0]) === \"string\" && d[0].toLowerCase() == 'paul' && d[1] == 23 && d[2][0] != undefined && d[2][0] == 'dog' && d[2][1] != undefined && d[2][1] == 3){return true;}else{return false;}})(myArray), 'message: <code>myArray</code> should now have [\"Paul\", 23, [\"dog\", 3]]).');"
], ],
"challengeSeed": [ "challengeSeed": [
"var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];", "var ourArray = [\"Stimpson\", \"J\", [\"cat\"]];",
"ourArray.shift();", "ourArray.shift();",
"ourArray.unshift([\"happy\", \"joy\"]);", "// ourArray now equals [\"J\", [\"cat\"]]",
"// ourArray now equals [[\"happy\", \"joy\"], \"J\", [\"cat\"]]", "ourArray.unshift(\"happy\");",
"// ourArray now equals [\"happy\", \"J\", [\"cat\"]]",
"", "",
"var myArray = [\"John\", 23, [\"dog\", 3]];", "var myArray = [\"John\", 23, [\"dog\", 3]];",
"myArray.shift();", "myArray.shift();",
"", "",
"// Add \"Paul\" to the start of myArray", "// Add \"Paul\" to the start of myArray.",
"// Only change code below this line.", "// Only change code below this line.",
"", "",
"", "",
@ -666,26 +648,27 @@
"title": "Write Reusable JavaScript with Functions", "title": "Write Reusable JavaScript with Functions",
"difficulty":"9.9819", "difficulty":"9.9819",
"description":[ "description":[
"In JavaScript, we can divide up our code into reusable parts called <code>functions</code>.", "In JavaScript, we can divide up our code into reusable parts called functions.",
"Here's an example of a function:", "Here's an example of a function:",
"<code>function functionName(a, b) {</code>", "<code>function functionName(a, b) {</code>",
"<code>&thinsp;&thinsp;return a + b;</code>", "<code>&thinsp;&thinsp;return a + b;</code>",
"<code>}</code>", "<code>}</code>",
"We can \"call\" our function like this: <code>functionName();</code>, and it will run and return its <code>return</code> value to us.", "After writing the above lines in our code, we can then pass values to our function and the result following the <code>return</code> statement will be returned.",
"Create and call a function called <code>myFunction</code> that returns the sum of a and b." "For example, we can pass numbers <code>4</code> and <code>2</code> by “calling” the function later in our code like this: <code>functionName(4, 2)</code>.",
"In this example, the function will return the number <code>6</code> as this is the result of <code>4 + 2</code>.",
"Create and call a function called <code>myFunction</code> that returns the sum of <code>a</code> and <code>b</code>."
], ],
"tests":[ "tests":[
"assert((function(){if(typeof(f) !== \"undefined\" && typeof(f) === \"number\" && f === a + b && editor.getValue().match(/return/gi).length >= 1 && editor.getValue().match(/a/gi).length >= 1 && editor.getValue().match(/b/gi).length >= 1 && editor.getValue().match(/\\+/gi).length >= 1){return true;}else{return false;}})(), 'Your function should return the value of a + b');" "assert((function(){if(typeof(f) !== \"undefined\" && f === a + b){return true;}else{return false;}})(), 'message: Your function should return the value of a + b');"
], ],
"challengeSeed":[ "challengeSeed":[
"var a = 4;", "var a = 4;",
"var b = 5;", "var b = 5;",
"", "",
"ourFunction = function() {", "function ourFunction(a, b) {",
" return a - b;", " return a - b;",
"};", "}",
"", "",
"// Don't modify above this line",
"// Create a function called myFunction that returns the value of a plus b.", "// Create a function called myFunction that returns the value of a plus b.",
"// Only change code below this line.", "// Only change code below this line.",
"", "",
@ -719,13 +702,13 @@
"<code>};</code>", "<code>};</code>",
"</code>", "</code>",
"Objects are useful for storing data in a structured way, and can represent real world objects, like a cat.", "Objects are useful for storing data in a structured way, and can represent real world objects, like a cat.",
"Let's try to make an Object that represents a dog called myDog which contains the properties 'name' (String), 'legs' (Number), 'tails' (Number) and 'friends' (Array)!" "Let's try to make an object that represents a dog called <code>myDog</code> which contains the properties <code>'name'</code> (String), <code>'legs'</code> (Number), <code>'tails'</code> (Number) and <code>'friends'</code> (Array)!"
], ],
"tests":[ "tests":[
"assert((function(z){if(z.hasOwnProperty(\"name\") && z.name !== undefined && typeof(z.name) === \"string\"){return true;}else{return false;}})(myDog), 'myDog should contain the property name and it should be a string');", "assert((function(z){if(z.hasOwnProperty(\"name\") && z.name !== undefined && typeof(z.name) === \"string\"){return true;}else{return false;}})(myDog), 'message: <code>myDog</code> should contain the property <code>name</code> and it should be a <code>string</code>.');",
"assert((function(z){if(z.hasOwnProperty(\"legs\") && z.legs !== undefined && typeof(z.legs) === \"number\"){return true;}else{return false;}})(myDog), 'myDog should contain the property legs and it should be a number');", "assert((function(z){if(z.hasOwnProperty(\"legs\") && z.legs !== undefined && typeof(z.legs) === \"number\"){return true;}else{return false;}})(myDog), 'message: <code>myDog</code> should contain the property <code>legs</code> and it should be a <code>number</code>.');",
"assert((function(z){if(z.hasOwnProperty(\"tails\") && z.tails !== undefined && typeof(z.tails) === \"number\"){return true;}else{return false;}})(myDog), 'myDog should contain the property tails and it should be a number');", "assert((function(z){if(z.hasOwnProperty(\"tails\") && z.tails !== undefined && typeof(z.tails) === \"number\"){return true;}else{return false;}})(myDog), 'message: <code>myDog</code> should contain the property <code>tails</code> and it should be a <code>number</code>.');",
"assert((function(z){if(z.hasOwnProperty(\"friends\") && z.friends !== undefined && Array.isArray(z.friends)){return true;}else{return false;}})(myDog), 'myDog should contain the property friends and it should be an array');" "assert((function(z){if(z.hasOwnProperty(\"friends\") && z.friends !== undefined && Array.isArray(z.friends)){return true;}else{return false;}})(myDog), 'message: <code>myDog</code> should contain the property <code>friends</code> and it should be an <code>array</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"// var ourDog = {", "// var ourDog = {",
@ -735,7 +718,7 @@
"// \"friends\": [\"everything!\"]", "// \"friends\": [\"everything!\"]",
"// };", "// };",
"", "",
"// add the name(string), legs(number), tails(number) and friends(array) properties to myDog.", "// Add the name (string), legs (number), tails (number) and friends (array) properties to myDog.",
"// You can set them to whatever you want.", "// You can set them to whatever you want.",
"", "",
"// Only change code below this line.", "// Only change code below this line.",
@ -761,11 +744,11 @@
"<code>myObject.myProperty = \"myValue\";</code>", "<code>myObject.myProperty = \"myValue\";</code>",
"We can also delete them like this:", "We can also delete them like this:",
"<code>delete myObject.myProperty;</code>", "<code>delete myObject.myProperty;</code>",
"Let's add the property \"bark\", and delete the property \"tails\"." "Let's add the property <code>\"bark\"</code>, and delete the property <code>\"tails\"</code>."
], ],
"tests":[ "tests":[
"assert(myDog.bark !== undefined, 'Add the property \"bark\" to myDog.');", "assert(myDog.bark !== undefined, 'message: Add the property <code>\"bark\"</code> to <code>myDog</code>.');",
"assert(myDog.tails === undefined, 'Delete the property \"tails\" from myDog.');" "assert(myDog.tails === undefined, 'message: Delete the property <code>\"tails\"</code> from <code>myDog</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"// var ourDog = {", "// var ourDog = {",
@ -815,8 +798,8 @@
"Let's try getting a for loop to work by pushing values to an array." "Let's try getting a for loop to work by pushing values to an array."
], ],
"tests":[ "tests":[
"assert(editor.getValue().match(/for/g), 'You should be using a for loop for this.');", "assert(editor.getValue().match(/for/g), 'message: You should be using a <code>for</code> loop for this.');",
"assert.deepEqual(myArray, [0,1,2,3,4], 'myArray should equal [0,1,2,3,4]');" "assert.deepEqual(myArray, [0,1,2,3,4], 'message: <code>myArray</code> should equal [0,1,2,3,4].');"
], ],
"challengeSeed":[ "challengeSeed":[
"ourArray = [];", "ourArray = [];",
@ -824,8 +807,15 @@
" ourArray.push(i);", " ourArray.push(i);",
"}", "}",
"var myArray = [];", "var myArray = [];",
"",
"// Only change code below this line.",
"",
"// Push the numbers zero through four to myArray using a \"for loop\" like above.", "// Push the numbers zero through four to myArray using a \"for loop\" like above.",
"", "",
"// Only change code above this line.",
"// We use this function to show you the value of your variable in your output box.",
"// You'll learn about functions soon.",
"if(typeof(myArray) !== \"undefined\"){(function(){return myArray;})();}",
"" ""
], ],
"type": "waypoint", "type": "waypoint",
@ -847,13 +837,19 @@
"Let's try getting a while loop to work by pushing values to an array." "Let's try getting a while loop to work by pushing values to an array."
], ],
"tests":[ "tests":[
"assert(editor.getValue().match(/while/g), 'You should be using a while loop for this.');", "assert(editor.getValue().match(/while/g), 'message: You should be using a <code>while</code> loop for this.');",
"assert.deepEqual(myArray, [0,1,2,3,4], 'myArray should equal [0,1,2,3,4]');" "assert.deepEqual(myArray, [0,1,2,3,4], 'message: <code>myArray</code> should equal [0,1,2,3,4].');"
], ],
"challengeSeed":[ "challengeSeed":[
"var myArray = [];", "var myArray = [];",
"//Push the numbers zero through four to myArray", "// Only change code below this line.",
"", "",
"// Push the numbers zero through four to myArray using a \"while loop\".",
"",
"// Only change code above this line.",
"// We use this function to show you the value of your variable in your output box.",
"// You'll learn about functions soon.",
"if(typeof(myArray) !== \"undefined\"){(function(){return myArray;})();}",
"" ""
], ],
"type": "waypoint", "type": "waypoint",
@ -869,13 +865,13 @@
"Use <code>Math.random()</code> to get <code>myFunction</code> to return a random number." "Use <code>Math.random()</code> to get <code>myFunction</code> to return a random number."
], ],
"tests":[ "tests":[
"assert(typeof(myFunction()) === \"number\", 'myFunction should return a random number');", "assert(typeof(myFunction()) === \"number\", 'message: <code>myFunction</code> should return a random number.');",
"assert((myFunction()+''). match(/\\./g), 'The number returned by myFunction should be a decimal');", "assert((myFunction()+''). match(/\\./g), 'message: The number returned by <code>myFunction</code> should be a decimal.');",
"assert(editor.getValue().match(/Math\\.random/g).length >= 2, 'You should be using Math.random to generate the random decimal number');" "assert(editor.getValue().match(/Math\\.random/g).length >= 2, 'message: You should be using <code>Math.random</code> to generate the random decimal number.');"
], ],
"challengeSeed":[ "challengeSeed":[
"function myFunction() {", "function myFunction() {",
" //Change the 0 to Math.random()", " // Change the 0 to Math.random().",
" // Only change code below this line.", " // Only change code below this line.",
"", "",
" return 0;", " return 0;",
@ -895,21 +891,21 @@
"difficulty":"9.9828", "difficulty":"9.9828",
"description":[ "description":[
"It's great that we can create random decimal numbers, but it's even more useful if we use it to generate a random whole number.", "It's great that we can create random decimal numbers, but it's even more useful if we use it to generate a random whole number.",
"To achieve this we can multiply the random number by ten and use the <code>Math.floor()</code> to convert the decimal number to a whole number.", "To achieve this we can multiply the random number by ten and use the <code>Math.floor()</code> to convert the decimal number to the nearest less than or equal whole number.",
"This technique gives us a whole number between zero and nine.", "This technique gives us a whole number between zero and nine.",
"Example:", "Example:",
"<code>Math.floor(Math.random()*10);</code>", "<code>Math.floor(Math.random()*10);</code>",
"Let's give this technique a go now." "Let's give this technique a go now."
], ],
"tests":[ "tests":[
"assert(typeof(myFunction()) === \"number\", 'The result of myFunction should be a number');", "assert(typeof(myFunction()) === \"number\", 'message: The result of <code>myFunction</code> should be a number.');",
"assert(editor.getValue().match(/Math.random/g), 'You should be using Math.random to create a random number');", "assert(editor.getValue().match(/Math.random/g), 'message: You should be using Math.random to create a random number.');",
"assert(!(''+myFunction()).match(/\\./g), 'You should have multiplied the result of Math.random by 10 to make it a number that\\'s greater than zero');", "assert(editor.getValue().match(/\\(\\s*?Math.random\\s*?\\(\\s*?\\)\\s*?\\*\\s*?10\\s*?\\)/g) || editor.getValue().match(/\\(\\s*?10\\s*?\\*\\s*?Math.random\\s*?\\(\\s*?\\)\\s*?\\)/g), 'message: You should have multiplied the result of <code>Math.random</code> by 10 to make it a number that is between zero and nine.');",
"assert(editor.getValue().match(/Math.floor/g), 'You should use Math.floor to remove the decimal part of the number');" "assert(editor.getValue().match(/Math.floor/g), 'message: You should use <code>Math.floor</code> to remove the decimal part of the number.');"
], ],
"challengeSeed":[ "challengeSeed":[
"function myFunction(){", "function myFunction(){",
" // Make myFunction return a random number betweenzero and nine> instead of a decimal", " // Make myFunction return a random number between zero and nine instead of a decimal.",
"", "",
" // Only change code below this line.", " // Only change code below this line.",
"", "",
@ -931,12 +927,13 @@
"description":[ "description":[
"We can use a certain mathematical expression to get a random number between two numbers.", "We can use a certain mathematical expression to get a random number between two numbers.",
"<code>Math.floor(Math.random() * (max - min + 1)) + min</code>", "<code>Math.floor(Math.random() * (max - min + 1)) + min</code>",
"By using this we can control the output of a random number." "By using this, we can control the output of a random number."
], ],
"tests":[ "tests":[
"assert(myFunction() >= min, 'The random number that\\'s generated by myFunction should be greater than or equal to the minimum number');", "assert(myFunction() >= min, 'message: The random number generated by <code>myFunction</code> should be greater than or equal to the minimum number.');",
"assert(myFunction() <= max, 'The random number that\\'s generated by myFunction should be less than or equal to the maximum number');", "assert(myFunction() <= max, 'message: The random number generated by <code>myFunction</code> should be less than or equal to the maximum number.');",
"assert((function(){if(editor.getValue().match(/max/g).length >= 2 && editor.getValue().match(/min/g).length >= 2 && editor.getValue().match(/Math.floor/g) && editor.getValue().match(/Math.random/g)){return true;}else{return false;}})(), 'You should be using the function given in the description to calculate the random in number in a range');" "assert(myFunction() % 1 === 0 , 'message: The random number generated by <code>myFunction</code> should be an integer, not a decimal.');",
"assert((function(){if(editor.getValue().match(/max/g).length >= 2 && editor.getValue().match(/min/g).length >= 2 && editor.getValue().match(/Math.floor/g) && editor.getValue().match(/Math.random/g)){return true;}else{return false;}})(), 'message: You should be using the function given in the description to calculate the random in number in a range.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var min = 0;", "var min = 0;",
@ -957,39 +954,40 @@
}, },
{ {
"id":"cf1111c1c12feddfaeb3bdef", "id":"cf1111c1c12feddfaeb3bdef",
"title": "Use Conditional Logic with If-Else Statements", "title": "Use Conditional Logic with If and Else Statements",
"difficulty":"9.983", "difficulty":"9.983",
"description":[ "description":[
"We can use if statements in JavaScript to only execute code if a certain condition is met.", "We can use <code>if</code> statements in JavaScript to only execute code if a certain condition is met.",
"if statements require some sort of boolean condition to evaluate.", "<code>if</code> statements require some sort of boolean condition to evaluate.",
"Example:", "For example:",
"<code> if (1 === 2) {</code>", "<code> if (1 === 2) {</code>",
"<code>&thinsp;&thinsp;return true;</code>", "<code>&thinsp;&thinsp;return true;</code>",
"<code>}</code>", "<code>} else {</code>",
"<code>else {</code>",
"<code>&thinsp;&thinsp;return false;</code>", "<code>&thinsp;&thinsp;return false;</code>",
"<code>}</code>", "<code>}</code>",
"Let's use <code>if</code> and <code>else</code> statements to make a coin-flip game.", "Let's use <code>if</code> and <code>else</code> statements to make a coin-flip game.",
"Create an <code>if-else statement</code> to return <code>heads</code> if the flip var is zero, or else return <code>tails</code> if it's not." "Create <code>if</code> and <code>else</code> statements to return the string <code>\"heads\"</code> if the flip variable is zero, or else return the string <code>\"tails\"</code> if the flip variable is not zero."
], ],
"tests":[ "tests":[
"assert((function(){if(myFunction() === \"heads\" || myFunction() === \"tails\"){return true;}else{return false;}})(), 'myFunction should either return heads or tails');", "assert((function(){var result = myFunction();if(result === 'heads' || result === 'tails'){return true;} else {return false;}})(), 'message: <code>myFunction</code> should either return <code>heads</code> or <code>tails</code>.');",
"assert(editor.getValue().match(/if/g).length >= 3, 'You should have created a new if statement');", "assert((function(){var result = myFunction();if(result === 'heads' && flip === 0 || result === 'tails' && flip !== 0){return true;} else {return false;}})(), 'message: <code>myFunction</code> should return <code>heads</code> when flip equals 0 and <code>tails</code> when flip equals 1.');",
"assert(editor.getValue().match(/else/g).length >= 2, 'You should have created a new else statement');" "assert(editor.getValue().match(/if/g).length >= 4, 'message: You should have created a new if statement.');",
"assert(editor.getValue().match(/else/g).length >= 2, 'message: You should have created a new else statement.');"
], ],
"challengeSeed":[ "challengeSeed":[
"function myFunction(){",
"var flip = Math.floor(Math.random() * (1 - 0 + 1)) + 0;", "var flip = Math.floor(Math.random() * (1 - 0 + 1)) + 0;",
"function myFunction(){",
" // Create an if-else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".", " // Create an if-else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".",
"", "",
" // Only change code below this line.", " // Only change code below this line.",
"", "",
"", "",
"}",
"", "",
" // Only change code above this line.", " // Only change code above this line.",
"}",
"",
"// We use this function to show you the value of your variable in your output box.", "// We use this function to show you the value of your variable in your output box.",
"(function(){return myFunction();})();" "var result = myFunction();if(typeof(flip) !== \"undefined\" && typeof(flip) === \"number\" && typeof(result) !== \"undefined\" && typeof(result) === \"string\"){(function(y,z){return 'flip = ' + y.toString() + ', text = ' + z;})(flip, result);}"
], ],
"type": "waypoint", "type": "waypoint",
"challengeType": 1 "challengeType": 1
@ -1005,17 +1003,17 @@
"<code>the</code> is the pattern we want to match.", "<code>the</code> is the pattern we want to match.",
"<code>g</code> means that we want to search the entire string for this pattern instead of just the first match.", "<code>g</code> means that we want to search the entire string for this pattern instead of just the first match.",
"<code>i</code> means that we want to ignore the case (uppercase or lowercase) when searching for the pattern.", "<code>i</code> means that we want to ignore the case (uppercase or lowercase) when searching for the pattern.",
"<code>Regular expressions</code> are written by surrounding the pattern with a <code>/</code> symbol.", "<code>Regular expressions</code> are written by surrounding the pattern with <code>/</code> symbols.",
"Let's try selecting all the occurrences of the word <code>and</code> in the string <code>George Boole and Alan Turing went to the shop and got some milk</code>. We can do this by replacing the <code>...</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>." "Let's try selecting all the occurrences of the word <code>and</code> in the string <code>Ada Lovelace and Charles Babbage designed the first computer and the software that would have run on it</code>. We can do this by replacing the <code>.</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>."
], ],
"tests":[ "tests":[
"assert(test==2, 'Your <code>regular expression</code> should find two occurrences of the word <code>and</code>');", "assert(test==2, 'message: Your <code>regular expression</code> should find two occurrences of the word <code>and</code>.');",
"assert(editor.getValue().match(/\\/and\\/gi/), 'You should have used <code>regular expressions</code> to find the word <code>and</code>');" "assert(editor.getValue().match(/\\/and\\/gi/), 'message: You should have used <code>regular expressions</code> to find the word <code>and</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var test = (function() {", "var test = (function() {",
" var testString = \"George Boole and Alan Turing went to the shop and got some milk\";", " var testString = \"Ada Lovelace and Charles Babbage designed the first computer and the software that would have run on it.\";",
" var expressionToGetMilk = /milk/gi;", " var expressionToGetSoftware = /software/gi;",
" // Only change code below this line.", " // Only change code below this line.",
"", "",
" var expression = /./gi;", " var expression = /./gi;",
@ -1035,12 +1033,13 @@
"description":[ "description":[
"We can use special selectors in <code>Regular Expressions</code> to select a particular type of value.", "We can use special selectors in <code>Regular Expressions</code> to select a particular type of value.",
"One such selector is the digit selector <code>\\d</code> which is used to grab the numbers in a string.", "One such selector is the digit selector <code>\\d</code> which is used to grab the numbers in a string.",
"It is used like this: <code>/\\d+/g</code>.", "It is used like this: <code>/\\d/g</code>.",
"Use the <code>\\d</code> selector to select the number of numbers in the string." "For numbers this is often written as <code>/\\d+/g</code>, where the <code>+</code> following the digit selector allows this regular expression to match multi-digit numbers.",
"Use the <code>\\d</code> selector to select the number of numbers in the string, allowing for the possibility of multi-digit numbers."
], ],
"tests":[ "tests":[
"assert(test === 2, 'Your RegEx should have found two numbers in the testString');", "assert(test === 2, 'message: Your RegEx should have found two numbers in the <code>testString</code>.');",
"assert(editor.getValue().match(/\\/\\\\d\\+\\//gi), 'You should be using the following expression /\\\\d+/gi to find the numbers in the testString');" "assert(editor.getValue().match(/\\/\\\\d\\+\\//gi), 'message: You should be using the following expression <code>/\\\\d+/gi</code> to find the numbers in the <code>testString</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var test = (function() {", "var test = (function() {",
@ -1069,8 +1068,8 @@
"Select all the spaces in the sentence string." "Select all the spaces in the sentence string."
], ],
"tests":[ "tests":[
"assert(test === 7, 'Your RegEx should have found seven spaces in the <code>testString</code>.');", "assert(test === 7, 'message: Your RegEx should have found seven spaces in the <code>testString</code>.');",
"assert(editor.getValue().match(/\\/\\\\s\\+\\//gi), 'You should be using the following expression /\\\\s+/gi to find the spaces in the <code>testString</code>.');" "assert(editor.getValue().match(/\\/\\\\s\\+\\//gi), 'message: You should be using the following expression <code>/\\\\s+/gi</code> to find the spaces in the <code>testString</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var test = (function(){", "var test = (function(){",
@ -1093,12 +1092,12 @@
"title": "Invert Regular Expression Matches with JavaScript", "title": "Invert Regular Expression Matches with JavaScript",
"difficulty":"9.987", "difficulty":"9.987",
"description":[ "description":[
"Use <code>/\\S/gi;</code> to match everything that isn't a space in the string.", "Use <code>/\\S/gi</code> to match everything that isn't a space in the string.",
"You can invert any match by using the uppercase version of the selector <code>\\s</code> versus <code>\\S</code> for example." "You can invert any match by using the uppercase version of the selector <code>\\s</code> versus <code>\\S</code> for example."
], ],
"tests":[ "tests":[
"assert(test === 49, 'Your RegEx should have found forty nine non-space characters in the <code>testString</code>.');", "assert(test === 49, 'message: Your RegEx should have found forty nine non-space characters in the <code>testString</code>.');",
"assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'You should be using the following expression <code>/\\\\S/gi</code> to find non-space characters in the <code>testString</code>.');" "assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'message: You should be using the following expression <code>/\\\\S/gi</code> to find non-space characters in the <code>testString</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var test = (function(){", "var test = (function(){",
@ -1124,14 +1123,14 @@
"We are now going to try and combine some of the stuff we've just learned and create the logic for a slot machine game.", "We are now going to try and combine some of the stuff we've just learned and create the logic for a slot machine game.",
"For this we will need to generate three random numbers between <code>1</code> and <code>3</code> to represent the possible values of each individual slot.", "For this we will need to generate three random numbers between <code>1</code> and <code>3</code> to represent the possible values of each individual slot.",
"Store the three random numbers in <code>slotOne</code>, <code>slotTwo</code> and <code>slotThree</code>.", "Store the three random numbers in <code>slotOne</code>, <code>slotTwo</code> and <code>slotThree</code>.",
"Generate the random numbers by using the system we used earlier:", "Generate the random numbers by using the system we used earlier (an explanation of the formula can be found <a href=\"https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Waypoint-Generate-Random-Whole-Numbers-within-a-Range#explanation\">here</a>):",
"<code>Math.floor(Math.random() * (3 - 1 + 1)) + 1;</code>" "<code>Math.floor(Math.random() * (3 - 1 + 1)) + 1;</code>"
], ],
"tests":[ "tests":[
"assert(typeof(runSlots($(\".slot\"))[0]) === \"number\", '<code>slotOne</code> should be a random number.')", "assert(typeof(runSlots($(\".slot\"))[0]) === \"number\", 'message: <code>slotOne</code> should be a random number.')",
"assert(typeof(runSlots($(\".slot\"))[1]) === \"number\", '<code>slotTwo</code> should be a random number.')", "assert(typeof(runSlots($(\".slot\"))[1]) === \"number\", 'message: <code>slotTwo</code> should be a random number.')",
"assert(typeof(runSlots($(\".slot\"))[2]) === \"number\", '<code>slotThree</code> should be a random number.')", "assert(typeof(runSlots($(\".slot\"))[2]) === \"number\", 'message: <code>slotThree</code> should be a random number.')",
"assert((function(){if(editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?3\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi) !== null){return editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?3\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi).length >= 3;}else{return false;}})(), 'You should have used <code>Math.floor(Math.random() * (3 - 1 + 1)) + 1;</code> three times to generate your random numbers.')" "assert((function(){if(editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?3\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi) !== null){return editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?3\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi).length >= 3;}else{return false;}})(), 'message: You should have used <code>Math.floor(Math.random() * (3 - 1 + 1)) + 1;</code> three times to generate your random numbers.')"
], ],
"challengeSeed":[ "challengeSeed":[
"fccss", "fccss",
@ -1285,7 +1284,7 @@
"<code>}</code>" "<code>}</code>"
], ],
"tests":[ "tests":[
"assert((function(){var data = runSlots();if(data === null){return true}else{if(data[0] === data[1] && data[1] === data[2]){return true;}else{return false;}}})(), 'If all three of our random numbers are the same we should return that number. Otherwise we should return null.')" "assert((function(){var data = runSlots();if(data === null){return true}else{if(data[0] === data[1] && data[1] === data[2]){return true;}else{return false;}}})(), 'If all three of our random numbers are the same we should return that number. Otherwise we should return <code>null</code>.')"
], ],
"challengeSeed":[ "challengeSeed":[
"fccss", "fccss",
@ -1443,8 +1442,8 @@
"Use the above selector to display each number in its corresponding slot." "Use the above selector to display each number in its corresponding slot."
], ],
"tests":[ "tests":[
"assert((function(){runSlots();if($($(\".slot\")[0]).html().replace(/\\s/gi, \"\") !== \"\" && $($(\".slot\")[1]).html().replace(/\\s/gi, \"\") !== \"\" && $($(\".slot\")[2]).html().replace(/\\s/gi, \"\") !== \"\"){return true;}else{return false;}})(), 'You should be displaying the result of the slot numbers in the corresponding slots')", "assert((function(){runSlots();if($($(\".slot\")[0]).html().replace(/\\s/gi, \"\") !== \"\" && $($(\".slot\")[1]).html().replace(/\\s/gi, \"\") !== \"\" && $($(\".slot\")[2]).html().replace(/\\s/gi, \"\") !== \"\"){return true;}else{return false;}})(), 'You should be displaying the result of the slot numbers in the corresponding slots.')",
"assert((function(){if(editor.match( /\\$\\(\\$\\(\\\"\\.slot\\\"\\)\\[\\d\\]\\)/gi )){if(editor.match( /\\$\\(\\$\\(\\\"\\.slot\\\"\\)\\[\\d\\]\\)/gi ).length >= 3 && editor.match( /\\.html\\(slotOne\\)/gi ) && editor.match( /\\.html\\(slotTwo\\)/gi ) && editor.match( /\\.html\\(slotThree\\)/gi )){return true;}else{return false;}}else{return false;}})(), 'You should have used the the selector given in the description to select each slot and assign it the value of slotOne&#44; slotTwo and slotThree respectively')" "assert((editor.match( /\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[\\d\\]\\s*?\\)/gi) && editor.match( /\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[\\d\\]\\s*?\\)/gi ).length >= 3 && editor.match( /\\.html\\(slotOne\\)/gi ) && editor.match( /\\.html\\(slotTwo\\)/gi ) && editor.match( /\\.html\\(slotThree\\)/gi )), 'You should have used the the selector given in the description to select each slot and assign it the value of <code>slotOne</code>&#44; <code>slotTwo</code> and <code>slotThree</code> respectively.')"
], ],
"challengeSeed":[ "challengeSeed":[
"fccss", "fccss",
@ -1598,7 +1597,7 @@
}, },
{ {
"id":"cf1111c1c11feddfaeb1bdff", "id":"cf1111c1c11feddfaeb1bdff",
"title": "Give your JavaScript Slot Machine some stylish images", "title": "Give your JavaScript Slot Machine some Stylish Images",
"difficulty":"9.9901", "difficulty":"9.9901",
"description":[ "description":[
"Now let's add some images to our slots.", "Now let's add some images to our slots.",
@ -1608,10 +1607,13 @@
"Set up all three slots like this, then click the \"Go\" button to play the slot machine." "Set up all three slots like this, then click the \"Go\" button to play the slot machine."
], ],
"tests":[ "tests":[
"assert((editor.match(/\\$\\(\\$\\(\\'\\.slot\\'\\)\\[\\d\\]\\)\\.html\\(\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\);/gi) && editor.match(/\\$\\(\\$\\(\\'\\.slot\\'\\)\\[\\d\\]\\)\\.html\\(\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\);/gi).length >= 3) || (editor.match(/\\$\\(\\$\\(\\\"\\.slot\\\"\\)\\[\\d\\]\\)\\.html\\(\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\);/gi) && editor.match(/\\$\\(\\$\\(\\\"\\.slot\\\"\\)\\[\\d\\]\\)\\.html\\(\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\);/gi).length >= 3), 'Use the provided code three times. One for each slot')", "assert((editor.match(/\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[\\d\\]\\s*?\\)\\.html\\(\\s*?\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\s*?\\);/gi) && editor.match(/\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[\\d\\]\\s*?\\)\\.html\\(\\s*?\\'\\<img\\s?src\\s?=\\s?\"\\'\\s?\\+\\s?images\\[\\w+\\-1\\]\\s?\\+\\s?\\'\"\\>\\'\\s*?\\);/gi).length >= 3), 'Use the provided code three times. One for each slot.')",
"assert(editor.match(/slotOne/gi) && editor.match(/slotOne/gi).length >= 7, 'You should have used the slotOne value at least once')", "assert(editor.match(/\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[0\\]\\s*?\\)/gi), 'You should have used <code>$&#40;&#39;.slot&#39;&#41;[0]</code> at least once.')",
"assert(editor.match(/slotTwo/gi) && editor.match(/slotTwo/gi).length >= 8, 'You should have used the slotTwo value at least once')", "assert(editor.match(/\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[1\\]\\s*?\\)/gi), 'You should have used <code>$&#40;&#39;.slot&#39;&#41;[1]</code> at least once.')",
"assert(editor.match(/slotThree/gi) && editor.match(/slotThree/gi).length >= 7, 'You should have used the slotThree value at least once')" "assert(editor.match(/\\$\\s*?\\(\\s*?\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.slot\\s*?(?:'|\")\\s*?\\)\\[2\\]\\s*?\\)/gi), 'You should have used <code>$&#40;&#39;.slot&#39;&#41;[2]</code> at least once.')",
"assert(editor.match(/slotOne/gi) && editor.match(/slotOne/gi).length >= 7, 'You should have used the <code>slotOne</code> value at least once.')",
"assert(editor.match(/slotTwo/gi) && editor.match(/slotTwo/gi).length >= 8, 'You should have used the <code>slotTwo</code> value at least once.')",
"assert(editor.match(/slotThree/gi) && editor.match(/slotThree/gi).length >= 7, 'You should have used the <code>slotThree</code> value at least once.')"
], ],
"challengeSeed":[ "challengeSeed":[
"fccss", "fccss",

View File

@ -1,6 +1,6 @@
{ {
"name": "Basic Front End Development Projects", "name": "Basic Front End Development Projects",
"order": 0.008, "order": 8,
"challenges": [ "challenges": [
{ {
"id": "bd7158d8c442eddfbeb5bd1f", "id": "bd7158d8c442eddfbeb5bd1f",
@ -16,7 +16,8 @@
"Drag the windows around and press the buttons in the lower-right hand corner to change the orientation to suit your preference.", "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 under the \"Add External CSS\" section, use the \"Quick-add\" select box to select Bootstrap. Then click \"Save & Close\".", "Click the gear next to CSS. Then under the \"Add External CSS\" section, use the \"Quick-add\" select box to select Bootstrap. Then click \"Save & Close\".",
"Verify that bootstrap is active by adding the following code to your HTML: <code>&lt;h1 class='text-primary'&gt;Hello CodePen!&lt;/h1&gt;</code>. The text's color should be Bootstrap blue.", "Verify that bootstrap is active by adding the following code to your HTML: <code>&lt;h1 class='text-primary'&gt;Hello CodePen!&lt;/h1&gt;</code>. The text's color should be Bootstrap blue.",
"Click the gear next to JavaScript. Click the \"Quick-add\" select box and choose jQuery (not jQuery UI). Then click \"Save & Close\".", "Click the gear next to JavaScript. Click the \"Quick-add\" select box and choose jQuery (not jQuery UI).",
"Click the \"Quick-add\" select box again and choose Bootstrap. Then click \"Save & Close\".",
"Now add the following code to your JavaScript: <code>$(document).ready(function() { $('.text-primary').text('Hi CodePen!') });</code>. Click the \"Save\" button at the top. Your \"Hello CodePen!\" should change to \"Hi CodePen!\". This means that jQuery is working.", "Now add the following code to your JavaScript: <code>$(document).ready(function() { $('.text-primary').text('Hi CodePen!') });</code>. Click the \"Save\" button at the top. Your \"Hello CodePen!\" should change to \"Hi CodePen!\". This means that jQuery is working.",
"You can use this CodePen that you've just created as a starting point for your Ziplines. Just click the \"fork\" button at the top of your CodePen and it will create a duplicate CodePen.", "You can use this CodePen that you've just created as a starting point for your Ziplines. Just click the \"fork\" button at the top of your CodePen and it will create a duplicate CodePen.",
"Now you're ready for your first Zipline. Click the \"I've completed this challenge\" button." "Now you're ready for your first Zipline. Click the \"I've completed this challenge\" button."
@ -28,8 +29,22 @@
"descriptionCn": [], "descriptionCn": [],
"nameFr": "", "nameFr": "",
"descriptionFr": [], "descriptionFr": [],
"nameRu": "", "nameRu": "Приготовьтесь к Zipline'ам",
"descriptionRu": [], "descriptionRu": [
"Теперь вы готовы приступить к Zipline'ам. Это задания по фронт-энд разработке, в них вы примените ранее изученные HTML, CSS, jQuery и JavaScript и создадите статические (не использующие базу данных) приложения.",
"Ни в коем случае не унывайте! Воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>, если что-то не получается.",
"Задания мы будем выполнять используя CodePen - популярный инструмент для создания и обмена статическими веб приложениями.",
"Перейдите по ссылке <a href='http://codepen.io' target='_blank'>http://codepen.io</a> и создайте аккаунт.",
"Нажмите на ваш аватар в правом верхнем углу, а затем в открывшемся меню на кнопку \"New pen\".",
"Выберите удобное расположение окон с помощью кнопок в правом нижнем углу, отрегулируйте их ширину.",
"Нажмите на звездочку рядом с CSS. Затем в секции \"Add External CSS\" выберите \"Quick-add\" и добавьте Bootstrap. Нажмите \"Save & Close\".",
"Проверьте, что Bootstrap подключен добавив следующий HTML код: <code>&lt;h1 class='text-primary'&gt;Hello CodePen!&lt;/h1&gt;</code>. Цвет текста должен быть синим.",
"Нажмите на звездочку рядом с JavaScript. Нажмите \"Quick-add\" и выберите jQuery (не jQuery UI). Нажмите \"Save & Close\".",
"Снова нажмите на поле \"Quick-add\", выберите Bootstrap и затем нажмите \"Save & Close\".",
"Теперь добавьте следующий код в окошко JavaScript: <code>$(document).ready(function() { $('.text-primary').text('Hi CodePen!') });</code>. Нажмите на кнопку \"Save\" расположенную наверху. Текст \"Hello CodePen!\" должен измениться на \"Hi CodePen!\". Это значит что jQuery работает.",
"CodePen, который мы создали, можно использовать в качестве отправной точки для ваших Zipline'ов. Кликните кнопку \"fork\", чтобы создать копию текущего CodePen'a.",
"Все готово для первого Zipline'а. Жмите кнопку \"I've completed this challenge\"."
],
"nameEs": "", "nameEs": "",
"descriptionEs": [], "descriptionEs": [],
"namePt": "", "namePt": "",
@ -56,7 +71,7 @@
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code>&lt;a target='_blank'&gt;</a></code>.", "Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code>&lt;a target='_blank'&gt;</a></code>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -65,8 +80,25 @@
"descriptionCn": [], "descriptionCn": [],
"nameFr": "", "nameFr": "",
"descriptionFr": [], "descriptionFr": [],
"nameRu": "", "nameRu": "Создайте сайт-портфолио",
"descriptionRu": [], "descriptionRu": [
"<span class='text-info'>Задание:</span> Создайте <a href='http://codepen.io' target='_blank'>CodePen.io</a> который успешно копирует вот этот: <a href='http://codepen.io/ThiagoFerreir4/full/eNMxEp' target='_blank'>http://codepen.io/ThiagoFerreir4/full/eNMxEp</a>.",
"<span class='text-info'>Правило #1:</span> Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.",
"<span class='text-info'>Правило #2:</span> Можете использовать любые библиотеки или API, которые потребуются.",
"<span class='text-info'>Правило #3:</span> Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.",
"<span class='text-info'>Подсказка:</span> Если вы не хотите создавать портфолио с нуля, можете взять за основу этот простой Bootstrap шаблон: <a href='http://codepen.io/FreeCodeCamp/pen/mJNqQj/' target='_blank'>http://codepen.io/FreeCodeCamp/pen/mJNqQj</a>.",
"Реализуйте следующие <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>пользовательские истории</a>, сделайте также бонусные по желанию:",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу получить доступ ко всей информации на странице просто прокрутив ее сверху вниз.",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу нажать на различные кнопки и перейти к социальным страницам владельца портфолио.",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу увидеть эскизы проектов, которые были созданы владельцем портфолио (используйте временную картинку если у вас пока нету собственных веб-страниц).",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу перемещаться к различным частям страницы нажимая на соответствующие навигационные кнопки.",
"Не переживайте если вам пока нечего показать в портфолио - вы создадите несколько веб приложений в следующих заданиях, а затем вернетесь и обновите портфолио.",
"В сети существует много шаблонов для портфолио, но в этом задании вам необходимо создать собственную уникальную страницу. Использование Bootstrap сделает этот процесс намного проще.",
"Обратите внимание, что CodePen.io переопределяет функцию Window.open(), поэтому, если вы хотите открывать окна используя jQuery, необходимо будет адресовать невидимые якорные элементы, такие как этот: <code>&lt;a target='_blank'&rt;</a></code>.",
"Если что-то не получается, воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>.",
"Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.",
"Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"nameEs": "", "nameEs": "",
"descriptionEs": [], "descriptionEs": [],
"namePt": "", "namePt": "",
@ -88,7 +120,7 @@
"Note that you can either put your quotes into an array and show them at random, or use an API to get quotes, such as <a href='http://forismatic.com/en/api/'>http://forismatic.com/en/api/</a>.", "Note that you can either put your quotes into an array and show them at random, or use an API to get quotes, such as <a href='http://forismatic.com/en/api/'>http://forismatic.com/en/api/</a>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -97,41 +129,20 @@
"descriptionCn": [], "descriptionCn": [],
"nameFr": "", "nameFr": "",
"descriptionFr": [], "descriptionFr": [],
"nameRu": "", "nameRu": "Создайте генератор случайных цитат",
"descriptionRu": [], "descriptionRu": [
"nameEs": "", "<span class='text-info'>Задание:</span> Создайте <a href='http://codepen.io' target='_blank'>CodePen.io</a> который успешно копирует вот этот: <a href='http://codepen.io/AdventureBear/full/vEoVMw' target='_blank'>http://codepen.io/AdventureBear/full/vEoVMw</a>.",
"descriptionEs": [], "<span class='text-info'>Правило #1:</span> Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.",
"namePt": "", "<span class='text-info'>Правило #2:</span> Можете использовать любые библиотеки или API, которые потребуются.",
"descriptionPt": [] "<span class='text-info'>Правило #3:</span> Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.",
}, "Реализуйте следующие <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>пользовательские истории</a>, сделайте также бонусные по желанию:",
{ "<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу нажать на кнопку и получить случайную цитату.",
"id": "bd7158d8c442eddfaeb5bd10", "<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу нажать на кнопку и опубликовать цитату в Twitter'e.",
"title": "Show the Local Weather", "Цитаты можно добавить в массив и случайным образом выводить одну из них, либо можно воспользоваться соответствующим API, например <a href='http://forismatic.com/en/api/'>http://forismatic.com/en/api/</a>.",
"difficulty": 1.03, "Если что-то не получается, воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>.",
"challengeSeed": ["126415127"], "Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.",
"description": [ "Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/AdventureBear/full/yNBJRj' target='_blank'>http://codepen.io/AdventureBear/full/yNBJRj</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can see the weather in my current location.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can see an icon depending on the temperature..",
"<span class='text-info'>Bonus User Story:</span> As a user, I see a different background image depending on the temperature (e.g. snowy mountain, hot desert).",
"<span class='text-info'>Bonus User Story:</span> As a user, I can push a button to toggle between Fahrenheit and Celsius.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline",
"challengeType": 3,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "", "nameEs": "",
"descriptionEs": [], "descriptionEs": [],
"namePt": "", "namePt": "",
@ -140,7 +151,6 @@
{ {
"id": "bd7158d8c442eddfaeb5bd0f", "id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock", "title": "Build a Pomodoro Clock",
"difficulty": 1.04,
"challengeSeed": ["126411567"], "challengeSeed": ["126411567"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/RPbGxZ/' target='_blank'>http://codepen.io/GeoffStorbeck/full/RPbGxZ/</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/RPbGxZ/' target='_blank'>http://codepen.io/GeoffStorbeck/full/RPbGxZ/</a>.",
@ -153,7 +163,7 @@
"<span class='text-info'>Bonus User Story:</span> As a user, I can customize the length of each pomodoro.", "<span class='text-info'>Bonus User Story:</span> As a user, I can customize the length of each pomodoro.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -162,35 +172,41 @@
"descriptionCn": [], "descriptionCn": [],
"nameFr": "", "nameFr": "",
"descriptionFr": [], "descriptionFr": [],
"nameRu": "", "nameRu": "Создайте таймер Pomodoro",
"descriptionRu": [], "descriptionRu": [
"<span class='text-info'>Задание:</span> Создайте <a href='http://codepen.io' target='_blank'>CodePen.io</a> который успешно копирует вот этот: <a href='http://codepen.io/GeoffStorbeck/full/RPbGxZ/' target='_blank'>http://codepen.io/GeoffStorbeck/full/RPbGxZ/</a>.",
"<span class='text-info'>Правило #1:</span> Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.",
"<span class='text-info'>Правило #2:</span> Можете использовать любые библиотеки или API, которые потребуются.",
"<span class='text-info'>Правило #3:</span> Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.",
"Реализуйте следующие <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>пользовательские истории</a>, сделайте также бонусные по желанию:",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу запустить 25 минутную 'помидорку', по истечении которой таймер выключится.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу сбросить таймер для установки следующей 'помидорки'.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу выбирать длительность 'помидорки'.",
"Если что-то не получается, воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>.",
"Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.",
"Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"nameEs": "", "nameEs": "",
"descriptionEs": [], "descriptionEs": [],
"namePt": "", "namePt": "",
"descriptionPt": [] "descriptionPt": []
}, },
{ {
"id": "bd7158d8c442eddfaeb5bd1f", "id": "bd7158d8c442eddfaeb5bd17",
"title": "Use the Twitch.tv JSON API", "title": "Build a JavaScript Calculator",
"difficulty": 1.05, "challengeSeed": ["126411565"],
"challengeSeed": ["126411564"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/GJKRxZ' target='_blank'>http://codepen.io/GeoffStorbeck/full/GJKRxZ</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/zxgaqw' target='_blank'>http://codepen.io/GeoffStorbeck/full/zxgaqw</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.", "<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.", "<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.", "<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:", "Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can see whether Free Code Camp is currently streaming on Twitch.tv.", "<span class='text-info'>User Story:</span> As a user, I can add, subtract, multiply and divide two numbers.",
"<span class='text-info'>User Story:</span> As a user, I can click the status output and be sent directly to the Free Code Camp's Twitch.tv channel.", "<span class='text-info'>Bonus User Story:</span> I can clear the input field with a clear button.",
"<span class='text-info'>User Story:</span> As a user, if Free Code Camp is streaming, I can see additional details about what they are streaming.", "<span class='text-info'>Bonus User Story:</span> I can keep chaining mathematical operations together until I hit the clear button, and the calculator will tell me the correct output.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can search through the streams listed.",
"<span class='text-info'>Bonus User Story:</span> As a user, I will see a placeholder notification if a streamer has closed their Twitch account. You can verify this works by adding brunofin and comster404 to your array of Twitch streamers.",
"<span class='text-info'>Hint:</span> Here's an example call to Twitch.tv's JSON API: <code>https://api.twitch.tv/kraken/streams/freecodecamp</code>.",
"<span class='text-info'>Hint:</span> The relevant documentation about this API call is here: <a href='https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel' target='_blank'>https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel</a>.",
"<span class='text-info'>Hint:</span> Here's an array of the Twitch.tv usernames of people who regularly stream coding: <code>[\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]</code>",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,

View File

@ -1,11 +1,10 @@
{ {
"name": "Responsive Design with Bootstrap", "name": "Responsive Design with Bootstrap",
"order": 0.003, "order": 3,
"challenges": [ "challenges": [
{ {
"id": "bad87fee1348bd9acde08712", "id": "bad87fee1348bd9acde08712",
"title": "Use Responsive Design with Bootstrap Fluid Containers", "title": "Use Responsive Design with Bootstrap Fluid Containers",
"difficulty": 2.01,
"description": [ "description": [
"Now let's go back to our Cat Photo App. This time, we'll style it using the popular Bootstrap responsive CSS framework.", "Now let's go back to our Cat Photo App. This time, we'll style it using the popular Bootstrap responsive CSS framework.",
"Bootstrap will figure out how wide your screen is and respond by resizing your HTML elements - hence the name <code>Responsive Design</code>.", "Bootstrap will figure out how wide your screen is and respond by resizing your HTML elements - hence the name <code>Responsive Design</code>.",
@ -89,7 +88,6 @@
{ {
"id": "bad87fee1348bd9acde08812", "id": "bad87fee1348bd9acde08812",
"title": "Make Images Mobile Responsive", "title": "Make Images Mobile Responsive",
"difficulty": 2.02,
"description": [ "description": [
"First, add a new image below the existing one. Set it's <code>src</code> attribute to <code>http://bit.ly/fcc-running-cats</code>.", "First, add a new image below the existing one. Set it's <code>src</code> attribute to <code>http://bit.ly/fcc-running-cats</code>.",
"It would be great if this image could be exactly the width of our phone's screen.", "It would be great if this image could be exactly the width of our phone's screen.",
@ -174,7 +172,6 @@
{ {
"id": "bad87fee1348bd8acde08812", "id": "bad87fee1348bd8acde08812",
"title": "Center Text with Bootstrap", "title": "Center Text with Bootstrap",
"difficulty": 2.03,
"description": [ "description": [
"Now that we're using Bootstrap, we can center our heading element to make it look better. All we need to do is add the class <code>text-center</code> to our <code>h2</code> element.", "Now that we're using Bootstrap, we can center our heading element to make it look better. All we need to do is add the class <code>text-center</code> to our <code>h2</code> element.",
"Remember that you can add several classes to the same element by separating each of them with a space, like this: <code>&#60h2 class=\"red-text text-center\"&#62your text&#60/h2&#62</code>." "Remember that you can add several classes to the same element by separating each of them with a space, like this: <code>&#60h2 class=\"red-text text-center\"&#62your text&#60/h2&#62</code>."
@ -257,7 +254,6 @@
{ {
"id": "bad87fee1348cd8acdf08812", "id": "bad87fee1348cd8acdf08812",
"title": "Create a Bootstrap Button", "title": "Create a Bootstrap Button",
"difficulty": 2.04,
"description": [ "description": [
"Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.", "Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.",
"Create a new <code>button</code> element below your large kitten photo. Give it the class <code>btn</code> and the text of \"Like\"." "Create a new <code>button</code> element below your large kitten photo. Give it the class <code>btn</code> and the text of \"Like\"."
@ -343,11 +339,10 @@
{ {
"id": "bad87fee1348cd8acef08812", "id": "bad87fee1348cd8acef08812",
"title": "Create a Block Element Bootstrap Button", "title": "Create a Block Element Bootstrap Button",
"difficulty": 2.05,
"description": [ "description": [
"Normally, your <code>button</code> elements are only as wide as the text that they contain. By making them block elements, your button will stretch to fill your page's entire horizontal space.", "Normally, your <code>button</code> elements are only as wide as the text that they contain. By making them block elements, your button will stretch to fill your page's entire horizontal space.",
"This image illustrates the difference between <code>inline</code> elements and <code>block-level</code> elements:", "This image illustrates the difference between <code>inline</code> elements and <code>block-level</code> elements:",
"<img class=\"img-responsive\" src=\"http://i.imgur.com/O32cDWE.png\" alt=\"An \"inline\" button is as small as the text it contains. In this image, it's centered. Below it is a \"block-level\" button, which stretches to fill the entire horizontal space.'>", "<a href=\"http://i.imgur.com/O32cDWE.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" src=\"http://i.imgur.com/O32cDWE.png\" title=\"Click to enlarge\" alt=\"An \"inline\" button is as small as the text it contains. In this image, it's centered. Below it is a \"block-level\" button, which stretches to fill the entire horizontal space.'></a>",
"Note that these buttons still need the <code>btn</code> class.", "Note that these buttons still need the <code>btn</code> class.",
"Add Bootstrap's <code>btn-block</code> class to your Bootstrap button." "Add Bootstrap's <code>btn-block</code> class to your Bootstrap button."
], ],
@ -432,7 +427,6 @@
{ {
"id": "bad87fee1348cd8acef08811", "id": "bad87fee1348cd8acef08811",
"title": "Taste the Bootstrap Button Color Rainbow", "title": "Taste the Bootstrap Button Color Rainbow",
"difficulty": 2.06,
"description": [ "description": [
"The <code>btn-primary</code> class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.", "The <code>btn-primary</code> class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.",
"Add Bootstrap's <code>btn-primary</code> class to your button.", "Add Bootstrap's <code>btn-primary</code> class to your button.",
@ -519,7 +513,6 @@
{ {
"id": "bad87fee1348cd8acef08813", "id": "bad87fee1348cd8acef08813",
"title": "Call out Optional Actions with Button Info", "title": "Call out Optional Actions with Button Info",
"difficulty": 2.07,
"description": [ "description": [
"Bootstrap comes with several pre-defined colors for buttons. The <code>btn-info</code> class is used to call attention to optional actions that the user can take.", "Bootstrap comes with several pre-defined colors for buttons. The <code>btn-info</code> class is used to call attention to optional actions that the user can take.",
"Create a new block-level Bootstrap button below your \"Like\" button with the text \"Info\", and add Bootstrap's <code>btn-info</code> and <code>btn-block</code> classes to it.", "Create a new block-level Bootstrap button below your \"Like\" button with the text \"Info\", and add Bootstrap's <code>btn-info</code> and <code>btn-block</code> classes to it.",
@ -607,7 +600,6 @@
{ {
"id": "bad87fee1348ce8acef08814", "id": "bad87fee1348ce8acef08814",
"title": "Warn your Users of a Dangerous Action", "title": "Warn your Users of a Dangerous Action",
"difficulty": 2.08,
"description": [ "description": [
"Bootstrap comes with several pre-defined colors for buttons. The <code>btn-danger</code> class is the button color you'll use to notify users that the button performs a destructive action, such as deleting a cat photo.", "Bootstrap comes with several pre-defined colors for buttons. The <code>btn-danger</code> class is the button color you'll use to notify users that the button performs a destructive action, such as deleting a cat photo.",
"Create a button with the text \"Delete\" and give it the class <code>btn-danger</code>.", "Create a button with the text \"Delete\" and give it the class <code>btn-danger</code>.",
@ -696,11 +688,10 @@
{ {
"id": "bad88fee1348ce8acef08815", "id": "bad88fee1348ce8acef08815",
"title": "Use the Bootstrap Grid to Put Elements Side By Side", "title": "Use the Bootstrap Grid to Put Elements Side By Side",
"difficulty": 2.09,
"description": [ "description": [
"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 <code>div</code> 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 <code>div</code> element.",
"Here's a diagram of how Bootstrap's 12-column grid layout works:", "Here's a diagram of how Bootstrap's 12-column grid layout works:",
"<a href=\"http://i.imgur.com/FaYuui8.png\" target=\"_blank\"><img class=\"img-responsive\" src=\"http://i.imgur.com/FaYuui8.png\" alt=\"an image illustrating Bootstrap's grid system\"></a>", "<a href=\"http://i.imgur.com/FaYuui8.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" src=\"http://i.imgur.com/FaYuui8.png\" title=\"Click to enlarge\" alt=\"an image illustrating Bootstrap's grid system\"></a>",
"Note that in this illustration, the <code>col-md-*</code> class is being used. Here, <code>md</code> means medium, and <code>*</code> is a number specifying how many columns wide the element should be. In this case, the column width of an element on a medium-sized screen, such as a laptop, is being specified.", "Note that in this illustration, the <code>col-md-*</code> class is being used. Here, <code>md</code> means medium, and <code>*</code> is a number specifying how many columns wide the element should be. In this case, the column width of an element on a medium-sized screen, such as a laptop, is being specified.",
"In the Cat Photo App that we're building, we'll use <code>col-xs-*</code>, where <code>xs</code> means extra small (like an extra-small mobile phone screen), and <code>*</code> is the number of columns specifying how many columns wide the element should be.", "In the Cat Photo App that we're building, we'll use <code>col-xs-*</code>, where <code>xs</code> means extra small (like an extra-small mobile phone screen), and <code>*</code> is the number of columns specifying how many columns wide the element should be.",
"Put the <code>Like</code>, <code>Info</code> and <code>Delete</code> buttons side-by-side by nesting all three of them within one <code>&#60;div class=\"row\"&#62;</code> element, then each of them within a <code>&#60;div class=\"col-xs-4\"&#62;</code> element.", "Put the <code>Like</code>, <code>Info</code> and <code>Delete</code> buttons side-by-side by nesting all three of them within one <code>&#60;div class=\"row\"&#62;</code> element, then each of them within a <code>&#60;div class=\"col-xs-4\"&#62;</code> element.",
@ -790,7 +781,6 @@
{ {
"id": "bad87fee1347bd9aedf08845", "id": "bad87fee1347bd9aedf08845",
"title": "Ditch Custom CSS for Bootstrap", "title": "Ditch Custom CSS for Bootstrap",
"difficulty": 2.10,
"description": [ "description": [
"We can clean up our code and make our Cat Photo App look more conventional by using Bootstrap's built-in styles instead of the custom styles we created earlier.", "We can clean up our code and make our Cat Photo App look more conventional by using Bootstrap's built-in styles instead of the custom styles we created earlier.",
"Don't worry - there will be plenty of time to customize our CSS later.", "Don't worry - there will be plenty of time to customize our CSS later.",
@ -891,11 +881,10 @@
{ {
"id": "bad87fee1348bd9aedf08845", "id": "bad87fee1348bd9aedf08845",
"title": "Use Spans for Inline Elements", "title": "Use Spans for Inline Elements",
"difficulty": 2.105,
"description": [ "description": [
"You can use spans to create inline elements. Remember when we used the <code>btn-block</code> class to make the button fill the entire row?", "You can use spans to create inline elements. Remember when we used the <code>btn-block</code> class to make the button fill the entire row?",
"This image illustrates the difference between <code>inline</code> elements and <code>block-level</code> elements:", "This image illustrates the difference between <code>inline</code> elements and <code>block-level</code> elements:",
"<img class=\"img-responsive\" src=\"http://i.imgur.com/O32cDWE.png\" alt=\"An \"inline\" button is as small as the text it contains. In this image, it's centered. Below it is a \"block-level\" button, which stretches to fill the entire horizontal space.'>", "<a href=\"http://i.imgur.com/O32cDWE.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" src=\"http://i.imgur.com/O32cDWE.png\" title=\"Click to enlarge\" alt=\"An \"inline\" button is as small as the text it contains. In this image, it's centered. Below it is a \"block-level\" button, which stretches to fill the entire horizontal space.'></a>",
"By using the <code>span</code> element, you can put several elements together, and even style different parts of the same element differently.", "By using the <code>span</code> element, you can put several elements together, and even style different parts of the same element differently.",
"Nest the word \"love\" in your \"Things cats love\" element below within a <code>span</code> element. Then give that <code>span</code> the class <code>text-danger</code> to make the text red.", "Nest the word \"love\" in your \"Things cats love\" element below within a <code>span</code> element. Then give that <code>span</code> the class <code>text-danger</code> to make the text red.",
"Here's how you would do this with the \"Top 3 things cats hate\" element: <code>&#60;p&#62;Top 3 things cats &#60;span class = \"text-danger\"&#62;hate&#60;/span&#62;&#60;/p&#62;</code>" "Here's how you would do this with the \"Top 3 things cats hate\" element: <code>&#60;p&#62;Top 3 things cats &#60;span class = \"text-danger\"&#62;hate&#60;/span&#62;&#60;/p&#62;</code>"
@ -909,19 +898,11 @@
"challengeSeed": [ "challengeSeed": [
"<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">", "<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">",
"<style>", "<style>",
" .red-text {",
" color: red;",
" }",
"", "",
" h2 {", " h2 {",
" font-family: Lobster, Monospace;", " font-family: Lobster, Monospace;",
" }", " }",
"", "",
" p {",
" font-size: 16px;",
" font-family: Monospace;",
" }",
"",
" .thick-green-border {", " .thick-green-border {",
" border-color: green;", " border-color: green;",
" border-width: 10px;", " border-width: 10px;",
@ -929,17 +910,12 @@
" border-radius: 50%;", " border-radius: 50%;",
" }", " }",
"", "",
" .smaller-image {",
" width: 100px;",
" }",
"</style>", "</style>",
"", "",
"<div class=\"container-fluid\">", "<div class=\"container-fluid\">",
" <h2 class=\"red-text text-center\">CatPhotoApp</h2>", " <h2 class=\"text-primary text-center\">CatPhotoApp</h2>",
"", "",
" <p>Click here for <a href=\"#\">cat photos</a>.</p>", " <a href=\"#\"><img class=\"img-responsive thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\"></a>",
"",
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\"></a>",
"", "",
" <img src=\"http://bit.ly/fcc-running-cats\" class=\"img-responsive\">", " <img src=\"http://bit.ly/fcc-running-cats\" class=\"img-responsive\">",
" <div class=\"row\">", " <div class=\"row\">",
@ -992,12 +968,11 @@
{ {
"id": "bad87fee1348bd9aede08845", "id": "bad87fee1348bd9aede08845",
"title": "Create a Custom Heading", "title": "Create a Custom Heading",
"difficulty": 2.11,
"description": [ "description": [
"We will make a simple heading for our Cat Photo App by putting them in the same row.", "We will make a simple heading for our Cat Photo App by putting them in the same row.",
"Remember, 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 <code>div</code> element.", "Remember, 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 <code>div</code> element.",
"Here's a diagram of how Bootstrap's 12-column grid layout works:", "Here's a diagram of how Bootstrap's 12-column grid layout works:",
"<a href=\"http://i.imgur.com/FaYuui8.png\" target=\"_blank\"><img class=\"img-responsive\" src=\"http://i.imgur.com/FaYuui8.png\" alt=\"an image illustrating Bootstrap's grid system\"></a>", "<a href=\"http://i.imgur.com/FaYuui8.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" src=\"http://i.imgur.com/FaYuui8.png\" title=\"Click to enlarge\" alt=\"an image illustrating Bootstrap's grid system\"></a>",
"Note that in this illustration, the <code>col-md-*</code> class is being used. Here, <code>md</code> means medium, and <code>*</code> is a number specifying how many columns wide the element should be. In this case, the column width of an element on a medium-sized screen, such as a laptop, is being specified.", "Note that in this illustration, the <code>col-md-*</code> class is being used. Here, <code>md</code> means medium, and <code>*</code> is a number specifying how many columns wide the element should be. In this case, the column width of an element on a medium-sized screen, such as a laptop, is being specified.",
"In the Cat Photo App that we're building, we'll use <code>col-xs-*</code>, where <code>xs</code> means extra small (like an extra-small mobile phone screen), and <code>*</code> is the number of columns specifying how many columns wide the element should be.", "In the Cat Photo App that we're building, we'll use <code>col-xs-*</code>, where <code>xs</code> means extra small (like an extra-small mobile phone screen), and <code>*</code> is the number of columns specifying how many columns wide the element should be.",
"Nest your first image and your <code>h2</code> element within a single <code>&#60;div class=\"row\"&#62;</code> element. Nest your <code>h2</code> text within a <code>&#60;div class=\"col-xs-8\"&#62;</code> and your image in a <code>&#60;div class=\"col-xs-4\"&#62;</code> so that they are on the same line.", "Nest your first image and your <code>h2</code> element within a single <code>&#60;div class=\"row\"&#62;</code> element. Nest your <code>h2</code> text within a <code>&#60;div class=\"col-xs-8\"&#62;</code> and your image in a <code>&#60;div class=\"col-xs-4\"&#62;</code> so that they are on the same line.",
@ -1081,7 +1056,6 @@
{ {
"id": "bad87fee1348bd9aedd08845", "id": "bad87fee1348bd9aedd08845",
"title": "Add Font Awesome Icons to our Buttons", "title": "Add Font Awesome Icons to our Buttons",
"difficulty": 2.12,
"description": [ "description": [
"Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the <code>.svg</code> file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.", "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the <code>.svg</code> file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
"Use Font Awesome to add a <code>thumbs-up</code> icon to your like button by giving it a <code>i</code> element with the classes <code>fa</code> and <code>fa-thumbs-up</code>." "Use Font Awesome to add a <code>thumbs-up</code> icon to your like button by giving it a <code>i</code> element with the classes <code>fa</code> and <code>fa-thumbs-up</code>."
@ -1166,15 +1140,14 @@
{ {
"id": "bad87fee1348bd9aedc08845", "id": "bad87fee1348bd9aedc08845",
"title": "Add Font Awesome Icons to all of our Buttons", "title": "Add Font Awesome Icons to all of our Buttons",
"difficulty": 2.13,
"description": [ "description": [
"Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the <code>.svg</code> file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.", "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the <code>.svg</code> file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
"Use Font Awesome to add a <code>info-circle</code> icon to your info button and a <code>trash</code> icon to your delete button." "Use Font Awesome to add a <code>info-circle</code> icon to your info button and a <code>trash</code> icon to your delete button."
], ],
"tests": [ "tests": [
"assert($(\"i\").hasClass(\"fa fa-trash\"), 'You should add a <code>&#60;i class=\"fa fa-trash\"&#62;&#60;/i&#62;</code> within your delete button element.')", "assert($(\".btn-danger > i\").hasClass(\"fa fa-trash\"), 'You should add a <code>&#60;i class=\"fa fa-trash\"&#62;&#60;/i&#62;</code> within your delete button element.')",
"assert($(\"i\").hasClass(\"fa fa-info-circle\"), 'You should add a <code>&#60;i class=\"fa fa-info-circle\"&#62;&#60;/i&#62;</code> within your info button element.')", "assert($(\".btn-info > i\").hasClass(\"fa fa-info-circle\"), 'You should add a <code>&#60;i class=\"fa fa-info-circle\"&#62;&#60;/i&#62;</code> within your info button element.')",
"assert(editor.match(/<\\/i>/g) && editor.match(/<\\/i/g).length > 2, 'Make sure each of your <code>i</code> elements has a closing tag.')" "assert(editor.match(/<\\/i>/g) && editor.match(/<\\/i>/g).length > 2 && $(\".btn-primary > i\").hasClass(\"fa fa-thumbs-up\"), 'Make sure each of your <code>i</code> elements has a closing tag and <code>&#60;i class=\"fa fa-thumbs-up\"&#62;&#60;/i&#62;</code> is in your like button element.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">", "<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">",
@ -1251,7 +1224,6 @@
{ {
"id": "bad87fee1348bd9aedb08845", "id": "bad87fee1348bd9aedb08845",
"title": "Responsively Style Radio Buttons", "title": "Responsively Style Radio Buttons",
"difficulty": 2.14,
"description": [ "description": [
"You can use Bootstrap's <code>col-xs-*</code> classes on <code>form</code> elements, too! This way, our radio buttons will be evenly spread out across the page, regardless of how wide the screen resolution is.", "You can use Bootstrap's <code>col-xs-*</code> classes on <code>form</code> elements, too! This way, our radio buttons will be evenly spread out across the page, regardless of how wide the screen resolution is.",
"Nest all of your radio buttons within a <code>&#60;div class=\"row\"&#62;</code> element. Then nest each of them within a <code>&#60;div class=\"col-xs-6\"&#62;</code> element." "Nest all of your radio buttons within a <code>&#60;div class=\"row\"&#62;</code> element. Then nest each of them within a <code>&#60;div class=\"col-xs-6\"&#62;</code> element."
@ -1336,7 +1308,6 @@
{ {
"id": "bad87fee1348bd9aeda08845", "id": "bad87fee1348bd9aeda08845",
"title": "Responsively Style Checkboxes", "title": "Responsively Style Checkboxes",
"difficulty": 2.15,
"description": [ "description": [
"You can use Bootstrap's <code>col-xs-*</code> classes on <code>form</code> elements, too! This way, our checkboxes will be evenly spread out across the page, regardless of how wide the screen resolution is.", "You can use Bootstrap's <code>col-xs-*</code> classes on <code>form</code> elements, too! This way, our checkboxes will be evenly spread out across the page, regardless of how wide the screen resolution is.",
"Nest all your checkboxes in a <code>&#60;div class=\"row\"&#62;</code> element. Then nest each of them in a <code>&#60;div class=\"col-xs-4\"&#62;</code> element." "Nest all your checkboxes in a <code>&#60;div class=\"row\"&#62;</code> element. Then nest each of them in a <code>&#60;div class=\"col-xs-4\"&#62;</code> element."
@ -1428,7 +1399,6 @@
{ {
"id": "bad87fee1348bd9aed908845", "id": "bad87fee1348bd9aed908845",
"title": "Style Text Inputs as Form Controls", "title": "Style Text Inputs as Form Controls",
"difficulty": 2.16,
"description": [ "description": [
"You can add the <code>fa-paper-plane</code> Font Awesome icon by adding <code>&#60;i class=\"fa fa-paper-plane\"&#62;&#60;/i&#62;</code> within your submit <code>button</code> element.", "You can add the <code>fa-paper-plane</code> Font Awesome icon by adding <code>&#60;i class=\"fa fa-paper-plane\"&#62;&#60;/i&#62;</code> within your submit <code>button</code> element.",
"Give your form's text input field a class of <code>form-control</code>. Give your form's submit button the classes <code>btn btn-primary</code>. Also give this button the Font Awesome icon of <code>fa-paper-plane</code>." "Give your form's text input field a class of <code>form-control</code>. Give your form's submit button the classes <code>btn btn-primary</code>. Also give this button the Font Awesome icon of <code>fa-paper-plane</code>."
@ -1529,7 +1499,6 @@
{ {
"id": "bad87fee1348bd9aec908845", "id": "bad87fee1348bd9aec908845",
"title": "Line up Form Elements Responsively with Bootstrap", "title": "Line up Form Elements Responsively with Bootstrap",
"difficulty": 2.17,
"description": [ "description": [
"Now let's get your form <code>input</code> and your submission <code>button</code> on the same line. We'll do this the same way we have previously: by using a <code>div</code> element with the class <code>row</code>, and other <code>div</code> elements within it using the <code>col-xs-*</code> class.", "Now let's get your form <code>input</code> and your submission <code>button</code> on the same line. We'll do this the same way we have previously: by using a <code>div</code> element with the class <code>row</code>, and other <code>div</code> elements within it using the <code>col-xs-*</code> class.",
"Nest both your form's text <code>input</code> and submit <code>button</code> within a <code>div</code> with the class <code>row</code>. Nest your form's text <code>input</code> within a div with the class of <code>col-xs-7</code>. Nest your form's submit <code>button</code> in a <code>div</code> with the class <code>col-xs-5</code>.", "Nest both your form's text <code>input</code> and submit <code>button</code> within a <code>div</code> with the class <code>row</code>. Nest your form's text <code>input</code> within a div with the class of <code>col-xs-7</code>. Nest your form's submit <code>button</code> in a <code>div</code> with the class <code>col-xs-5</code>.",
@ -1631,7 +1600,6 @@
{ {
"id": "bad87fee1348bd9aec908846", "id": "bad87fee1348bd9aec908846",
"title": "Create a Bootstrap Headline", "title": "Create a Bootstrap Headline",
"difficulty": 2.18,
"description": [ "description": [
"Now let's build something from scratch to practice our HTML, CSS and Bootstrap skills.", "Now let's build something from scratch to practice our HTML, CSS and Bootstrap skills.",
"We'll build a jQuery playground, which we'll soon put to use in our jQuery challenges.", "We'll build a jQuery playground, which we'll soon put to use in our jQuery challenges.",
@ -1666,7 +1634,6 @@
{ {
"id": "bad87fee1348bd9aec908746", "id": "bad87fee1348bd9aec908746",
"title": "House our page within a Bootstrap Container Fluid Div", "title": "House our page within a Bootstrap Container Fluid Div",
"difficulty": 2.18,
"description": [ "description": [
"Now let's make sure all the content on your page is mobile-responsive.", "Now let's make sure all the content on your page is mobile-responsive.",
"Let's nest your <code>h3</code> element within a <code>div</code> element with the class <code>container-fluid</code>." "Let's nest your <code>h3</code> element within a <code>div</code> element with the class <code>container-fluid</code>."
@ -1696,7 +1663,6 @@
{ {
"id": "bad87fee1348bd9bec908846", "id": "bad87fee1348bd9bec908846",
"title": "Create a Bootstrap Row", "title": "Create a Bootstrap Row",
"difficulty": 2.19,
"description": [ "description": [
"Now we'll create a Bootstrap row for our inline elements.", "Now we'll create a Bootstrap row for our inline elements.",
"Create a <code>div</code> element with the class <code>row</code>." "Create a <code>div</code> element with the class <code>row</code>."
@ -1729,13 +1695,12 @@
{ {
"id": "bad87fee1348bd9aec908847", "id": "bad87fee1348bd9aec908847",
"title": "Split your Bootstrap Row", "title": "Split your Bootstrap Row",
"difficulty": 2.20,
"description": [ "description": [
"Now that we have a Bootstrap Row, let's split it into two columns to house our elements.", "Now that we have a Bootstrap Row, let's split it into two columns to house our elements.",
"Create two <code>div</code> elements within your row, both with the class <code>col-xs-6</code>." "Create two <code>div</code> elements within your row, both with the class <code>col-xs-6</code>."
], ],
"tests": [ "tests": [
"assert($(\"div.row\").children(\"div.col-xs-6\").length > 1, 'Nest two <code>div class=\"col-xs-6\"</code> elements within your <code>div class=\"row\"</code> element.')", "assert($(\"div.row > div.col-xs-6\").length > 1, 'Nest two <code>div class=\"col-xs-6\"</code> elements within your <code>div class=\"row\"</code> element.')",
"assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure all your <code>div</code> elements have closing tags.')" "assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure all your <code>div</code> elements have closing tags.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -1763,14 +1728,13 @@
{ {
"id": "bad87fee1348bd9aec908848", "id": "bad87fee1348bd9aec908848",
"title": "Create Bootstrap Wells", "title": "Create Bootstrap Wells",
"difficulty": 2.21,
"description": [ "description": [
"Bootstrap has a class called <code>well</code> that can create a visual sense of depth for your columns.", "Bootstrap has a class called <code>well</code> that can create a visual sense of depth for your columns.",
"Nest one <code>div</code> element with the class <code>well</code> within each of your <code>col-xs-6</code> <code>div</code> elements." "Nest one <code>div</code> element with the class <code>well</code> within each of your <code>col-xs-6</code> <code>div</code> elements."
], ],
"tests": [ "tests": [
"assert($(\"div\").length > 4, 'Add a <code>div</code> element with the class <code>well</code> inside each of your <code>div class=\"col-xs-6\" elements</code>')", "assert($(\"div.col-xs-6\").not(\":has(>div.well)\").length < 1, 'Add a <code>div</code> element with the class <code>well</code> inside each of your <code>div</code> elements with the class <code>\"col-xs-6\"</code>')",
"assert($(\"div.col-xs-6 div.well\").length > 1, 'Nest both of your <code>div class=\"col-xs-6\"</code> elements within your <code>div class=\"row\"</code> element.')", "assert($(\"div.row > div.col-xs-6\").length > 1, 'Nest both of your <code>div</code> elements with the class <code>\"col-xs-6\"</code> within your <code>div</code> element with the class <code>\"row\"</code>.')",
"assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure all your <code>div</code> elements have closing tags.')" "assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure all your <code>div</code> elements have closing tags.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -1802,7 +1766,6 @@
{ {
"id": "bad87fee1348bd9aec908849", "id": "bad87fee1348bd9aec908849",
"title": "Add Elements within your Bootstrap Wells", "title": "Add Elements within your Bootstrap Wells",
"difficulty": 2.22,
"description": [ "description": [
"Now we're several <code>div</code> elements deep on each column of our row. This is as deep as we'll need to go. Now we can add our <code>button</code> elements.", "Now we're several <code>div</code> elements deep on each column of our row. This is as deep as we'll need to go. Now we can add our <code>button</code> elements.",
"Nest three <code>button</code> elements within each of your <code>well</code> <code>div</code> elements." "Nest three <code>button</code> elements within each of your <code>well</code> <code>div</code> elements."
@ -1849,7 +1812,6 @@
{ {
"id": "bad87fee1348bd9aec908850", "id": "bad87fee1348bd9aec908850",
"title": "Apply the Default Bootstrap Button Style", "title": "Apply the Default Bootstrap Button Style",
"difficulty": 2.23,
"description": [ "description": [
"Bootstrap has another button class called <code>btn-default</code>.", "Bootstrap has another button class called <code>btn-default</code>.",
"Apply both the <code>btn</code> and <code>btn-default</code> classes to each of your <code>button</code> elements." "Apply both the <code>btn</code> and <code>btn-default</code> classes to each of your <code>button</code> elements."
@ -1895,7 +1857,6 @@
{ {
"id": "bad87fee1348bd9aec908852", "id": "bad87fee1348bd9aec908852",
"title": "Create a Class to Target with jQuery Selectors", "title": "Create a Class to Target with jQuery Selectors",
"difficulty": 2.24,
"description": [ "description": [
"Not every class needs to have corresponding CSS. Sometimes we create classes just for the purpose of selecting these elements more easily using jQuery.", "Not every class needs to have corresponding CSS. Sometimes we create classes just for the purpose of selecting these elements more easily using jQuery.",
"Give each of your <code>button</code> elements the class <code>target</code>." "Give each of your <code>button</code> elements the class <code>target</code>."
@ -1940,7 +1901,6 @@
{ {
"id": "bad87fee1348bd9aec908853", "id": "bad87fee1348bd9aec908853",
"title": "Add ID Attributes to Bootstrap Elements", "title": "Add ID Attributes to Bootstrap Elements",
"difficulty": 2.25,
"description": [ "description": [
"Recall that in addition to class attributes, you can give each of your elements an <code>id</code> attribute.", "Recall that in addition to class attributes, you can give each of your elements an <code>id</code> attribute.",
"Each id should be unique to a specific element.", "Each id should be unique to a specific element.",
@ -1949,8 +1909,8 @@
"Give the well on the left the id of <code>left-well</code>. Give the well on the right the <code>id</code> of <code>right-well</code>." "Give the well on the left the id of <code>left-well</code>. Give the well on the right the <code>id</code> of <code>right-well</code>."
], ],
"tests": [ "tests": [
"assert($(\"#left-well\") && $(\"#left-well\").length > 0, 'Give your left <code>well</code> the id of <code>left-well</code>.')", "assert($(\".col-xs-6\").children(\"#left-well\") && $(\".col-xs-6\").children(\"#left-well\").length > 0, 'Give your left <code>well</code> the id of <code>left-well</code>.')",
"assert($(\"#right-well\") && $(\"#right-well\").length > 0, 'Give your right <code>well</code> the id of <code>right-well</code>.')" "assert($(\".col-xs-6\").children(\"#right-well\") && $(\".col-xs-6\").children(\"#right-well\").length > 0, 'Give your right <code>well</code> the id of <code>right-well</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<div class=\"container-fluid\">", "<div class=\"container-fluid\">",
@ -1989,14 +1949,13 @@
{ {
"id": "bad87fee1348bd9aec908854", "id": "bad87fee1348bd9aec908854",
"title": "Label Bootstrap Wells", "title": "Label Bootstrap Wells",
"difficulty": 2.26,
"description": [ "description": [
"For the sake of clarity, let's label both of our wells with their ids.", "For the sake of clarity, let's label both of our wells with their ids.",
"Above your left-well, inside its <code>col-xs-6</code> <code>div</code> element, add a <code>h4</code> element with the text <code>#left-well</code>.", "Above your left-well, inside its <code>col-xs-6</code> <code>div</code> element, add a <code>h4</code> element with the text <code>#left-well</code>.",
"Above your right-well, inside its <code>col-xs-6</code> <code>div</code> element, add a <code>h4</code> element with the text <code>#right-well</code>." "Above your right-well, inside its <code>col-xs-6</code> <code>div</code> element, add a <code>h4</code> element with the text <code>#right-well</code>."
], ],
"tests": [ "tests": [
"assert($(\".col-xs-6\").children(\"h4\") && $(\".col-xs-6\").children(\"h4\").length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\\\"col-xs-6\\\"&#62;</code> elements.');", "assert($(\".col-xs-6\").children(\"h4\") && $(\".col-xs-6\").children(\"h4\").length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\"col-xs-6\"&#62;</code> elements.');",
"assert(new RegExp(\"#left-well\",\"gi\").test($(\"h4\").text()), 'One <code>h4</code> element should have the text <code>#left-well</code>.');", "assert(new RegExp(\"#left-well\",\"gi\").test($(\"h4\").text()), 'One <code>h4</code> element should have the text <code>#left-well</code>.');",
"assert(new RegExp(\"#right-well\",\"gi\").test($(\"h4\").text()), 'One <code>h4</code> element should have the text <code>#right-well</code>.');", "assert(new RegExp(\"#right-well\",\"gi\").test($(\"h4\").text()), 'One <code>h4</code> element should have the text <code>#right-well</code>.');",
"assert(editor.match(/<\\/h4>/g) && editor.match(/<h4/g) && editor.match(/<\\/h4>/g).length === editor.match(/<h4/g).length, 'Make sure all your <code>h4</code> elements have closing tags.')" "assert(editor.match(/<\\/h4>/g) && editor.match(/<h4/g) && editor.match(/<\\/h4>/g).length === editor.match(/<h4/g).length, 'Make sure all your <code>h4</code> elements have closing tags.')"
@ -2040,18 +1999,17 @@
{ {
"id": "bad87fee1348bd9aec908855", "id": "bad87fee1348bd9aec908855",
"title": "Give Each Element a Unique ID", "title": "Give Each Element a Unique ID",
"difficulty": 2.27,
"description": [ "description": [
"We will also want to be able to use jQuery to target each button by its unique id.", "We will also want to be able to use jQuery to target each button by its unique id.",
"Give each of your buttons a unique id like, starting with <code>target1</code> and ending with <code>target6</code>." "Give each of your buttons a unique id like, starting with <code>target1</code> and ending with <code>target6</code>."
], ],
"tests": [ "tests": [
"assert($(\"#target1\") && $(\"#target1\").length > 0, 'One <code>button</code> element should have the id <code>target1</code>.')", "assert($(\"#left-well\").children(\"#target1\") && $(\"#left-well\").children(\"#target1\").length > 0, 'One <code>button</code> element should have the id <code>target1</code>.')",
"assert($(\"#target2\") && $(\"#target2\").length > 0, 'One <code>button</code> element should have the id <code>target2</code>.')", "assert($(\"#left-well\").children(\"#target2\") && $(\"#left-well\").children(\"#target2\").length > 0, 'One <code>button</code> element should have the id <code>target2</code>.')",
"assert($(\"#target3\") && $(\"#target3\").length > 0, 'One <code>button</code> element should have the id <code>target3</code>.')", "assert($(\"#left-well\").children(\"#target3\") && $(\"#left-well\").children(\"#target3\").length > 0, 'One <code>button</code> element should have the id <code>target3</code>.')",
"assert($(\"#target4\") && $(\"#target4\").length > 0, 'One <code>button</code> element should have the id <code>target4</code>.')", "assert($(\"#right-well\").children(\"#target4\") && $(\"#right-well\").children(\"#target4\").length > 0, 'One <code>button</code> element should have the id <code>target4</code>.')",
"assert($(\"#target5\") && $(\"#target5\").length > 0, 'One <code>button</code> element should have the id <code>target5</code>.')", "assert($(\"#right-well\").children(\"#target5\") && $(\"#right-well\").children(\"#target5\").length > 0, 'One <code>button</code> element should have the id <code>target5</code>.')",
"assert($(\"#target6\") && $(\"#target6\").length > 0, 'One <code>button</code> element should have the id <code>target6</code>.')" "assert($(\"#right-well\").children(\"#target6\") && $(\"#right-well\").children(\"#target6\").length > 0, 'One <code>button</code> element should have the id <code>target6</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<div class=\"container-fluid\">", "<div class=\"container-fluid\">",
@ -2092,7 +2050,6 @@
{ {
"id": "bad87fee1348bd9aec908856", "id": "bad87fee1348bd9aec908856",
"title": "Label Bootstrap Buttons", "title": "Label Bootstrap Buttons",
"difficulty": 2.28,
"description": [ "description": [
"Just like we labeled our wells, we want to label our buttons.", "Just like we labeled our wells, we want to label our buttons.",
"Give each of your <code>button</code> elements text that corresponds to their <code>id</code>." "Give each of your <code>button</code> elements text that corresponds to their <code>id</code>."
@ -2144,7 +2101,6 @@
{ {
"id": "bad87fee1348bd9aec908857", "id": "bad87fee1348bd9aec908857",
"title": "Use Comments to Clarify Code", "title": "Use Comments to Clarify Code",
"difficulty": 2.29,
"description": [ "description": [
"When we start using jQuery, we will modify HTML elements without needing to actually change them in HTML.", "When we start using jQuery, we will modify HTML elements without needing to actually change them in HTML.",
"Let's make sure that everyone knows they shouldn't actually modify any of this code directly.", "Let's make sure that everyone knows they shouldn't actually modify any of this code directly.",

View File

@ -0,0 +1,226 @@
{
"name": "Claim Your Front End Development Certificate",
"order": 12,
"challenges": [
{
"id": "561add10cb82ac38a17513be",
"title": "Claim Your Front End Development Certificate",
"difficulty": 0.00,
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/RlEk2IF.jpg",
"a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits",
"Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [
{
"id": "ad7123c8c441eddfaeb5bdef",
"title": "Meet Bonfire"
},
{
"id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String"
},
{
"id": "a302f7aae1aa3152a5b413bc",
"title": "Factorialize a Number"
},
{
"id": "aaa48de84e1ecc7c742e1124",
"title": "Check for Palindromes"
},
{
"id": "a26cbbe9ad8655a977e1ceb5",
"title": "Find the Longest Word in a String"
},
{
"id": "ab6137d4e35944e21037b769",
"title": "Title Case a Sentence"
},
{
"id": "a789b3483989747d63b0e427",
"title": "Return Largest Numbers in Arrays"
},
{
"id": "acda2fb1324d9b0fa741e6b5",
"title": "Confirm the Ending"
},
{
"id": "afcc8d540bea9ea2669306b6",
"title": "Repeat a string repeat a string"
},
{
"id": "ac6993d51946422351508a41",
"title": "Truncate a string"
},
{
"id": "a9bd25c716030ec90084d8a1",
"title": "Chunky Monkey"
},
{
"id": "ab31c21b530c0dafa9e241ee",
"title": "Slasher Flick"
},
{
"id": "af2170cad53daa0770fabdea",
"title": "Mutations"
},
{
"id": "adf08ec01beb4f99fc7a68f2",
"title": "Falsy Bouncer"
},
{
"id": "a39963a4c10bc8b4d4f06d7e",
"title": "Seek and Destroy"
},
{
"id": "a24c1a4622e3c05097f71d67",
"title": "Where do I belong"
},
{
"id": "a3566b1109230028080c9345",
"title": "Sum All Numbers in a Range"
},
{
"id": "a5de63ebea8dbee56860f4f2",
"title": "Diff Two Arrays"
},
{
"id": "a7f4d8f2483413a6ce226cac",
"title": "Roman Numeral Converter"
},
{
"id": "a8e512fbe388ac2f9198f0fa",
"title": "Where art thou"
},
{
"id": "a0b5010f579e69b815e7c5d6",
"title": "Search and Replace"
},
{
"id": "aa7697ea2477d1316795783b",
"title": "Pig Latin"
},
{
"id": "afd15382cdfb22c9efe8b7de",
"title": "DNA Pairing"
},
{
"id": "af7588ade1100bde429baf20",
"title": "Missing letters"
},
{
"id": "a77dbc43c33f39daa4429b4f",
"title": "Boo who"
},
{
"id": "a105e963526e7de52b219be9",
"title": "Sorted Union"
},
{
"id": "a6b0bb188d873cb2c8729495",
"title": "Convert HTML Entities"
},
{
"id": "a103376db3ba46b2d50db289",
"title": "Spinal Tap Case"
},
{
"id": "a5229172f011153519423690",
"title": "Sum All Odd Fibonacci Numbers"
},
{
"id": "a3bfc1673c0526e06d3ac698",
"title": "Sum All Primes"
},
{
"id": "ae9defd7acaf69703ab432ea",
"title": "Smallest Common Multiple"
},
{
"id": "a6e40f1041b06c996f7b2406",
"title": "Finders Keepers"
},
{
"id": "a5deed1811a43193f9f1c841",
"title": "Drop it"
},
{
"id": "ab306dbdcc907c7ddfc30830",
"title": "Steamroller"
},
{
"id": "a8d97bd4c764e91f9d2bda01",
"title": "Binary Agents"
},
{
"id": "a10d2431ad0c6a099a4b8b52",
"title": "Everything Be True"
},
{
"id": "a97fd23d9b809dac9921074f",
"title": "Arguments Optional"
},
{
"id": "bd7158d8c442eddfbeb5bd1f",
"title": "Get Set for Ziplines"
},
{
"id": "bd7158d8c242eddfaeb5bd13",
"title": "Build a Personal Portfolio Webpage"
},
{
"id": "bd7158d8c442eddfaeb5bd13",
"title": "Build a Random Quote Machine"
},
{
"id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock"
},
{
"id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator"
},
{
"id": "bd7158d8c442eddfaeb5bd10",
"title": "Show the Local Weather"
},
{
"id": "bd7158d8c442eddfaeb5bd1f",
"title": "Use the Twitch.tv JSON API"
},
{
"id": "bd7158d8c442eddfaeb5bd18",
"title": "Stylize Stories on Camper News"
},
{
"id": "bd7158d8c442eddfaeb5bd19",
"title": "Build a Wikipedia Viewer"
},
{
"id": "bd7158d8c442eedfaeb5bd1c",
"title": "Build a Tic Tac Toe Game"
},
{
"id": "bd7158d8c442eddfaeb5bd1c",
"title": "Build a Simon Game"
}
],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
}
]
}

View File

@ -0,0 +1,286 @@
{
"name": "Claim Your Full Stack Development Certificate",
"order": 21,
"challenges": [
{
"id": "660add10cb82ac38a17513be",
"title": "Claim Your Full Stack Development Certificate",
"difficulty": 0.00,
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/RlEk2IF.jpg",
"a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits",
"Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [
{
"id": "ad7123c8c441eddfaeb5bdef",
"title": "Meet Bonfire"
},
{
"id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String"
},
{
"id": "a302f7aae1aa3152a5b413bc",
"title": "Factorialize a Number"
},
{
"id": "aaa48de84e1ecc7c742e1124",
"title": "Check for Palindromes"
},
{
"id": "a26cbbe9ad8655a977e1ceb5",
"title": "Find the Longest Word in a String"
},
{
"id": "ab6137d4e35944e21037b769",
"title": "Title Case a Sentence"
},
{
"id": "a789b3483989747d63b0e427",
"title": "Return Largest Numbers in Arrays"
},
{
"id": "acda2fb1324d9b0fa741e6b5",
"title": "Confirm the Ending"
},
{
"id": "afcc8d540bea9ea2669306b6",
"title": "Repeat a string repeat a string"
},
{
"id": "ac6993d51946422351508a41",
"title": "Truncate a string"
},
{
"id": "a9bd25c716030ec90084d8a1",
"title": "Chunky Monkey"
},
{
"id": "ab31c21b530c0dafa9e241ee",
"title": "Slasher Flick"
},
{
"id": "af2170cad53daa0770fabdea",
"title": "Mutations"
},
{
"id": "adf08ec01beb4f99fc7a68f2",
"title": "Falsy Bouncer"
},
{
"id": "a39963a4c10bc8b4d4f06d7e",
"title": "Seek and Destroy"
},
{
"id": "a24c1a4622e3c05097f71d67",
"title": "Where do I belong"
},
{
"id": "a3566b1109230028080c9345",
"title": "Sum All Numbers in a Range"
},
{
"id": "a5de63ebea8dbee56860f4f2",
"title": "Diff Two Arrays"
},
{
"id": "a7f4d8f2483413a6ce226cac",
"title": "Roman Numeral Converter"
},
{
"id": "a8e512fbe388ac2f9198f0fa",
"title": "Where art thou"
},
{
"id": "a0b5010f579e69b815e7c5d6",
"title": "Search and Replace"
},
{
"id": "aa7697ea2477d1316795783b",
"title": "Pig Latin"
},
{
"id": "afd15382cdfb22c9efe8b7de",
"title": "DNA Pairing"
},
{
"id": "af7588ade1100bde429baf20",
"title": "Missing letters"
},
{
"id": "a77dbc43c33f39daa4429b4f",
"title": "Boo who"
},
{
"id": "a105e963526e7de52b219be9",
"title": "Sorted Union"
},
{
"id": "a6b0bb188d873cb2c8729495",
"title": "Convert HTML Entities"
},
{
"id": "a103376db3ba46b2d50db289",
"title": "Spinal Tap Case"
},
{
"id": "a5229172f011153519423690",
"title": "Sum All Odd Fibonacci Numbers"
},
{
"id": "a3bfc1673c0526e06d3ac698",
"title": "Sum All Primes"
},
{
"id": "ae9defd7acaf69703ab432ea",
"title": "Smallest Common Multiple"
},
{
"id": "a6e40f1041b06c996f7b2406",
"title": "Finders Keepers"
},
{
"id": "a5deed1811a43193f9f1c841",
"title": "Drop it"
},
{
"id": "ab306dbdcc907c7ddfc30830",
"title": "Steamroller"
},
{
"id": "a8d97bd4c764e91f9d2bda01",
"title": "Binary Agents"
},
{
"id": "a10d2431ad0c6a099a4b8b52",
"title": "Everything Be True"
},
{
"id": "a97fd23d9b809dac9921074f",
"title": "Arguments Optional"
},
{
"id": "bd7158d8c442eddfbeb5bd1f",
"title": "Get Set for Ziplines"
},
{
"id": "bd7158d8c242eddfaeb5bd13",
"title": "Build a Personal Portfolio Webpage"
},
{
"id": "bd7158d8c442eddfaeb5bd13",
"title": "Build a Random Quote Machine"
},
{
"id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock"
},
{
"id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator"
},
{
"id": "bd7158d8c442eddfaeb5bd10",
"title": "Show the Local Weather"
},
{
"id": "bd7158d8c442eddfaeb5bd1f",
"title": "Use the Twitch.tv JSON API"
},
{
"id": "bd7158d8c442eddfaeb5bd18",
"title": "Stylize Stories on Camper News"
},
{
"id": "bd7158d8c442eddfaeb5bd19",
"title": "Build a Wikipedia Viewer"
},
{
"id": "bd7158d8c442eedfaeb5bd1c",
"title": "Build a Tic Tac Toe Game"
},
{
"id": "bd7158d8c442eddfaeb5bd1c",
"title": "Build a Simon Game"
},
{
"id": "a2f1d72d9b908d0bd72bb9f6",
"title": "Make a Person"
},
{
"id": "af4afb223120f7348cdfc9fd",
"title": "Map the Debris"
},
{
"id": "a3f503de51cfab748ff001aa",
"title": "Pairwise"
},
{
"id": "aff0395860f5d3034dc0bfc9",
"title": "Validate US Telephone Numbers"
},
{
"id": "a3f503de51cf954ede28891d",
"title": "Symmetric Difference"
},
{
"id": "aa2e6f85cab2ab736c9a9b24",
"title": "Exact Change"
},
{
"id": "a56138aff60341a09ed6c480",
"title": "Inventory Update"
},
{
"id": "a7bf700cd123b9a54eef01d5",
"title": "No repeats please"
},
{
"id": "a19f0fbe1872186acd434d5a",
"title": "Friendly Date Ranges"
},
{
"id": "bd7158d8c443eddfaeb5bcef",
"title": "Get Set for Basejumps"
},
{
"id": "bd7158d8c443eddfaeb5bdef",
"title": "Build a Voting App"
},
{
"id": "bd7158d8c443eddfaeb5bdff",
"title": "Build a Nightlife Coordination App"
},
{
"id": "bd7158d8c443eddfaeb5bd0e",
"title": "Chart the Stock Market"
},
{
"id": "bd7158d8c443eddfaeb5bd0f",
"title": "Manage a Book Trading Club"
},
{
"id": "bd7158d8c443eddfaeb5bdee",
"title": "Build a Pinterest Clone"
}
],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
}
]
}

View File

@ -0,0 +1,314 @@
{
"name": "Get Started with Free Code Camp",
"order": 1,
"challenges": [
{
"id": "560add10cb82ac38a17513be",
"title": "Learn how Free Code Camp Works",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/RlEk2IF.jpg",
"a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits",
"Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.",
""
],
[
"http://i.imgur.com/pYsTbjI.jpg",
"a screenshot of our curriculum alongside a screenshot of our chat room.",
"Learning to code is hard. To succeed, you'll need lots of practice and support. That's why we've created a rigorous curriculum and supportive community.",
""
],
[
"http://i.imgur.com/D7Y5luw.jpg",
"A graph of the rate of job growth against growth in computer science degree graduates. There are 1.4 million jobs and only 400 million people to fill them.",
"There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year. If you want a coding job, we can help prepare you to get one.",
""
],
[
"http://i.imgur.com/dLx8nrg.jpg",
"An illustration showing that you will learn HTML5, CSS3, JavaScript, Databases, Git, Node.js, Angular.js and Agile.",
"First you'll work through our rigorous 800-hour curriculum learn technologies like HTML5, Node.js and databases. It's self-paced and 100% free.",
""
],
[
"http://i.imgur.com/q4IjuCL.jpg",
"a screenshot of our Front End Development Certificate",
"About half way through our curriculum, you'll earn a verified Front End Development Certificate. If you can finish our entire curriculum, you'll earn a verified Full Stack Development Certificate.",
""
],
[
"http://i.imgur.com/yXyxbDd.jpg",
"a screen shot of our nonprofit project directory.",
"Then you'll build several real-life projects for nonprofits. By the time you finish, you'll have a portfolio of real apps that people use every day.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add37cb82ac38a17513bf",
"title": "Create a GitHub Account and Join our Chat Rooms",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/EAR7Lvh.jpg",
"a screenshot of our one of our Gitter chat rooms.",
"Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with. First you'll need a GitHub account.",
""
],
[
"http://i.imgur.com/FEImaEN.gif",
"A gif showing you to click the link below to go to GitHub. Fill in the necessary fields and click submit.",
"Create an account with GitHub. Be sure to use your real email address - GitHub will keep this private.",
"https://github.com/join"
],
[
"http://i.imgur.com/ALN6zPK.gif",
"A gif showing you how to click the profile image in the upper right hand corner of GitHub. Upload a photo of yourself or you will continue to use the automatically generated pixel art. Then fill in the remaining form fields and click submit.",
"Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how your fellow campers will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.",
"https://github.com/settings/profile"
],
[
"http://i.imgur.com/OXL3G3n.gif",
"Click the link below to navigate to Free Code Camp's open-source repository. In the upper right hand corner, you can click the \"star\" button to star this repository.",
"Go to Free Code Camp's open-source repository and \"star\" it. \"Starring\" is the GitHub equivalent of \"liking\" something.",
"https://github.com/freecodecamp/freecodecamp"
],
[
"http://i.imgur.com/EZHzKCV.gif",
"A gif showing you how to click the link below to go to our chat room and click the \"sign in with GitHub\" button. Then you can click into the text input field and type a message to your fellow campers.",
" Now that you have a GitHub account, you can join our main chat room by logging in with GitHub. Introduce yourself by saying \"Hello world!\". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
"https://gitter.im/FreeCodeCamp/FreeCodeCamp"
],
[
"http://i.imgur.com/Ecs5XAd.gif",
"A gif showing you how you can click the settings button in the upper right hand corner and modify your notification settings.",
"Our chat rooms are extremely active. You should change your settings so you're only notified if someone mentions you.",
""
],
[
"http://i.imgur.com/T0bGJPe.gif",
"A gif showing how you can click on a user profile image to initiate a private message with that user.",
"Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.",
""
],
[
"http://i.imgur.com/vDTMJSh.gif",
"A gif showing that you can tab back and forth between challenges and our chat rooms.",
"Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.",
""
],
[
"http://i.imgur.com/SLQ27Gr.gif",
"A gif showing how you can click the link below to download a native chat room app for your computer.",
"You can also download the chat room app to your computer or phone.",
"https://gitter.im/apps"
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add56cb82ac38a17513c0",
"title": "Configure your Public Profile",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/FkEzbto.gif",
"A gif showing how you can click your profile image in your upper right hand corner to access the account page and connect GitHub.",
"Check out your portfolio page. Click your picture your upper right hand corner. To activate your portfolio page, you'll need to link your GitHub account with Free Code Camp.",
""
],
[
"http://i.imgur.com/WKzEr1q.gif",
"A gif showing how you can access your profile page and hover over different days to see how many brownie points you got on those days.",
"Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add65cb82ac38a17513c1",
"title": "Try our Wiki and Camper News",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/DoOqkNW.gif",
"A gif showing how you can click the \"Wiki\" button in your upper-right corner to access the wiki.",
"Try this: Click the \"Wiki\" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.",
""
],
[
"http://i.imgur.com/nmSiMy1.gif",
"A gif showing how you can access our Camper News page and click the \"upvote\" button to upvote a story.",
"Click the \"News\" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add71cb82ac38a17513c2",
"title": "Join a Campsite in Your City",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/Elb3dfj.jpg",
"A picture of some of our campers meeting in a local cafe. 3 men and 3 women are sitting around a table with laptops out, and are smiling and coding.",
"Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.",
""
],
[
"http://i.imgur.com/EZHzKCV.gif",
"A gif showing how you can click the link below, find your city on the list of Campsites, then click on the Facebook link for your city and join your city's Facebook group.",
"Find your city on this list, click the \"Facebook\" link, then click the \"Join group\" button to apply to join your city's Facebook group (someone from the campsite should approve you shortly). If your city isn't on this list, scroll to the bottom of the wiki article for instructions for how you can create your city's Campsite.",
"https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites"
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add8ccb82ac38a17513c3",
"title": "Join our Alumni Network and Commit to Your Goal",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/P7qfJXt.gif",
"A gif showing how you can click the link below and fill in the necessary fields to add your Free Code Camp studies to your LinkedIn profile.",
"You can add Free Code Camp to your LinkedIn education background. Set your graduation date as next year. For \"Degree\", type \"Full Stack Web Development\". For \"Field of study\", type \"Computer Software Engineering\". Then click \"Save Changes\".",
"https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp"
],
[
"",
"",
"Free Code Camp will always be free. If you want to feel more motivated to earn our certificates faster, we encourage you to instead donate each month to a nonprofit.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "560add8ccb82ac38a17513c4",
"title": "Learn What to Do If You Get Stuck",
"challengeSeed": [],
"description": [
[
"http://i.imgur.com/EWWZBag.jpg",
"An image with the text \"1. Read the error 2. Search Google 3. Ask for help.",
"Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: Read-Search-Ask.",
""
],
[
"http://i.imgur.com/99BfAcK.jpg",
"An image showing jQuery documentation",
"First, read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.",
""
],
[
"http://i.imgur.com/GxvrsFb.gif",
"A gif showing you how to do an advanced Google search. First, we enter the query \"jquery doesn't run when my page loads\". Then we click search tools button and change the \"Any time\" select box to \"within the last year\". Then we click on a result and read through the article and find our answer.",
"If that didn't help, 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.",
""
],
[
"http://i.imgur.com/LZYU7p2.gif",
"A gif showing us following the link below to go to the help chat room and ask \"jquery doesn't run when my page loads\".",
"If that didn't help, ask your friends. If you have trouble, you can ask your fellow campers in our help chat room.",
"https://gitter.im/FreeCodeCamp/Help"
],
[
"http://i.imgur.com/WsfzvVo.gif",
"A gif showing us clicking the \"map\" button in our upper right hand corner and browsing our challenge map.",
"Now you're ready to start coding! The \"Map\" button in your upper right hand corner will show you our challenge map. This map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace. You can also return to your next challenge by clicking the \"Learn\" button.",
""
]
],
"type": "Waypoint",
"challengeType": 7,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
}
]
}

View File

@ -1,21 +1,20 @@
{ {
"name": "Git", "name": "Git",
"order" : 0.016, "order" : 17,
"challenges": [ "challenges": [
{ {
"id": "bd7353d8c341eddeaeb5bd0f", "id": "bd7353d8c341eddeaeb5bd0f",
"title": "Save your Code Revisions Forever with Git", "title": "Save your Code Revisions Forever with Git",
"difficulty": 0.01,
"challengeSeed": ["133316034"], "challengeSeed": ["133316034"],
"description": [ "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.", "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 <a href='http://c9.io' target='_blank'>http://c9.io</a>.", "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
"Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.", "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> 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.", "Click on the \"+\" icon at the top right of the c9.io page to create a new workspace.",
"Give your workspace a name.", "Give your workspace a name and an optional description.",
"Choose Node.js in the selection area below the name field.", "Choose Node.js in the selection area below the name field.",
"Click the Create button. Then click into your new workspace.", "Click the \"Create workspace\" 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.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.",
"Install <code>git-it</code> with this command: <code>npm install -g git-it</code>", "Install <code>git-it</code> with this command: <code>npm install -g git-it</code>",
"Now start the tutorial by running <code>git-it</code>.", "Now start the tutorial by running <code>git-it</code>.",
"Note that you can resize the c9.io's windows by dragging their borders.", "Note that you can resize the c9.io's windows by dragging their borders.",

View File

@ -5,7 +5,6 @@
{ {
"id": "bd7128d8c441eddfbeb5bddf", "id": "bd7128d8c441eddfbeb5bddf",
"title": "Computer Basics 1: The 4 Basic Parts of a Computer", "title": "Computer Basics 1: The 4 Basic Parts of a Computer",
"difficulty": 9.01,
"challengeSeed": [ "challengeSeed": [
"132542064" "132542064"
], ],
@ -45,7 +44,6 @@
{ {
"id": "bd7127d8c441eddfbeb5bddf", "id": "bd7127d8c441eddfbeb5bddf",
"title": "Computer Basics 2: More Computer Hardware", "title": "Computer Basics 2: More Computer Hardware",
"difficulty": 9.02,
"challengeSeed": [ "challengeSeed": [
"132542458" "132542458"
], ],
@ -84,7 +82,6 @@
{ {
"id": "bd7126d8c441eddfbeb5bddf", "id": "bd7126d8c441eddfbeb5bddf",
"title": "Computer Basics 3: Intro to Binary Code", "title": "Computer Basics 3: Intro to Binary Code",
"difficulty": 9.03,
"challengeSeed": [ "challengeSeed": [
"132542757" "132542757"
], ],
@ -118,7 +115,6 @@
{ {
"id": "bd7125d8c441eddfbeb5bddf", "id": "bd7125d8c441eddfbeb5bddf",
"title": "Computer Basics 4: Decoding a Binary Number", "title": "Computer Basics 4: Decoding a Binary Number",
"difficulty": 9.04,
"challengeSeed": [ "challengeSeed": [
"132543332" "132543332"
], ],
@ -154,7 +150,6 @@
{ {
"id": "bd7124d8c441eddfbeb5bddf", "id": "bd7124d8c441eddfbeb5bddf",
"title": "Computer Basics 5: How To Measure Data Size", "title": "Computer Basics 5: How To Measure Data Size",
"difficulty": 9.05,
"challengeSeed": [ "challengeSeed": [
"132543959" "132543959"
], ],
@ -193,7 +188,6 @@
{ {
"id": "bd7123d8c441eddfbeb5bddf", "id": "bd7123d8c441eddfbeb5bddf",
"title": "Computer Basics 6: Measuring Data Speed", "title": "Computer Basics 6: Measuring Data Speed",
"difficulty": 9.06,
"challengeSeed": [ "challengeSeed": [
"132545171" "132545171"
], ],
@ -230,7 +224,6 @@
{ {
"id": "bd7122d8c441eddfbeb5bddf", "id": "bd7122d8c441eddfbeb5bddf",
"title": "Computer Basics 7: Binary Bytes", "title": "Computer Basics 7: Binary Bytes",
"difficulty": 9.07,
"challengeSeed": [ "challengeSeed": [
"132545417" "132545417"
], ],
@ -264,7 +257,6 @@
{ {
"id": "bd7121d8c441eddfbeb5bddf", "id": "bd7121d8c441eddfbeb5bddf",
"title": "Computer Basics 8: Types of Computers", "title": "Computer Basics 8: Types of Computers",
"difficulty": 9.08,
"challengeSeed": [ "challengeSeed": [
"132546182" "132546182"
], ],
@ -303,7 +295,6 @@
{ {
"id": "bd7120d8c441eddfbeb5bddf", "id": "bd7120d8c441eddfbeb5bddf",
"title": "Computer Basics 9: More on the Motherboard", "title": "Computer Basics 9: More on the Motherboard",
"difficulty": 9.09,
"challengeSeed": [ "challengeSeed": [
"132547285" "132547285"
], ],
@ -344,7 +335,6 @@
{ {
"id": "bd712fd8c441eddfbeb5bddf", "id": "bd712fd8c441eddfbeb5bddf",
"title": "Computer Basics 10: Data Networks", "title": "Computer Basics 10: Data Networks",
"difficulty": 9.10,
"challengeSeed": [ "challengeSeed": [
"132547590" "132547590"
], ],
@ -384,7 +374,6 @@
{ {
"id": "bd712ed8c441eddfbeb5bddf", "id": "bd712ed8c441eddfbeb5bddf",
"title": "Computer Basics 11: IP Addresses", "title": "Computer Basics 11: IP Addresses",
"difficulty": 9.11,
"challengeSeed": [ "challengeSeed": [
"132548071" "132548071"
], ],
@ -423,7 +412,6 @@
{ {
"id": "bd712dd8c441eddfbeb5bddf", "id": "bd712dd8c441eddfbeb5bddf",
"title": "Computer Basics 12: How the Internet Works", "title": "Computer Basics 12: How the Internet Works",
"difficulty": 9.12,
"challengeSeed": [ "challengeSeed": [
"132548579" "132548579"
], ],
@ -462,7 +450,6 @@
{ {
"id": "bd712cd8c441eddfbeb5bddf", "id": "bd712cd8c441eddfbeb5bddf",
"title": "Computer Basics 13: Software", "title": "Computer Basics 13: Software",
"difficulty": 9.13,
"challengeSeed": [ "challengeSeed": [
"132548908" "132548908"
], ],
@ -495,7 +482,6 @@
{ {
"id": "bd712bd8c441eddfbeb5bddf", "id": "bd712bd8c441eddfbeb5bddf",
"title": "What Do Programmers Do?", "title": "What Do Programmers Do?",
"difficulty": 9.14,
"challengeSeed": [ "challengeSeed": [
"133166912" "133166912"
], ],
@ -532,7 +518,6 @@
{ {
"id": "bd712ad8c441eddfbeb5bddf", "id": "bd712ad8c441eddfbeb5bddf",
"title": "Console and Logging", "title": "Console and Logging",
"difficulty": 9.15,
"challengeSeed": [ "challengeSeed": [
"133170880" "133170880"
], ],
@ -569,7 +554,6 @@
{ {
"id": "bd7119d8c441eddfbeb5bddf", "id": "bd7119d8c441eddfbeb5bddf",
"title": "Variables In Code", "title": "Variables In Code",
"difficulty": 9.16,
"challengeSeed": [ "challengeSeed": [
"133172920" "133172920"
], ],
@ -602,7 +586,6 @@
{ {
"id": "bd7029d8c441eddfbeb5bddf", "id": "bd7029d8c441eddfbeb5bddf",
"title": "Source Code", "title": "Source Code",
"difficulty": 9.17,
"challengeSeed": [ "challengeSeed": [
"133177129" "133177129"
], ],
@ -647,7 +630,6 @@
{ {
"id": "bd7129d8b441eddfbeb5bddf", "id": "bd7129d8b441eddfbeb5bddf",
"title": "Routers and Packets", "title": "Routers and Packets",
"difficulty": 9.18,
"challengeSeed": [ "challengeSeed": [
"133181251" "133181251"
], ],
@ -698,7 +680,6 @@
{ {
"id": "bd7129d8a441eddfbeb5bddf", "id": "bd7129d8a441eddfbeb5bddf",
"title": "Hardware: Chips and Moore's Law", "title": "Hardware: Chips and Moore's Law",
"difficulty": 9.19,
"challengeSeed": [ "challengeSeed": [
"133182057" "133182057"
], ],
@ -735,7 +716,6 @@
{ {
"id": "bd7129d80441eddfbeb5bddf", "id": "bd7129d80441eddfbeb5bddf",
"title": "Analog vs Digital and File Compression", "title": "Analog vs Digital and File Compression",
"difficulty": 9.20,
"challengeSeed": [ "challengeSeed": [
"133182587" "133182587"
], ],
@ -774,7 +754,6 @@
{ {
"id": "bd7129d89441eddfbeb5bddf", "id": "bd7129d89441eddfbeb5bddf",
"title": "Computer Security", "title": "Computer Security",
"difficulty": 9.21,
"challengeSeed": [ "challengeSeed": [
"133186284" "133186284"
], ],

View File

@ -1,11 +1,10 @@
{ {
"name": "HTML5 and CSS", "name": "HTML5 and CSS",
"order": 0.002, "order": 2,
"challenges": [ "challenges": [
{ {
"id": "bd7123c8c441eddfaeb5bdef", "id": "bd7123c8c441eddfaeb5bdef",
"title": "Say Hello to HTML Elements", "title": "Say Hello to HTML Elements",
"difficulty": 1.01,
"description": [ "description": [
"Welcome to Free Code Camp's first coding challenge!", "Welcome to Free Code Camp's first coding challenge!",
"You can edit <code>code</code> in your <code>text editor</code>, which we've embedded into this web page.", "You can edit <code>code</code> in your <code>text editor</code>, which we've embedded into this web page.",
@ -54,8 +53,9 @@
{ {
"id": "bad87fee1348bd9aedf0887a", "id": "bad87fee1348bd9aedf0887a",
"title": "Headline with the h2 Element", "title": "Headline with the h2 Element",
"difficulty": 1.02,
"description": [ "description": [
"Over the next few challenges, we'll build an HTML5 app that will look something like this:",
"<a href=\"http://i.imgur.com/jOc1JF1.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" src=\"http://i.imgur.com/jOc1JF1.png\" title=\"Click to enlarge\" alt=\"A screen shot of our finished Cat Photo App\"></a>",
"Add an <code>h2</code> tag that says \"CatPhotoApp\" to create a second HTML <code>element</code> below your \"Hello World\" <code>h1</code> element.", "Add an <code>h2</code> tag that says \"CatPhotoApp\" to create a second HTML <code>element</code> below your \"Hello World\" <code>h1</code> element.",
"The <code>h2</code> element you enter will create an <code>h2</code> element on the website.", "The <code>h2</code> element you enter will create an <code>h2</code> element on the website.",
"This element tells the browser how to render the text that it contains.", "This element tells the browser how to render the text that it contains.",
@ -98,7 +98,6 @@
{ {
"id": "bad87fee1348bd9aedf08801", "id": "bad87fee1348bd9aedf08801",
"title": "Inform with the Paragraph Element", "title": "Inform with the Paragraph Element",
"difficulty": 1.03,
"description": [ "description": [
"Create a <code>p</code> element below your <code>h2</code> element, and give it the text \"Hello Paragraph\".", "Create a <code>p</code> element below your <code>h2</code> element, and give it the text \"Hello Paragraph\".",
"<code>p</code> elements are the preferred element for normal-sized paragraph text on websites. P is short for \"paragraph\".", "<code>p</code> elements are the preferred element for normal-sized paragraph text on websites. P is short for \"paragraph\".",
@ -139,7 +138,6 @@
{ {
"id": "bad87fee1348bd9aedf08802", "id": "bad87fee1348bd9aedf08802",
"title": "Uncomment HTML", "title": "Uncomment HTML",
"difficulty": 1.04,
"description": [ "description": [
"Uncomment your <code>h1</code>, <code>h2</code> and <code>p</code> elements.", "Uncomment your <code>h1</code>, <code>h2</code> and <code>p</code> elements.",
"Commenting is a way that you can leave comments within your code without affecting the code itself.", "Commenting is a way that you can leave comments within your code without affecting the code itself.",
@ -189,7 +187,6 @@
{ {
"id": "bad87fee1348bd9aedf08804", "id": "bad87fee1348bd9aedf08804",
"title": "Comment out HTML", "title": "Comment out HTML",
"difficulty": 1.05,
"description": [ "description": [
"Comment out your <code>h1</code> element and your <code>p</code> element, but leave your <code>h2</code> element uncommented.", "Comment out your <code>h1</code> element and your <code>p</code> element, but leave your <code>h2</code> element uncommented.",
"Remember that in order to start a comment, you need to use <code>&#60;!--</code> and to end a comment, you need to use <code>--&#62;</code>.", "Remember that in order to start a comment, you need to use <code>&#60;!--</code> and to end a comment, you need to use <code>--&#62;</code>.",
@ -236,7 +233,6 @@
{ {
"id": "bad87fee1348bd9aedf08833", "id": "bad87fee1348bd9aedf08833",
"title": "Fill in the Blank with Placeholder Text", "title": "Fill in the Blank with Placeholder Text",
"difficulty": 1.06,
"description": [ "description": [
"Web developers traditionally use <code>lorem ipsum text</code> as placeholder text. It's called <code>lorem ipsum text</code> because those are the first two words of a famous passage by Cicero of Ancient Rome.", "Web developers traditionally use <code>lorem ipsum text</code> as placeholder text. It's called <code>lorem ipsum text</code> because those are the first two words of a famous passage by Cicero of Ancient Rome.",
"<code>lorem ipsum text</code> has been used as placeholder text by typesetters since the 16th century, and this tradition continues on the web.", "<code>lorem ipsum text</code> has been used as placeholder text by typesetters since the 16th century, and this tradition continues on the web.",
@ -283,7 +279,6 @@
{ {
"id": "bad87fed1348bd9aedf08833", "id": "bad87fed1348bd9aedf08833",
"title": "Delete HTML Elements", "title": "Delete HTML Elements",
"difficulty": 1.07,
"description": [ "description": [
"Delete your <code>h1</code> element so we can simplify our view.", "Delete your <code>h1</code> element so we can simplify our view.",
"Our phone doesn't have much vertical space.", "Our phone doesn't have much vertical space.",
@ -327,7 +322,6 @@
{ {
"id": "bad87fee1348bd9aedf08803", "id": "bad87fee1348bd9aedf08803",
"title": "Change the Color of Text", "title": "Change the Color of Text",
"difficulty": 1.08,
"description": [ "description": [
"Change your <code>h2</code> element's style so that its text color is red.", "Change your <code>h2</code> element's style so that its text color is red.",
"We can do this by changing the \"style\" of your <code>h2</code> element.", "We can do this by changing the \"style\" of your <code>h2</code> element.",
@ -369,7 +363,6 @@
{ {
"id": "bad87fee1348bd9aedf08805", "id": "bad87fee1348bd9aedf08805",
"title": "Use CSS Selectors to Style Elements", "title": "Use CSS Selectors to Style Elements",
"difficulty": 1.09,
"description": [ "description": [
"Delete your <code>h2</code> element's style attribute and instead create a CSS <code>style</code> element. Add the necessary CSS to turn all <code>h2</code> elements blue.", "Delete your <code>h2</code> element's style attribute and instead create a CSS <code>style</code> element. Add the necessary CSS to turn all <code>h2</code> elements blue.",
"With CSS, there are hundreds of CSS <code>properties</code> that you can use to change the way an element looks on your page.", "With CSS, there are hundreds of CSS <code>properties</code> that you can use to change the way an element looks on your page.",
@ -383,7 +376,7 @@
"assert(!$(\"h2\").attr(\"style\"), 'Remove the style attribute from your <code>h2</code> element.')", "assert(!$(\"h2\").attr(\"style\"), 'Remove the style attribute from your <code>h2</code> element.')",
"assert($(\"style\") && $(\"style\").length > 1, 'Create a <code>style</code> element.')", "assert($(\"style\") && $(\"style\").length > 1, 'Create a <code>style</code> element.')",
"assert($(\"h2\").css(\"color\") === \"rgb(0, 0, 255)\", 'Your <code>h2</code> element should be blue.')", "assert($(\"h2\").css(\"color\") === \"rgb(0, 0, 255)\", 'Your <code>h2</code> element should be blue.')",
"assert(editor.match(/<\\/style>/g) && editor.match(/<\\/style>/g).length === editor.match(/<style>/g).length, 'Make sure each of your <code>style</code> elements has a closing tag.')" "assert(editor.match(/<\\/style>/g) && editor.match(/<\\/style>/g).length === (editor.match(/<style((\\s)*((type|media|scoped|title|disabled)=\"[^\"]*\")?(\\s)*)*>/g) || []).length, 'Make sure all your <code>style</code> elements are valid and have a closing tag.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<h2 style=\"color: red\">CatPhotoApp</h2>", "<h2 style=\"color: red\">CatPhotoApp</h2>",
@ -424,7 +417,6 @@
{ {
"id": "bad87fee1348bd9aecf08806", "id": "bad87fee1348bd9aecf08806",
"title": "Use a CSS Class to Style an Element", "title": "Use a CSS Class to Style an Element",
"difficulty": 1.11,
"description": [ "description": [
"Create a CSS class called <code>red-text</code> and apply it to your <code>h2</code> element.", "Create a CSS class called <code>red-text</code> and apply it to your <code>h2</code> element.",
"Classes are reusable styles that can be added to HTML elements.", "Classes are reusable styles that can be added to HTML elements.",
@ -491,7 +483,6 @@
{ {
"id": "bad87fee1348bd9aefe08806", "id": "bad87fee1348bd9aefe08806",
"title": "Style Multiple Elements with a CSS Class", "title": "Style Multiple Elements with a CSS Class",
"difficulty": 1.12,
"description": [ "description": [
"Apply the <code>red-text</code> class to your <code>h2</code> and <code>p</code> elements.", "Apply the <code>red-text</code> class to your <code>h2</code> and <code>p</code> elements.",
"Remember that you can attach classes to HTML elements by using <code>class=\"your-class-here\"</code> within the relevant element's opening tag.", "Remember that you can attach classes to HTML elements by using <code>class=\"your-class-here\"</code> within the relevant element's opening tag.",
@ -540,7 +531,6 @@
{ {
"id": "bad87fee1348bd9aedf08806", "id": "bad87fee1348bd9aedf08806",
"title": "Change the Font Size of an Element", "title": "Change the Font Size of an Element",
"difficulty": 1.13,
"description": [ "description": [
"Create a second <code>p</code> element with the following <code>kitty ipsum text</code>: <code>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</code>", "Create a second <code>p</code> element with the following <code>kitty ipsum text</code>: <code>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</code>",
"Then, inside your <code>&#60;style&#62;</code> element, set the <code>font-size</code> of all <code>p</code> elements to 16 pixels.", "Then, inside your <code>&#60;style&#62;</code> element, set the <code>font-size</code> of all <code>p</code> elements to 16 pixels.",
@ -551,7 +541,8 @@
"assert($(\"p\").length > 1, 'You need 2 <code>p</code> elements with Kitty Ipsum text.')", "assert($(\"p\").length > 1, 'You need 2 <code>p</code> elements with Kitty Ipsum text.')",
"assert(editor.match(/<\\/p>/g) && editor.match(/<\\/p>/g).length === editor.match(/<p/g).length, 'Make sure each of your <code>p</code> elements has a closing tag.')", "assert(editor.match(/<\\/p>/g) && editor.match(/<\\/p>/g).length === editor.match(/<p/g).length, 'Make sure each of your <code>p</code> elements has a closing tag.')",
"assert.isTrue((/Purr\\s+jump\\s+eat/gi).test($(\"p\").text()), 'Your <code>p</code> element should contain the first few words of the provided additional <code>kitty ipsum text</code>.')", "assert.isTrue((/Purr\\s+jump\\s+eat/gi).test($(\"p\").text()), 'Your <code>p</code> element should contain the first few words of the provided additional <code>kitty ipsum text</code>.')",
"assert($(\"p\").css(\"font-size\") === \"16px\", 'Give your <code>p</code> elements the <code>font-size</code> of 16px.')" "assert($(\"p.red-text\").length === 2, 'Give each of your <code>p</code> elements the <code>red-text</code> class.')",
"assert($(\"p\").css(\"font-size\") === \"16px\", 'Give elements with the <code>red-text</code> class a <code>font-size</code> of 16px.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<style>", "<style>",
@ -592,7 +583,6 @@
{ {
"id": "bad87fee1348bd9aede08807", "id": "bad87fee1348bd9aede08807",
"title": "Set the Font Family of an Element", "title": "Set the Font Family of an Element",
"difficulty": 1.14,
"description": [ "description": [
"Make all of your <code>p</code> elements use the <code>Monospace</code> font.", "Make all of your <code>p</code> elements use the <code>Monospace</code> font.",
"You can set an element's font by using the <code>font-family</code> property.", "You can set an element's font by using the <code>font-family</code> property.",
@ -639,7 +629,6 @@
{ {
"id": "bad87fee1348bd9aedf08807", "id": "bad87fee1348bd9aedf08807",
"title": "Import a Google Font", "title": "Import a Google Font",
"difficulty": 1.15,
"description": [ "description": [
"Apply the <code>font-family</code> of <code>Lobster</code> to your <code>h2</code> element.", "Apply the <code>font-family</code> of <code>Lobster</code> to your <code>h2</code> element.",
"First, you'll need to make a <code>call</code> to Google to grab the <code>Lobster</code> font and load it into your HTML.", "First, you'll need to make a <code>call</code> to Google to grab the <code>Lobster</code> font and load it into your HTML.",
@ -693,7 +682,6 @@
{ {
"id": "bad87fee1348bd9aedf08808", "id": "bad87fee1348bd9aedf08808",
"title": "Specify How Fonts Should Degrade", "title": "Specify How Fonts Should Degrade",
"difficulty": 1.16,
"description": [ "description": [
"There are several default fonts that are available in all browsers. These include <code>Monospace</code>, <code>Serif</code> and <code>Sans-Serif</code>. Leave <code>Lobster</code> as the font-family for your <code>h2</code> elements. Make them \"degrade\" to <code>Monospace</code> when <code>Lobster</code> isn't available.", "There are several default fonts that are available in all browsers. These include <code>Monospace</code>, <code>Serif</code> and <code>Sans-Serif</code>. Leave <code>Lobster</code> as the font-family for your <code>h2</code> elements. Make them \"degrade\" to <code>Monospace</code> when <code>Lobster</code> isn't available.",
"For example, if you wanted an element to use the <code>Helvetica</code> font, but also degrade to the <code>Sans-Serif</code> font when <code>Helvetica</code> wasn't available, you could use this CSS style: <code>p { font-family: Helvetica, Sans-Serif; }</code>.", "For example, if you wanted an element to use the <code>Helvetica</code> font, but also degrade to the <code>Sans-Serif</code> font when <code>Helvetica</code> wasn't available, you could use this CSS style: <code>p { font-family: Helvetica, Sans-Serif; }</code>.",
@ -751,7 +739,6 @@
{ {
"id": "bad87fee1348bd9aedf08812", "id": "bad87fee1348bd9aedf08812",
"title": "Add Images to your Website", "title": "Add Images to your Website",
"difficulty": 1.17,
"description": [ "description": [
"You can add images to your website by using the <code>img</code> element, and point to a specific image's URL using the <code>src</code> attribute.", "You can add images to your website by using the <code>img</code> element, and point to a specific image's URL using the <code>src</code> attribute.",
"An example of this would be <code>&#60img src=\"http://www.your-image-source.com/your-image.jpg\"&#62</code>. Note that in most cases, <code>img</code> elements are self-closing.", "An example of this would be <code>&#60img src=\"http://www.your-image-source.com/your-image.jpg\"&#62</code>. Note that in most cases, <code>img</code> elements are self-closing.",
@ -806,7 +793,6 @@
{ {
"id": "bad87fee1348bd9acdf08812", "id": "bad87fee1348bd9acdf08812",
"title": "Size your Images", "title": "Size your Images",
"difficulty": 1.18,
"description": [ "description": [
"CSS has a property called <code>width</code> that controls an element's width. Just like with fonts, we'll use <code>px</code> (pixels) to specify the image's width.", "CSS has a property called <code>width</code> that controls an element's width. Just like with fonts, we'll use <code>px</code> (pixels) to specify the image's width.",
"For example, if we wanted to create a CSS class called <code>larger-image</code> that gave HTML elements a width of 500 pixels, we'd use: <code>&#60;style&#62; .larger-image { width: 500px; } &#60;/style&#62;</code>.", "For example, if we wanted to create a CSS class called <code>larger-image</code> that gave HTML elements a width of 500 pixels, we'd use: <code>&#60;style&#62; .larger-image { width: 500px; } &#60;/style&#62;</code>.",
@ -862,17 +848,17 @@
{ {
"id": "bad87fee1348bd9bedf08813", "id": "bad87fee1348bd9bedf08813",
"title": "Add Borders Around your Elements", "title": "Add Borders Around your Elements",
"difficulty": 1.19,
"description": [ "description": [
"CSS borders have properties like <code>style</code>, <code>color</code> and <code>width</code>.", "CSS borders have properties like <code>style</code>, <code>color</code> and <code>width</code>.",
"For example, if we wanted to create a red, 5 pixel border around an HTML element, we could use this class: <code>&#60;style&#62; .thin-red-border { border-color: red; border-width: 5px; border-style: solid; } &#60;/style&#62;</code>.", "For example, if we wanted to create a red, 5 pixel border around an HTML element, we could use this class: <code>&#60;style&#62; .thin-red-border { border-color: red; border-width: 5px; border-style: solid; } &#60;/style&#62;</code>.",
"Create a class called <code>thick-green-border</code> that puts a 10-pixel-wide green border with a style of <code>solid</code> around an HTML element, and apply that class to your cat photo." "Create a class called <code>thick-green-border</code> that puts a 10-pixel-wide green border with a style of <code>solid</code> around an HTML element, and apply that class to your cat photo.",
"Remember that you can apply multiple classes to an element by separating each class with a space within its <code>class</code> attribute. For example: <code>&lt;img class=\"class1 class2\"&gt;</code>"
], ],
"tests": [ "tests": [
"assert($(\"img\").hasClass(\"smaller-image\"), 'Your <code>img</code> element should have the class <code>smaller-image</code>.')", "assert($(\"img\").hasClass(\"smaller-image\"), 'Your <code>img</code> element should have the class <code>smaller-image</code>.')",
"assert($(\"img\").hasClass(\"thick-green-border\"), 'Your <code>img</code> element should have the class <code>thick-green-border</code>.')", "assert($(\"img\").hasClass(\"thick-green-border\"), 'Your <code>img</code> element should have the class <code>thick-green-border</code>.')",
"assert($(\"img\").hasClass(\"thick-green-border\") && parseInt($(\"img\").css(\"border-top-width\")), 'Give your image a border width of <code>10px</code>.')", "assert($(\"img\").hasClass(\"thick-green-border\") && parseInt($(\"img\").css(\"border-top-width\"), 10) === 10, 'Give your image a border width of <code>10px</code>.')",
"assert(new RegExp(\"solid\", \"gi\").test(editor), 'Give your image a border style of <code>solid</code>.')", "assert($(\"img\").css(\"border-right-style\") === \"solid\", 'Give your image a border style of <code>solid</code>.')",
"assert($(\"img\").css(\"border-left-color\") === \"rgb(0, 128, 0)\", 'The border around your <code>img</code> element should be green.')" "assert($(\"img\").css(\"border-left-color\") === \"rgb(0, 128, 0)\", 'The border around your <code>img</code> element should be green.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -925,7 +911,6 @@
{ {
"id": "bad87fee1348bd9aedf08814", "id": "bad87fee1348bd9aedf08814",
"title": "Add Rounded Corners with a Border Radius", "title": "Add Rounded Corners with a Border Radius",
"difficulty": 1.20,
"description": [ "description": [
"Your cat photo currently has sharp corners. We can round out those corners with a CSS property called <code>border-radius</code>.", "Your cat photo currently has sharp corners. We can round out those corners with a CSS property called <code>border-radius</code>.",
"You can specify a <code>border-radius</code> with pixels. This will affect how rounded the corners are. Add this property to your <code>thick-green-border</code> class and set it to <code>10px</code>.", "You can specify a <code>border-radius</code> with pixels. This will affect how rounded the corners are. Add this property to your <code>thick-green-border</code> class and set it to <code>10px</code>.",
@ -991,7 +976,6 @@
{ {
"id": "bad87fee1348bd9aedf08815", "id": "bad87fee1348bd9aedf08815",
"title": "Make Circular Images with a Border Radius", "title": "Make Circular Images with a Border Radius",
"difficulty": 1.21,
"description": [ "description": [
"In addition to pixels, you can also specify a <code>border-radius</code> using a percentage.", "In addition to pixels, you can also specify a <code>border-radius</code> using a percentage.",
"Give your cat photo a <code>border-radius</code> of <code>50%</code>." "Give your cat photo a <code>border-radius</code> of <code>50%</code>."
@ -1056,11 +1040,10 @@
{ {
"id": "bad87fee1348bd9aedf08816", "id": "bad87fee1348bd9aedf08816",
"title": "Link to External Pages with Anchor Elements", "title": "Link to External Pages with Anchor Elements",
"difficulty": 1.22,
"description": [ "description": [
"<code>a</code> elements, also known as <code>anchor</code> elements, are used to link to content outside of the current page.", "<code>a</code> elements, also known as <code>anchor</code> elements, are used to link to content outside of the current page.",
"Here's a diagram of an <code>a</code> element. In this case, the <code>a</code> element is used in the middle of a paragraph element, which means the link will appear in the middle of a sentence.", "Here's a diagram of an <code>a</code> element. In this case, the <code>a</code> element is used in the middle of a paragraph element, which means the link will appear in the middle of a sentence.",
"<img class=\"img-responsive\" alt=\"a diagram of how anchor tags are composed with the same text as on the following line\" src=\"http://i.imgur.com/hviuZwe.png\">", "<a href=\"http://i.imgur.com/hviuZwe.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" title=\"Click to enlarge\" alt=\"a diagram of how anchor tags are composed with the same text as on the following line\" src=\"http://i.imgur.com/hviuZwe.png\"></a>",
"Here's an example: <code>&#60;p&#62;Here's a &#60;a href=\"http://freecodecamp.com\"&#62; link to Free Code Camp&#60;/a&#62; for you to follow.&#60;/p&#62;</code>.", "Here's an example: <code>&#60;p&#62;Here's a &#60;a href=\"http://freecodecamp.com\"&#62; link to Free Code Camp&#60;/a&#62; for you to follow.&#60;/p&#62;</code>.",
"Create an <code>a</code> element that links to <code>http://freecatphotoapp.com</code> and has \"cat photos\" as its <code>anchor text</code>." "Create an <code>a</code> element that links to <code>http://freecatphotoapp.com</code> and has \"cat photos\" as its <code>anchor text</code>."
], ],
@ -1127,20 +1110,20 @@
{ {
"id": "bad87fee1348bd9aede08817", "id": "bad87fee1348bd9aede08817",
"title": "Nest an Anchor Element within a Paragraph", "title": "Nest an Anchor Element within a Paragraph",
"difficulty": 1.23,
"description": [ "description": [
"Again, here's a diagram of an <code>a</code> element for your reference:", "Again, here's a diagram of an <code>a</code> element for your reference:",
"<img class=\"img-responsive\" alt=\"a diagram of how anchor tags are composed with the same text as on the following line\" src=\"http://i.imgur.com/hviuZwe.png\">", "<a href=\"http://i.imgur.com/hviuZwe.png\" data-lightbox=\"img-enlarge\"><img class=\"img-responsive\" title=\"Click to enlarge\" alt=\"a diagram of how anchor tags are composed with the same text as on the following line\" src=\"http://i.imgur.com/hviuZwe.png\"></a>",
"Here's an example: <code>&#60;p&#62;Here's a &#60;a href=\"http://freecodecamp.com\"&#62; link to Free Code Camp&#60;/a&#62; for you to follow.&#60;/p&#62;</code>.", "Here's an example: <code>&#60;p&#62;Here's a &#60;a href=\"http://freecodecamp.com\"&#62; link to Free Code Camp&#60;/a&#62; for you to follow.&#60;/p&#62;</code>.",
"<code>Nesting</code> just means putting one element inside of another element.", "<code>Nesting</code> just means putting one element inside of another element.",
"Now nest your existing <code>a</code> element within a new <code>p</code> element so that the surrounding paragraph says \"click here for cat photos\", but where only \"cat photos\" is a link, and the rest of the text is rest is plain text." "Now nest your existing <code>a</code> element within a new <code>p</code> element so that the surrounding paragraph says \"View more cat photos\", but where only \"cat photos\" is a link, and the rest of the text is plain text."
], ],
"tests": [ "tests": [
"assert($(\"a\").attr(\"href\").match(/freecatphotoapp.com/gi).length > 0, 'You need an <code>a</code> element that links to \"freecatphotoapp.com\".')", "assert($(\"a\").attr(\"href\").match(/freecatphotoapp.com/gi).length > 0, 'You need an <code>a</code> element that links to \"freecatphotoapp.com\".')",
"assert($(\"a\").text().match(/cat\\sphotos/gi).length > 0, 'Your <code>a</code> element should have the anchor text of \"cat photos\"')", "assert($(\"a\").text().match(/cat\\sphotos/gi), 'Your <code>a</code> element should have the anchor text of \"cat photos\"')",
"assert($(\"p\") && $(\"p\").length > 2, 'Create a new <code>p</code> element around your <code>a</code> element.')", "assert($(\"p\") && $(\"p\").length > 2, 'Create a new <code>p</code> element around your <code>a</code> element.')",
"assert($(\"a[href=\\\"http://www.freecatphotoapp.com\\\"]\").parent().is(\"p\"), 'Your <code>a</code> element should be nested within your new <code>p</code> element.')", "assert($(\"a[href=\\\"http://www.freecatphotoapp.com\\\"]\").parent().is(\"p\"), 'Your <code>a</code> element should be nested within your new <code>p</code> element.')",
"assert($(\"p\").text().match(/click\\shere\\sfor/gi), 'Your <code>p</code> element should have the text \"click here for\".')", "assert($(\"p\").text().match(/^View\\smore\\s/gi), 'Your <code>p</code> element should have the text \"View more \" (with a space after it).')",
"assert(!$(\"a\").text().match(/View\\smore/gi), 'Your <code>a</code> element should <em>not</em> have the text \"View more\".')",
"assert(editor.match(/<\\/p>/g) && editor.match(/<p/g) && editor.match(/<\\/p>/g).length === editor.match(/<p/g).length, 'Make sure each of your <code>p</code> elements has a closing tag.')", "assert(editor.match(/<\\/p>/g) && editor.match(/<p/g) && editor.match(/<\\/p>/g).length === editor.match(/<p/g).length, 'Make sure each of your <code>p</code> elements has a closing tag.')",
"assert(editor.match(/<\\/a>/g) && editor.match(/<a/g) && editor.match(/<\\/a>/g).length === editor.match(/<a/g).length, 'Make sure each of your <code>a</code> elements has a closing tag.')" "assert(editor.match(/<\\/a>/g) && editor.match(/<a/g) && editor.match(/<\\/a>/g).length === editor.match(/<a/g).length, 'Make sure each of your <code>a</code> elements has a closing tag.')"
], ],
@ -1203,7 +1186,6 @@
{ {
"id": "bad87fee1348bd9aedf08817", "id": "bad87fee1348bd9aedf08817",
"title": "Make Dead Links using the Hash Symbol", "title": "Make Dead Links using the Hash Symbol",
"difficulty": 1.24,
"description": [ "description": [
"Sometimes you want to add <code>a</code> elements to your website before you know where they will link.", "Sometimes you want to add <code>a</code> 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 <code>jQuery</code>, which we'll learn about later.", "This is also handy when you're changing the behavior of a link using <code>jQuery</code>, which we'll learn about later.",
@ -1272,7 +1254,6 @@
{ {
"id": "bad87fee1348bd9aedf08820", "id": "bad87fee1348bd9aedf08820",
"title": "Turn an Image into a Link", "title": "Turn an Image into a Link",
"difficulty": 1.25,
"description": [ "description": [
"You can make elements into links by nesting them within an <code>a</code> element.", "You can make elements into links by nesting them within an <code>a</code> element.",
"Nest your image within an <code>a</code> element. Here's an example: <code>&#60;a href=\"#\"&#62;&#60;img src=\"http://bit.ly/fcc-running-cats\"/&#62;&#60;/a&#62;</code>.", "Nest your image within an <code>a</code> element. Here's an example: <code>&#60;a href=\"#\"&#62;&#60;img src=\"http://bit.ly/fcc-running-cats\"/&#62;&#60;/a&#62;</code>.",
@ -1345,7 +1326,6 @@
{ {
"id": "bad87fee1348bd9aedf08818", "id": "bad87fee1348bd9aedf08818",
"title": "Add Alt Text to an Image for Accessibility", "title": "Add Alt Text to an Image for Accessibility",
"difficulty": 1.26,
"description": [ "description": [
"<code>alt</code> attributes, also known as <code>alt text</code>, are what browsers will display if they fail to load the image. <code>alt</code> attributes are also important for blind or visually impaired users to understand what an image portrays. And search engines also look at <code>alt</code> attributes.", "<code>alt</code> attributes, also known as <code>alt text</code>, are what browsers will display if they fail to load the image. <code>alt</code> attributes are also important for blind or visually impaired users to understand what an image portrays. And search engines also look at <code>alt</code> attributes.",
"In short, every image should have an <code>alt</code> attribute!", "In short, every image should have an <code>alt</code> attribute!",
@ -1416,7 +1396,6 @@
{ {
"id": "bad87fee1348bd9aedf08827", "id": "bad87fee1348bd9aedf08827",
"title": "Create a Bulleted Unordered List", "title": "Create a Bulleted Unordered List",
"difficulty": 1.27,
"description": [ "description": [
"HTML has a special element for creating <code>unordered lists</code>, or bullet point-style lists.", "HTML has a special element for creating <code>unordered lists</code>, or bullet point-style lists.",
"Unordered lists start with a <code>&#60;ul&#62;</code> element. Then they contain some number of <code>&#60;li&#62;</code> elements.", "Unordered lists start with a <code>&#60;ul&#62;</code> element. Then they contain some number of <code>&#60;li&#62;</code> elements.",
@ -1494,7 +1473,6 @@
{ {
"id": "bad87fee1348bd9aedf08828", "id": "bad87fee1348bd9aedf08828",
"title": "Create an Ordered List", "title": "Create an Ordered List",
"difficulty": 1.28,
"description": [ "description": [
"HTML has a special element for creating <code>ordered lists</code>, or numbered-style lists.", "HTML has a special element for creating <code>ordered lists</code>, or numbered-style lists.",
"Ordered lists start with a <code>&#60;ol&#62;</code> element. Then they contain some number of <code>&#60;li&#62;</code> elements.", "Ordered lists start with a <code>&#60;ol&#62;</code> element. Then they contain some number of <code>&#60;li&#62;</code> elements.",
@ -1580,7 +1558,6 @@
{ {
"id": "bad87fee1348bd9aedf08829", "id": "bad87fee1348bd9aedf08829",
"title": "Create a Text Field", "title": "Create a Text Field",
"difficulty": 1.29,
"description": [ "description": [
"Now let's create a web <code>form</code>.", "Now let's create a web <code>form</code>.",
"Text inputs are a convenient way to get input from your user.", "Text inputs are a convenient way to get input from your user.",
@ -1659,7 +1636,6 @@
{ {
"id": "bad87fee1348bd9aedf08830", "id": "bad87fee1348bd9aedf08830",
"title": "Add Placeholder Text to a Text Field", "title": "Add Placeholder Text to a Text Field",
"difficulty": 1.30,
"description": [ "description": [
"Your placeholder text is what appears in your text <code>input</code> before your user has inputed anything.", "Your placeholder text is what appears in your text <code>input</code> before your user has inputed anything.",
"You can create placeholder text like so: <code>&#60;input type=\"text\" placeholder=\"this is placeholder text\"&#62;</code>.", "You can create placeholder text like so: <code>&#60;input type=\"text\" placeholder=\"this is placeholder text\"&#62;</code>.",
@ -1739,7 +1715,6 @@
{ {
"id": "bad87fee1348bd9aede08830", "id": "bad87fee1348bd9aede08830",
"title": "Create a Form Element", "title": "Create a Form Element",
"difficulty": 1.31,
"description": [ "description": [
"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 <code>form</code> 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 <code>form</code> element.",
"For example: <code>&#60;form action=\"/url-where-you-want-to-submit-form-data\"&#62;&#60;/form&#62;</code>.", "For example: <code>&#60;form action=\"/url-where-you-want-to-submit-form-data\"&#62;&#60;/form&#62;</code>.",
@ -1747,9 +1722,8 @@
], ],
"tests": [ "tests": [
"assert($(\"form\") && $(\"form\").children(\"input\") && $(\"form\").children(\"input\").length > 0, 'Nest your text input element within a <code>form</code> element.')", "assert($(\"form\") && $(\"form\").children(\"input\") && $(\"form\").children(\"input\").length > 0, 'Nest your text input element within a <code>form</code> element.')",
"assert($(\"form\").attr(\"action\"), 'Your <code>form</code> element should have an <code>action</code> attribute.')", "assert($(\"form\").attr(\"action\") === \"/submit-cat-photo\", 'Make sure your <code>form</code> has an <code>action</code> attribute which is set to <code>/submit-cat-photo</code>.')",
"assert(editor.match(/<\\/form>/g) && editor.match(/<form/g) && editor.match(/<\\/form>/g).length === editor.match(/<form/g).length, 'Make sure your <code>form</code> element has a closing tag.')", "assert(editor.match(/<\\/form>/g) && editor.match(/<form/g) && editor.match(/<\\/form>/g).length === editor.match(/<form/g).length, 'Make sure your <code>form</code> element has a closing tag.')"
"assert(editor.match(/\\/submit-cat-photo/ig), 'Make sure your <code>form</code> action is set to <code>/submit-cat-photo</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">", "<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">",
@ -1821,7 +1795,6 @@
{ {
"id": "bad87fee1348bd9aedd08830", "id": "bad87fee1348bd9aedd08830",
"title": "Add a Submit Button to a Form", "title": "Add a Submit Button to a Form",
"difficulty": 1.32,
"description": [ "description": [
"Let's add a <code>submit</code> button to your form. Clicking this button will send the data from your form to the URL you specified with your form's <code>action</code> attribute.", "Let's add a <code>submit</code> button to your form. Clicking this button will send the data from your form to the URL you specified with your form's <code>action</code> attribute.",
"Here's an example submit button: <code>&#60;button type=\"submit\"&#62;this button submits the form&#60;/button&#62;</code>.", "Here's an example submit button: <code>&#60;button type=\"submit\"&#62;this button submits the form&#60;/button&#62;</code>.",
@ -1905,7 +1878,6 @@
{ {
"id": "bad87fee1348bd9aedc08830", "id": "bad87fee1348bd9aedc08830",
"title": "Use HTML5 to Require a Field", "title": "Use HTML5 to Require a Field",
"difficulty": 1.33,
"description": [ "description": [
"You can require specific form fields so that your user will not be able to submit your form until he or she has filled them out.", "You can require specific form fields so that your user will not be able to submit your form until he or she has filled them out.",
"For example, if you wanted to make a text input field required, you can just add the word <code>required</code> within your <code>input</code> element, you would use: <code>&#60;input type=\"text\" required&#62;</code>.", "For example, if you wanted to make a text input field required, you can just add the word <code>required</code> within your <code>input</code> element, you would use: <code>&#60;input type=\"text\" required&#62;</code>.",
@ -1987,7 +1959,6 @@
{ {
"id": "bad87fee1348bd9aedf08834", "id": "bad87fee1348bd9aedf08834",
"title": "Create a Set of Radio Buttons", "title": "Create a Set of Radio Buttons",
"difficulty": 1.34,
"description": [ "description": [
"You can use <code>radio buttons</code> for questions where you want the user to only give you one answer.", "You can use <code>radio buttons</code> for questions where you want the user to only give you one answer.",
"Radio buttons are a type of <code>input</code>.", "Radio buttons are a type of <code>input</code>.",
@ -1998,8 +1969,8 @@
], ],
"tests": [ "tests": [
"assert($('input[type=\"radio\"]').length > 1, 'Your page should have two radio button elements.')", "assert($('input[type=\"radio\"]').length > 1, 'Your page should have two radio button elements.')",
"assert($('input[type=\"radio\"]:nth-child(1)').attr('name') === 'indoor-outdoor', 'Give your radio buttons the <code>name</code> attribute of <code>indoor-outdoor</code>.')", "assert($('label > input[type=\"radio\"]').filter(\"[name='indoor-outdoor']\").length > 1, 'Give your radio buttons the <code>name</code> attribute of <code>indoor-outdoor</code>.')",
"assert($(\"label\").length > 1, 'Each of your two radio button elements should be nested in a <code>label</code> element.')", "assert($('label > input[type=\"radio\"]:only-child').length > 1, 'Each of your two radio button elements should be nested in its own <code>label</code> element.')",
"assert(editor.match(/<\\/label>/g) && editor.match(/<label/g) && editor.match(/<\\/label>/g).length === editor.match(/<label/g).length, 'Make sure each of your <code>label</code> elements has a closing tag.')", "assert(editor.match(/<\\/label>/g) && editor.match(/<label/g) && editor.match(/<\\/label>/g).length === editor.match(/<label/g).length, 'Make sure each of your <code>label</code> elements has a closing tag.')",
"assert($(\"label\").text().match(/indoor/gi), 'One of your radio buttons should have the label <code>indoor</code>.')", "assert($(\"label\").text().match(/indoor/gi), 'One of your radio buttons should have the label <code>indoor</code>.')",
"assert($(\"label\").text().match(/outdoor/gi), 'One of your radio buttons should have the label <code>outdoor</code>.')" "assert($(\"label\").text().match(/outdoor/gi), 'One of your radio buttons should have the label <code>outdoor</code>.')"
@ -2080,7 +2051,6 @@
{ {
"id": "bad87fee1348bd9aedf08835", "id": "bad87fee1348bd9aedf08835",
"title": "Create a Set of Checkboxes", "title": "Create a Set of Checkboxes",
"difficulty": 1.35,
"description": [ "description": [
"Forms commonly use <code>checkboxes</code> for questions that may have more than one answer.", "Forms commonly use <code>checkboxes</code> for questions that may have more than one answer.",
"Checkboxes are a type of <code>input</code>.", "Checkboxes are a type of <code>input</code>.",
@ -2091,9 +2061,9 @@
], ],
"tests": [ "tests": [
"assert($('input[type=\"checkbox\"]').length > 2, 'Your page should have three checkbox elements.')", "assert($('input[type=\"checkbox\"]').length > 2, 'Your page should have three checkbox elements.')",
"assert($('label:has(input[type=\"checkbox\"])').length > 2, 'Each of your three checkbox elements should be nested in its own <code>label</code> element.')", "assert($('label > input[type=\"checkbox\"]:only-child').length > 2, 'Each of your three checkbox elements should be nested in its own <code>label</code> element.')",
"assert(editor.match(/<\\/label>/g) && editor.match(/<label/g) && editor.match(/<\\/label>/g).length === editor.match(/<label/g).length, \"Make sure each of your <code>label</code> elements has a closing tag.\")", "assert(editor.match(/<\\/label>/g) && editor.match(/<label/g) && editor.match(/<\\/label>/g).length === editor.match(/<label/g).length, \"Make sure each of your <code>label</code> elements has a closing tag.\")",
"assert($('input[type=\"checkbox\"]:nth-child(1)').attr(\"name\") === \"personality\", 'Give your checkboxes buttons the <code>name</code> attribute of <code>personality</code>.')" "assert($('label > input[type=\"checkbox\"]').filter(\"[name='personality']\").length > 2, 'Give your checkboxes the <code>name</code> attribute of <code>personality</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">", "<link href=\"http://fonts.googleapis.com/css?family=Lobster\" rel=\"stylesheet\" type=\"text/css\">",
@ -2170,7 +2140,6 @@
{ {
"id": "bad87fee1348bd9aedd08835", "id": "bad87fee1348bd9aedd08835",
"title": "Check Radio Buttons and Checkboxes by Default", "title": "Check Radio Buttons and Checkboxes by Default",
"difficulty": 1.37,
"description": [ "description": [
"You can set a checkbox or radio button to be checked by default using the <code>checked</code> attribute.", "You can set a checkbox or radio button to be checked by default using the <code>checked</code> attribute.",
"To do this, just add the word \"checked\" to the inside of an input element. For example, <code>&#60;input type=\"radio\" name=\"test-name\" checked&#62;</code>.", "To do this, just add the word \"checked\" to the inside of an input element. For example, <code>&#60;input type=\"radio\" name=\"test-name\" checked&#62;</code>.",
@ -2258,7 +2227,6 @@
{ {
"id": "bad87fee1348bd9aede08835", "id": "bad87fee1348bd9aede08835",
"title": "Nest Many Elements within a Single Div Element", "title": "Nest Many Elements within a Single Div Element",
"difficulty": 1.38,
"description": [ "description": [
"The <code>div</code> element, also known as a division element, is a general purpose container for other elements.", "The <code>div</code> element, also known as a division element, is a general purpose container for other elements.",
"The <code>div</code> element is probably the most commonly used HTML element of all. It's useful for passing the CSS of its own class declarations down to all the elements that it contains.", "The <code>div</code> element is probably the most commonly used HTML element of all. It's useful for passing the CSS of its own class declarations down to all the elements that it contains.",
@ -2353,7 +2321,6 @@
{ {
"id": "bad87fed1348bd9aede07836", "id": "bad87fed1348bd9aede07836",
"title": "Give a Background Color to a Div Element", "title": "Give a Background Color to a Div Element",
"difficulty": 1.39,
"description": [ "description": [
"You can set an element's background color with the <code>background-color</code> property.", "You can set an element's background color with the <code>background-color</code> property.",
"For example, if you wanted an element's background color to be <code>green</code>, you'd use <code>.green-background { background-color: green; }</code> within your <code>style</code> element.", "For example, if you wanted an element's background color to be <code>green</code>, you'd use <code>.green-background { background-color: green; }</code> within your <code>style</code> element.",
@ -2440,7 +2407,6 @@
{ {
"id": "bad87eee1348bd9aede07836", "id": "bad87eee1348bd9aede07836",
"title": "Set the ID of an Element", "title": "Set the ID of an Element",
"difficulty": 1.391,
"description": [ "description": [
"In addition to classes, each HTML element can also have an <code>id</code> attribute.", "In addition to classes, each HTML element can also have an <code>id</code> attribute.",
"There are several benefits to using <code>id</code> attributes, and you'll learn more about them once you start using jQuery.", "There are several benefits to using <code>id</code> attributes, and you'll learn more about them once you start using jQuery.",
@ -2531,7 +2497,6 @@
{ {
"id": "bad87dee1348bd9aede07836", "id": "bad87dee1348bd9aede07836",
"title": "Use an ID Attribute to Style an Element", "title": "Use an ID Attribute to Style an Element",
"difficulty": 1.392,
"description": [ "description": [
"One cool thing about <code>id</code> attributes is that, like classes, you can style them using CSS.", "One cool thing about <code>id</code> attributes is that, like classes, you can style them using CSS.",
"Here's an example of how you can take your element with the <code>id</code> attribute of <code>cat-photo-element</code> and give it the background color of green. In your <code>style</code> element: <code>#cat-photo-element { background-color: green; }</code>", "Here's an example of how you can take your element with the <code>id</code> attribute of <code>cat-photo-element</code> and give it the background color of green. In your <code>style</code> element: <code>#cat-photo-element { background-color: green; }</code>",
@ -2624,7 +2589,6 @@
{ {
"id": "bad88fee1348bd9aedf08825", "id": "bad88fee1348bd9aedf08825",
"title": "Adjusting the Padding of an Element", "title": "Adjusting the Padding of an Element",
"difficulty": 1.40,
"description": [ "description": [
"You may have already noticed this, but all HTML elements are essentially little rectangles.", "You may have already noticed this, but all HTML elements are essentially little rectangles.",
"Three important properties control the space that surrounds each HTML element: <code>padding</code>, <code>margin</code>, and <code>border</code>.", "Three important properties control the space that surrounds each HTML element: <code>padding</code>, <code>margin</code>, and <code>border</code>.",
@ -2695,7 +2659,6 @@
{ {
"id": "bad87fee1348bd9aedf08822", "id": "bad87fee1348bd9aedf08822",
"title": "Adjust the Margin of an Element", "title": "Adjust the Margin of an Element",
"difficulty": 1.41,
"description": [ "description": [
"An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.", "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
"Here, we can see that the green box and the red box are nested within the yellow box. Note that the red box has more <code>margin</code> than the green box, making it appear smaller.", "Here, we can see that the green box and the red box are nested within the yellow box. Note that the red box has more <code>margin</code> than the green box, making it appear smaller.",
@ -2766,7 +2729,6 @@
{ {
"id": "bad87fee1348bd9aedf08823", "id": "bad87fee1348bd9aedf08823",
"title": "Add a Negative Margin to an Element", "title": "Add a Negative Margin to an Element",
"difficulty": 1.42,
"description": [ "description": [
"An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.", "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
"If you set an element's <code>margin</code> to a negative value, the element will grow larger.", "If you set an element's <code>margin</code> to a negative value, the element will grow larger.",
@ -2836,17 +2798,16 @@
{ {
"id": "bad87fee1348bd9aedf08824", "id": "bad87fee1348bd9aedf08824",
"title": "Add Different Padding to Each Side of an Element", "title": "Add Different Padding to Each Side of an Element",
"difficulty": 1.43,
"description": [ "description": [
"Sometimes you will want to customize an element so that it has different <code>padding</code> on each of its sides.", "Sometimes you will want to customize an element so that it has different <code>padding</code> on each of its sides.",
"CSS allows you to control the <code>padding</code> of an element on all four sides with <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> properties.", "CSS allows you to control the <code>padding</code> of an element on all four sides with <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> properties.",
"Give the green box a <code>padding</code> of <code>40px</code> on its top and left side, but only <code>20px</code> on its bottom and right side." "Give the green box a <code>padding</code> of <code>40px</code> on its top and left side, but only <code>20px</code> on its bottom and right side."
], ],
"tests": [ "tests": [
"assert($(\".green-box\").css(\"padding-top\") === \"40px\", 'Your <code>green-box</code> class should give the top of elements <code>40px</code> of <code>padding</code>.')", "assert($(\".green-box\").css(\"padding-top\") === \"40px\", 'Your <code>green-box</code> class should give the top of the elements <code>40px</code> of <code>padding</code>.')",
"assert($(\".green-box\").css(\"padding-left\") === \"40px\", 'Your <code>green-box</code> class should give the left of elements <code>40px</code> of <code>padding</code>.')", "assert($(\".green-box\").css(\"padding-left\") === \"40px\", 'Your <code>green-box</code> class should give the left of the elements <code>40px</code> of <code>padding</code>.')",
"assert($(\".green-box\").css(\"padding-right\") === \"20px\", 'Your <code>green-box</code> class should give the right of elements <code>20px</code> of <code>padding</code>.')", "assert($(\".green-box\").css(\"padding-right\") === \"20px\", 'Your <code>green-box</code> class should give the right of the elements <code>20px</code> of <code>padding</code>.')",
"assert($(\".green-box\").css(\"padding-bottom\") === \"20px\", 'Your <code>green-box</code> class should give the bottom of elements <code>20px</code> of <code>padding</code>.')" "assert($(\".green-box\").css(\"padding-bottom\") === \"20px\", 'Your <code>green-box</code> class should give the bottom of the elements <code>20px</code> of <code>padding</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"<style>", "<style>",
@ -2908,7 +2869,6 @@
{ {
"id": "bad87fee1248bd9aedf08824", "id": "bad87fee1248bd9aedf08824",
"title": "Add Different Margins to Each Side of an Element", "title": "Add Different Margins to Each Side of an Element",
"difficulty": 1.44,
"description": [ "description": [
"Give the green box a <code>margin</code> of <code>40px</code> on its top and left side, but only <code>20px</code> on its bottom and right side.", "Give the green box a <code>margin</code> of <code>40px</code> on its top and left side, but only <code>20px</code> on its bottom and right side.",
"Sometimes you will want to customize an element so that it has a different <code>margin</code> on each of its sides.", "Sometimes you will want to customize an element so that it has a different <code>margin</code> on each of its sides.",
@ -2979,7 +2939,6 @@
{ {
"id": "bad87fee1348bd9aedf08826", "id": "bad87fee1348bd9aedf08826",
"title": "Use Clockwise Notation to Specify the Padding of an Element", "title": "Use Clockwise Notation to Specify the Padding of an Element",
"difficulty": 1.44,
"description": [ "description": [
"Instead of specifying an element's <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> properties, you can specify them all in one line, like this: <code>padding: 10px 20px 10px 20px;</code>.", "Instead of specifying an element's <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> properties, you can specify them all in one line, like this: <code>padding: 10px 20px 10px 20px;</code>.",
"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.", "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.",
@ -3048,7 +3007,6 @@
{ {
"id": "bad87fee1348bd9afdf08726", "id": "bad87fee1348bd9afdf08726",
"title": "Use Clockwise Notation to Specify the Margin of an Element", "title": "Use Clockwise Notation to Specify the Margin of an Element",
"difficulty": 1.45,
"description": [ "description": [
"Let's try this again, but with <code>margin</code> this time.", "Let's try this again, but with <code>margin</code> this time.",
"Instead of specifying an element's <code>margin-top</code>, <code>margin-right</code>, <code>margin-bottom</code>, and <code>margin-left</code> properties, you can specify them all in one line, like this: <code>margin: 10px 20px 10px 20px;</code>.", "Instead of specifying an element's <code>margin-top</code>, <code>margin-right</code>, <code>margin-bottom</code>, and <code>margin-left</code> properties, you can specify them all in one line, like this: <code>margin: 10px 20px 10px 20px;</code>.",
@ -3118,7 +3076,6 @@
{ {
"id": "bad87fee1348bd9aedf08736", "id": "bad87fee1348bd9aedf08736",
"title": "Style the HTML Body Element", "title": "Style the HTML Body Element",
"difficulty": 1.46,
"description": [ "description": [
"Now let's start fresh and talk about CSS inheritance.", "Now let's start fresh and talk about CSS inheritance.",
"Every HTML page has a <code>body</code> element.", "Every HTML page has a <code>body</code> element.",
@ -3151,7 +3108,6 @@
{ {
"id": "bad87fee1348bd9aedf08746", "id": "bad87fee1348bd9aedf08746",
"title": "Inherit Styles from the Body Element", "title": "Inherit Styles from the Body Element",
"difficulty": 1.47,
"description": [ "description": [
"Now we've proven that every HTML page has a <code>body</code> element, and that its <code>body</code> element can also be styled with CSS.", "Now we've proven that every HTML page has a <code>body</code> element, and that its <code>body</code> element can also be styled with CSS.",
"Remember, you can style your <code>body</code> element just like any other HTML element, and all your other elements will inherit your <code>body</code> element's styles.", "Remember, you can style your <code>body</code> element just like any other HTML element, and all your other elements will inherit your <code>body</code> element's styles.",
@ -3194,7 +3150,6 @@
{ {
"id": "bad87fee1348bd9aedf08756", "id": "bad87fee1348bd9aedf08756",
"title": "Prioritize One Style Over Another", "title": "Prioritize One Style Over Another",
"difficulty": 1.48,
"description": [ "description": [
"Sometimes your HTML elements will receive multiple styles that conflict with one another.", "Sometimes your HTML elements will receive multiple styles that conflict with one another.",
"For example, your <code>h1</code> element can't be both green and pink at the same time.", "For example, your <code>h1</code> element can't be both green and pink at the same time.",
@ -3234,7 +3189,6 @@
{ {
"id": "bad87fee1348bd9aedf04756", "id": "bad87fee1348bd9aedf04756",
"title": "Override Styles in Subsequent CSS", "title": "Override Styles in Subsequent CSS",
"difficulty": 1.49,
"description": [ "description": [
"Our \"pink-text\" class overrode our <code>body</code> element's CSS declaration!", "Our \"pink-text\" class overrode our <code>body</code> element's CSS declaration!",
"We just proved that our classes will override the <code>body</code> element's CSS. So the next logical question is, what can we do to override our <code>pink-text</code> class?", "We just proved that our classes will override the <code>body</code> element's CSS. So the next logical question is, what can we do to override our <code>pink-text</code> class?",
@ -3278,7 +3232,6 @@
{ {
"id": "bad87fee1348bd8aedf06756", "id": "bad87fee1348bd8aedf06756",
"title": "Override Class Declarations by Styling ID Attributes", "title": "Override Class Declarations by Styling ID Attributes",
"difficulty": 1.52,
"description": [ "description": [
"We just proved that browsers read CSS from top to bottom. That means that, in the event of a conflict, the browser will use whichever CSS declaration came last.", "We just proved that browsers read CSS from top to bottom. That means that, in the event of a conflict, the browser will use whichever CSS declaration came last.",
"But we're not done yet. There are other ways that you can override CSS. Do you remember id attributes?", "But we're not done yet. There are other ways that you can override CSS. Do you remember id attributes?",
@ -3329,7 +3282,6 @@
{ {
"id": "bad87fee1348bd9aedf06756", "id": "bad87fee1348bd9aedf06756",
"title": "Override Class Declarations with Inline Styles", "title": "Override Class Declarations with Inline Styles",
"difficulty": 1.52,
"description": [ "description": [
"So we've proven that id declarations override class declarations, regardless of where they are declared in your <code>style</code> element CSS.", "So we've proven that id declarations override class declarations, regardless of where they are declared in your <code>style</code> element CSS.",
"There are other ways that you can override CSS. Do you remember inline styles?", "There are other ways that you can override CSS. Do you remember inline styles?",
@ -3340,7 +3292,7 @@
"assert($(\"h1\").hasClass(\"pink-text\"), 'Your <code>h1</code> element should have the class <code>pink-text</code>.')", "assert($(\"h1\").hasClass(\"pink-text\"), 'Your <code>h1</code> element should have the class <code>pink-text</code>.')",
"assert($(\"h1\").hasClass(\"blue-text\"), 'Your <code>h1</code> element should have the class <code>blue-text</code>.')", "assert($(\"h1\").hasClass(\"blue-text\"), 'Your <code>h1</code> element should have the class <code>blue-text</code>.')",
"assert($(\"h1\").attr(\"id\") === \"orange-text\", 'Your <code>h1</code> element should have the id of <code>orange-text</code>.')", "assert($(\"h1\").attr(\"id\") === \"orange-text\", 'Your <code>h1</code> element should have the id of <code>orange-text</code>.')",
"assert(editor.match(/<h1.*style/gi) && editor.match(/<h1.*style.*color:/gi).length > 0, 'Give your <code>h1</code> element the inline style of <code>color&#58; white</code>.')", "assert(editor.match(/<h1.*style/gi) && editor.match(/<h1.*style.*color\\s*?:/gi), 'Give your <code>h1</code> element the inline style of <code>color&#58; white</code>.')",
"assert($(\"h1\").css(\"color\") === \"rgb(255, 255, 255)\", 'Your <code>h1</code> element should be white.')" "assert($(\"h1\").css(\"color\") === \"rgb(255, 255, 255)\", 'Your <code>h1</code> element should be white.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -3380,7 +3332,6 @@
{ {
"id": "bad87fee1348bd9aedf07756", "id": "bad87fee1348bd9aedf07756",
"title": "Override All Other Styles by using Important", "title": "Override All Other Styles by using Important",
"difficulty": 1.53,
"description": [ "description": [
"Yay! We just proved that in-line styles will override all the CSS declarations in your <code>style</code> element.", "Yay! We just proved that in-line styles will override all the CSS declarations in your <code>style</code> element.",
"But wait. There's one last way to override CSS. This is the most powerful method of all. But before we do it, let's talk about why you would ever want to override CSS.", "But wait. There's one last way to override CSS. This is the most powerful method of all. But before we do it, let's talk about why you would ever want to override CSS.",
@ -3393,7 +3344,7 @@
"assert($(\"h1\").hasClass(\"pink-text\"), 'Your <code>h1</code> element should have the class <code>pink-text</code>.')", "assert($(\"h1\").hasClass(\"pink-text\"), 'Your <code>h1</code> element should have the class <code>pink-text</code>.')",
"assert($(\"h1\").hasClass(\"blue-text\"), 'Your <code>h1</code> element should have the class <code>blue-text</code>.')", "assert($(\"h1\").hasClass(\"blue-text\"), 'Your <code>h1</code> element should have the class <code>blue-text</code>.')",
"assert($(\"h1\").attr(\"id\") === \"orange-text\", 'Your <code>h1</code> element should have the id of <code>orange-text</code>.')", "assert($(\"h1\").attr(\"id\") === \"orange-text\", 'Your <code>h1</code> element should have the id of <code>orange-text</code>.')",
"assert(editor.match(/<h1.*style/gi) && editor.match(/<h1.*style.*color:/gi).length > 0, 'Your <code>h1</code> element should have the inline style of <code>color&#58; white</code>.')", "assert(editor.match(/<h1.*style/gi) && editor.match(/<h1.*style.*color\\s*?:/gi), 'Your <code>h1</code> element should have the inline style of <code>color&#58; white</code>.')",
"assert(editor.match(/pink.*\\!important;/gi), 'Your <code>pink-text</code> class should have the <code>!important</code> keyword to override all other declarations.')", "assert(editor.match(/pink.*\\!important;/gi), 'Your <code>pink-text</code> class should have the <code>!important</code> keyword to override all other declarations.')",
"assert($(\"h1\").css(\"color\") === \"rgb(255, 192, 203)\", 'Your <code>h1</code> element should be pink.')" "assert($(\"h1\").css(\"color\") === \"rgb(255, 192, 203)\", 'Your <code>h1</code> element should be pink.')"
], ],
@ -3434,7 +3385,6 @@
{ {
"id": "bad87fee1348bd9aedf08726", "id": "bad87fee1348bd9aedf08726",
"title": "Use Hex Code for Specific Colors", "title": "Use Hex Code for Specific Colors",
"difficulty": 1.54,
"description": [ "description": [
"Did you know there are other ways to represent colors in CSS? One of these ways is called hexadecimal code, or <code>hex code</code> for short.", "Did you know there are other ways to represent colors in CSS? One of these ways is called hexadecimal code, or <code>hex code</code> for short.",
"<code>Decimal</code> means the numbers zero through nine - the numbers that people use in everyday life. <code>Hexadecimal</code> includes these 10 numbers, plus the letters A, B, C, D, E and F. This means that Hexidecimal has a total of 16 possible values, instead of the 10 possible values that our normal base-10 number system gives us.", "<code>Decimal</code> means the numbers zero through nine - the numbers that people use in everyday life. <code>Hexadecimal</code> includes these 10 numbers, plus the letters A, B, C, D, E and F. This means that Hexidecimal has a total of 16 possible values, instead of the 10 possible values that our normal base-10 number system gives us.",
@ -3470,7 +3420,6 @@
{ {
"id": "bad87fee1348bd9aedf08725", "id": "bad87fee1348bd9aedf08725",
"title": "Use Hex Code to Color Elements White", "title": "Use Hex Code to Color Elements White",
"difficulty": 1.55,
"description": [ "description": [
"<code>0</code> is the lowest number in hex code, and represents a complete absence of color.", "<code>0</code> is the lowest number in hex code, and represents a complete absence of color.",
"<code>F</code> is the highest number in hex code, and it represents the maximum possible brightness.", "<code>F</code> is the highest number in hex code, and it represents the maximum possible brightness.",
@ -3505,10 +3454,9 @@
{ {
"id": "bad87fee1348bd9aedf08724", "id": "bad87fee1348bd9aedf08724",
"title": "Use Hex Code to Color Elements Red", "title": "Use Hex Code to Color Elements Red",
"difficulty": 1.56,
"description": [ "description": [
"You may be wondering why we use 6 digits to represent a color instead of just one or two. The answer is that using 6 digits gives us a huge variety.", "You may be wondering why we use 6 digits to represent a color instead of just one or two. The answer is that using 6 digits gives us a huge variety.",
"How many colors are possible? 16 colors and 6 positions means we have 16 to the 6th power, or more than 16 million possible colors.", "How many colors are possible? 16 values and 6 positions means we have 16 to the 6th power, or more than 16 million possible colors.",
"Hex code follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.", "Hex code follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
"So to get the absolute brightest red, you would just use <code>F</code> for the first and second digits (the highest possible value) and <code>0</code> for the third, fourth, fifth and sixth digits (the lowest possible value).", "So to get the absolute brightest red, you would just use <code>F</code> for the first and second digits (the highest possible value) and <code>0</code> for the third, fourth, fifth and sixth digits (the lowest possible value).",
"Make the <code>body</code> element's background color red by giving it the hex code value of <code>#FF0000</code>." "Make the <code>body</code> element's background color red by giving it the hex code value of <code>#FF0000</code>."
@ -3542,7 +3490,6 @@
{ {
"id": "bad87fee1348bd9aedf08723", "id": "bad87fee1348bd9aedf08723",
"title": "Use Hex Code to Color Elements Green", "title": "Use Hex Code to Color Elements Green",
"difficulty": 1.57,
"description": [ "description": [
"Remember that <code>hex code</code> follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.", "Remember that <code>hex code</code> follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
"So to get the absolute brightest green, you would just use <code>F</code> for the third and fourth digits (the highest possible value) and <code>0</code> for all the other digits (the lowest possible value).", "So to get the absolute brightest green, you would just use <code>F</code> for the third and fourth digits (the highest possible value) and <code>0</code> for all the other digits (the lowest possible value).",
@ -3577,7 +3524,6 @@
{ {
"id": "bad87fee1348bd9aedf08722", "id": "bad87fee1348bd9aedf08722",
"title": "Use Hex Code to Color Elements Blue", "title": "Use Hex Code to Color Elements Blue",
"difficulty": 1.58,
"description": [ "description": [
"Hex code follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.", "Hex code follows the red-green-blue, or <code>rgb</code> format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
"So to get the absolute brightest blue, we use <code>F</code> for the fifth and sixth digits (the highest possible value) and <code>0</code> for all the other digits (the lowest possible value).", "So to get the absolute brightest blue, we use <code>F</code> for the fifth and sixth digits (the highest possible value) and <code>0</code> for all the other digits (the lowest possible value).",
@ -3612,7 +3558,6 @@
{ {
"id": "bad87fee1348bd9aedf08721", "id": "bad87fee1348bd9aedf08721",
"title": "Use Hex Code to Mix Colors", "title": "Use Hex Code to Mix Colors",
"difficulty": 1.59,
"description": [ "description": [
"From these three pure colors (red, green and blue), we can create 16 million other colors.", "From these three pure colors (red, green and blue), we can create 16 million other colors.",
"For example, orange is pure red, mixed with some green, and no blue.", "For example, orange is pure red, mixed with some green, and no blue.",
@ -3647,7 +3592,6 @@
{ {
"id": "bad87fee1348bd9aede08720", "id": "bad87fee1348bd9aede08720",
"title": "Use Hex Code to Color Elements Gray", "title": "Use Hex Code to Color Elements Gray",
"difficulty": 1.60,
"description": [ "description": [
"From these three pure colors (red, green and blue), we can create 16 million other colors.", "From these three pure colors (red, green and blue), we can create 16 million other colors.",
"We can also create different shades of gray by evenly mixing all three colors.", "We can also create different shades of gray by evenly mixing all three colors.",
@ -3682,7 +3626,6 @@
{ {
"id": "bad87fee1348bd9aedf08720", "id": "bad87fee1348bd9aedf08720",
"title": "Use Hex Code for Specific Shades of Gray", "title": "Use Hex Code for Specific Shades of Gray",
"difficulty": 1.61,
"description": [ "description": [
"We can also create other shades of gray by evenly mixing all three colors. We can go very close to true black.", "We can also create other shades of gray by evenly mixing all three colors. We can go very close to true black.",
"Make the <code>body</code> element's background color a dark gray by giving it the hex code value of <code>#111111</code>." "Make the <code>body</code> element's background color a dark gray by giving it the hex code value of <code>#111111</code>."
@ -3716,7 +3659,6 @@
{ {
"id": "bad87fee1348bd9aedf08719", "id": "bad87fee1348bd9aedf08719",
"title": "Use Abbreviated Hex Code", "title": "Use Abbreviated Hex Code",
"difficulty": 1.62,
"description": [ "description": [
"Many people feel overwhelmed by the possibilities of more than 16 million colors. And it's difficult to remember hex code. Fortunately, you can shorten it.", "Many people feel overwhelmed by the possibilities of more than 16 million colors. And it's difficult to remember hex code. Fortunately, you can shorten it.",
"For example, red, which is <code>#FF0000</code> in hex code, can be shortened to <code>#F00</code>. That is, one digit for red, one digit for green, one digit for blue.", "For example, red, which is <code>#FF0000</code> in hex code, can be shortened to <code>#F00</code>. That is, one digit for red, one digit for green, one digit for blue.",
@ -3752,7 +3694,6 @@
{ {
"id": "bad87fee1348bd9aede08718", "id": "bad87fee1348bd9aede08718",
"title": "Use RGB values to Color Elements", "title": "Use RGB values to Color Elements",
"difficulty": 1.63,
"description": [ "description": [
"Another way you can represent colors in CSS is by using <code>rgb</code> values.", "Another way you can represent colors in CSS is by using <code>rgb</code> values.",
"RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)</code> for white.", "RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)</code> for white.",
@ -3789,7 +3730,6 @@
{ {
"id": "bad88fee1348bd9aedf08726", "id": "bad88fee1348bd9aedf08726",
"title": "Use RGB to Color Elements White", "title": "Use RGB to Color Elements White",
"difficulty": 1.64,
"description": [ "description": [
"RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)</code> for white.", "RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)</code> for white.",
"Instead of using six hexadecimal digits like you do with hex code, with <code>rgb</code> you specify the brightness of each color with a number between 0 and 255.", "Instead of using six hexadecimal digits like you do with hex code, with <code>rgb</code> you specify the brightness of each color with a number between 0 and 255.",
@ -3824,7 +3764,6 @@
{ {
"id": "bad89fee1348bd9aedf08724", "id": "bad89fee1348bd9aedf08724",
"title": "Use RGB to Color Elements Red", "title": "Use RGB to Color Elements Red",
"difficulty": 1.65,
"description": [ "description": [
"Just like with hex code, you can represent different colors in RGB by using combinations of different values.", "Just like with hex code, you can represent different colors in RGB by using combinations of different values.",
"These values follow the pattern of RGB: the first number represents red, the second number represents green, and the third number represents blue.", "These values follow the pattern of RGB: the first number represents red, the second number represents green, and the third number represents blue.",
@ -3859,7 +3798,6 @@
{ {
"id": "bad80fee1348bd9aedf08723", "id": "bad80fee1348bd9aedf08723",
"title": "Use RGB to Color Elements Green", "title": "Use RGB to Color Elements Green",
"difficulty": 1.66,
"description": [ "description": [
"Now change the <code>body</code> element's background color to the <code>rgb</code> value green: <code>rgb(0, 255, 0)</code>" "Now change the <code>body</code> element's background color to the <code>rgb</code> value green: <code>rgb(0, 255, 0)</code>"
], ],
@ -3892,7 +3830,6 @@
{ {
"id": "bad81fee1348bd9aedf08722", "id": "bad81fee1348bd9aedf08722",
"title": "Use RGB to Color Elements Blue", "title": "Use RGB to Color Elements Blue",
"difficulty": 1.67,
"description": [ "description": [
"Change the <code>body</code> element's background color to the RGB value blue: <code>rgb(0, 0, 255)</code>" "Change the <code>body</code> element's background color to the RGB value blue: <code>rgb(0, 0, 255)</code>"
], ],
@ -3925,7 +3862,6 @@
{ {
"id": "bad82fee1348bd9aedf08721", "id": "bad82fee1348bd9aedf08721",
"title": "Use RGB to Mix Colors", "title": "Use RGB to Mix Colors",
"difficulty": 1.68,
"description": [ "description": [
"Just like with hex code, you can mix colors in RGB by using combinations of different values.", "Just like with hex code, you can mix colors in RGB by using combinations of different values.",
"Change the <code>body</code> element's background color to the RGB value orange: <code>rgb(255, 165, 0)</code>" "Change the <code>body</code> element's background color to the RGB value orange: <code>rgb(255, 165, 0)</code>"
@ -3959,7 +3895,6 @@
{ {
"id": "bad83fee1348bd9aede08720", "id": "bad83fee1348bd9aede08720",
"title": "Use RGB to Color Elements Gray", "title": "Use RGB to Color Elements Gray",
"difficulty": 1.69,
"description": [ "description": [
"With RGB values, we can make an element gray by using combinations of the same value for all three colors.", "With RGB values, we can make an element gray by using combinations of the same value for all three colors.",
"Change the <code>body</code> element's background color to the RGB value for gray: <code>rgb(128, 128, 128)</code>" "Change the <code>body</code> element's background color to the RGB value for gray: <code>rgb(128, 128, 128)</code>"

View File

@ -1,11 +1,10 @@
{ {
"name": "Intermediate Algorithm Scripting", "name": "Intermediate Algorithm Scripting",
"order": 0.009, "order": 9,
"challenges": [ "challenges": [
{ {
"id": "a3566b1109230028080c9345", "id": "a3566b1109230028080c9345",
"title": "Sum All Numbers in a Range", "title": "Sum All Numbers in a Range",
"difficulty": "2.00",
"description": [ "description": [
"We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.", "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.", "The lowest number will not always come first.",
@ -19,11 +18,11 @@
"sumAll([1, 4]);" "sumAll([1, 4]);"
], ],
"tests": [ "tests": [
"expect(sumAll([1, 4])).to.be.a('Number');", "assert(typeof(sumAll([1, 4])) === \"number\", 'message: <code>sumAll()</code> should return a number.');",
"expect(sumAll([1, 4])).to.equal(10);", "assert.deepEqual(sumAll([1, 4]), 10, 'message: <code>sumAll([1, 4])</code> should return 10.');",
"expect(sumAll([4, 1])).to.equal(10);", "assert.deepEqual(sumAll([4, 1]), 10, 'message: <code>sumAll([4, 1])</code> should return 10.');",
"expect(sumAll([5, 10])).to.equal(45);", "assert.deepEqual(sumAll([5, 10]), 45, 'message: <code>sumAll([5, 10])</code> should return 45.');",
"expect(sumAll([10, 5])).to.equal(45);" "assert.deepEqual(sumAll([10, 5]), 45, 'message: <code>sumAll([10, 5])</code> should return 45.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Math.max()", "Math.max()",
@ -46,7 +45,6 @@
{ {
"id": "a5de63ebea8dbee56860f4f2", "id": "a5de63ebea8dbee56860f4f2",
"title": "Diff Two Arrays", "title": "Diff Two Arrays",
"difficulty": "2.01",
"description": [ "description": [
"Compare two arrays and return a new array with any items not found in both of the original arrays.", "Compare two arrays and return a new array with any items not found in both of the original arrays.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -61,13 +59,13 @@
"diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);" "diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);"
], ],
"tests": [ "tests": [
"expect(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])).to.be.a('array');", "assert(typeof(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])) === \"object\", 'message: <code>diff()</code> should return an 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.deepEqual(diff([\"diorite\", \"andesite\", \"grass\", \"dirt\", \"pink wool\", \"dead shrub\"], [\"diorite\", \"andesite\", \"grass\", \"dirt\", \"dead shrub\"]), [\"pink wool\"], 'message: <code>[\"diorite\", \"andesite\", \"grass\", \"dirt\", \"pink wool\", \"dead shrub\"], [\"diorite\", \"andesite\", \"grass\", \"dirt\", \"dead shrub\"]</code> should return <code>[\"pink wool\"]</code>.');",
"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.includeMembers(diff([\"andesite\", \"grass\", \"dirt\", \"pink wool\", \"dead shrub\"], [\"diorite\", \"andesite\", \"grass\", \"dirt\", \"dead shrub\"]), [\"diorite\", \"pink wool\"], 'message: <code>[\"andesite\", \"grass\", \"dirt\", \"pink wool\", \"dead shrub\"], [\"diorite\", \"andesite\", \"grass\", \"dirt\", \"dead shrub\"]</code> should return <code>[\"diorite\", \"pink wool\"]</code>.');",
"assert.deepEqual(diff(['andesite', 'grass', 'dirt', 'dead shrub'], ['andesite', 'grass', 'dirt', 'dead shrub']), [], 'arrays with no difference');", "assert.deepEqual(diff([\"andesite\", \"grass\", \"dirt\", \"dead shrub\"], [\"andesite\", \"grass\", \"dirt\", \"dead shrub\"]), [], 'message: <code>[\"andesite\", \"grass\", \"dirt\", \"dead shrub\"], [\"andesite\", \"grass\", \"dirt\", \"dead shrub\"]</code> should return <code>[]</code>.');",
"assert.deepEqual(diff([1, 2, 3, 5], [1, 2, 3, 4, 5]), [4], 'arrays with numbers');", "assert.deepEqual(diff([1, 2, 3, 5], [1, 2, 3, 4, 5]), [4], 'message: <code>[1, 2, 3, 5], [1, 2, 3, 4, 5]</code> should return <code>[4]</code>.');",
"assert.includeMembers(diff([1, 'calf', 3, 'piglet'], [1, 'calf', 3, 4]), ['piglet', 4], 'arrays with numbers and strings');", "assert.includeMembers(diff([1, \"calf\", 3, \"piglet\"], [1, \"calf\", 3, 4]), [\"piglet\", 4], 'message: <code>[1, \"calf\", 3, \"piglet\"], [1, \"calf\", 3, 4]</code> should return <code>[\"piglet\", 4]</code>.');",
"assert.deepEqual(diff([], ['snuffleupagus', 'cookie monster', 'elmo']), ['snuffleupagus', 'cookie monster', 'elmo'], 'empty array');" "assert.deepEqual(diff([], [\"snuffleupagus\", \"cookie monster\", \"elmo\"]), [\"snuffleupagus\", \"cookie monster\", \"elmo\"], 'message: <code>[], [\"snuffleupagus\", \"cookie monster\", \"elmo\"]</code> should return <code>[\"snuffleupagus\", \"cookie monster\", \"elmo\"]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Comparison Operators", "Comparison Operators",
@ -93,13 +91,12 @@
"id": "a7f4d8f2483413a6ce226cac", "id": "a7f4d8f2483413a6ce226cac",
"title": "Roman Numeral Converter", "title": "Roman Numeral Converter",
"tests": [ "tests": [
"expect(convert(12)).to.equal(\"XII\");", "assert.deepEqual(convert(12), \"XII\", 'message: <code>convert(12)</code> should return \"XII\".');",
"expect(convert(5)).to.equal(\"V\");", "assert.deepEqual(convert(5), \"V\", 'message: <code>convert(5)</code> should return \"V\".');",
"expect(convert(9)).to.equal(\"IX\");", "assert.deepEqual(convert(9), \"IX\", 'message: <code>convert(9)</code> should return \"IX\".');",
"expect(convert(29)).to.equal(\"XXIX\");", "assert.deepEqual(convert(29), \"XXIX\", 'message: <code>convert(29)</code> should return \"XXIX\".');",
"expect(convert(16)).to.equal(\"XVI\");" "assert.deepEqual(convert(16), \"XVI\", 'message: <code>convert(16)</code> should return \"XVI\".');"
], ],
"difficulty": "2.02",
"description": [ "description": [
"Convert the given number into a roman numeral.", "Convert the given number into a roman numeral.",
"All <a href=\"http://www.mathsisfun.com/roman-numerals.html\" target=\"_blank\">roman numerals</a> answers should be provided in upper-case.", "All <a href=\"http://www.mathsisfun.com/roman-numerals.html\" target=\"_blank\">roman numerals</a> answers should be provided in upper-case.",
@ -113,6 +110,7 @@
"convert(36);" "convert(36);"
], ],
"MDNlinks": [ "MDNlinks": [
"Roman Numerals",
"Array.splice()", "Array.splice()",
"Array.indexOf()", "Array.indexOf()",
"Array.join()" "Array.join()"
@ -130,31 +128,70 @@
"namePt": "", "namePt": "",
"descriptionPt": [] "descriptionPt": []
}, },
{
"id": "a8e512fbe388ac2f9198f0fa",
"title": "Where art thou",
"description": [
"Make a function that looks through an array of objects (first argument) and returns an array of all objects that have matching property and value pairs (second argument). Each property and value pair of the source object has to be present in the object from the collection if it is to be included in the returned array.",
"For example, if the first argument is <code>[{ first: \"Romeo\", last: \"Montague\" }, { first: \"Mercutio\", last: null }, { first: \"Tybalt\", last: \"Capulet\" }]</code>, and the second argument is <code>{ last: \"Capulet\" }</code>, then you must return the third object from the array (the first argument), because it contains the property and it's value, that was passed on as the second argument.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Write your own code."
],
"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\" }], 'message: <code>where()</code> 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 }], 'message: <code>where([{ \"a\": 1 }, { \"a\": 1 }, { \"a\": 1, \"b\": 2 }], { \"a\": 1 })</code> should return <code>[{ \"a\": 1 }, { \"a\": 1 }, { \"a\": 1, \"b\": 2 }]</code>.');",
"assert.deepEqual(where([{ \"a\": 1, \"b\": 2 }, { \"a\": 1 }, { \"a\": 1, \"b\": 2, \"c\": 2 }], { \"a\": 1, \"b\": 2 }), [{ \"a\": 1, \"b\": 2 }, { \"a\": 1, \"b\": 2, \"c\": 2 }], 'message: <code>where([{ \"a\": 1, \"b\": 2 }, { \"a\": 1 }, { \"a\": 1, \"b\": 2, \"c\": 2 }], { \"a\": 1, \"b\": 2 })</code> should return <code>[{ \"a\": 1, \"b\": 2 }, { \"a\": 1, \"b\": 2, \"c\": 2 }]</code>.');"
],
"MDNlinks": [
"Global Object",
"Object.hasOwnProperty()",
"Object.keys()"
],
"type": "bonfire",
"challengeType": 5,
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{ {
"id": "a0b5010f579e69b815e7c5d6", "id": "a0b5010f579e69b815e7c5d6",
"title": "Search and Replace", "title": "Search and Replace",
"tests": [ "tests": [
"expect(replace(\"Let us go to the store\", \"store\", \"mall\")).to.equal(\"Let us go to the mall\");", "assert.deepEqual(myReplace(\"Let us go to the store\", \"store\", \"mall\"), \"Let us go to the mall\", 'message: <code>myReplace(\"Let us go to the store\", \"store\", \"mall\")</code> should return \"Let us go to the mall\".');",
"expect(replace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\")).to.equal(\"He is Sitting on the couch\");", "assert.deepEqual(myReplace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\"), \"He is Sitting on the couch\", 'message: <code>myReplace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\")</code> should return \"He is Sitting on the couch\".');",
"expect(replace(\"This has a spellngi error\", \"spellngi\", \"spelling\")).to.equal(\"This has a spelling error\");", "assert.deepEqual(myReplace(\"This has a spellngi error\", \"spellngi\", \"spelling\"), \"This has a spelling error\", 'message: <code>myReplace(\"This has a spellngi error\", \"spellingi\", \"spelling\")</code> should return \"This has a spelling error\".');",
"expect(replace(\"His name is Tom\", \"Tom\", \"john\")).to.equal(\"His name is John\");", "assert.deepEqual(myReplace(\"His name is Tom\", \"Tom\", \"john\"), \"His name is John\", 'message: <code>myReplace(\"His name is Tom\", \"Tom\", \"john\")</code> should return \"His name is John\".');",
"expect(replace(\"Let us get back to more Coding\", \"Coding\", \"bonfires\")).to.equal(\"Let us get back to more Bonfires\");" "assert.deepEqual(myReplace(\"Let us get back to more Coding\", \"Coding\", \"bonfires\"), \"Let us get back to more Bonfires\", 'message: <code>myReplace(\"Let us get back to more Coding\", \"Coding\", \"bonfires\")</code> should return \"Let us get back to more Bonfires\".');"
], ],
"difficulty": "2.03",
"description": [ "description": [
"Perform a search and replace on the sentence using the arguments provided and return the new sentence.", "Perform a search and replace on the sentence using the arguments provided and return the new sentence.",
"First argument is the sentence to perform the search and replace on.", "First argument is the sentence to perform the search and replace on.",
"Second argument is the word that you will be replacing (before).", "Second argument is the word that you will be replacing (before).",
"Third argument is what you will be replacing the second argument with (after).", "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'", "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\"",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
"function replace(str, before, after) {", "function myReplace(str, before, after) {",
" return str;", " return str;",
"}", "}",
"", "",
"replace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");" "myReplace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.splice()", "Array.splice()",
@ -178,13 +215,12 @@
"id": "aa7697ea2477d1316795783b", "id": "aa7697ea2477d1316795783b",
"title": "Pig Latin", "title": "Pig Latin",
"tests": [ "tests": [
"expect(translate(\"california\")).to.equal(\"aliforniacay\");", "assert.deepEqual(translate(\"california\"), \"aliforniacay\", 'message: <code>translate(\"california\")</code> should return \"aliforniacay\".');",
"expect(translate(\"paragraphs\")).to.equal(\"aragraphspay\");", "assert.deepEqual(translate(\"paragraphs\"), \"aragraphspay\", 'message: <code>translate(\"paragraphs\")</code> should return \"aragraphspay\".');",
"expect(translate(\"glove\")).to.equal(\"oveglay\");", "assert.deepEqual(translate(\"glove\"), \"oveglay\", 'message: <code>translate(\"glove\")</code> should return \"oveglay\".');",
"expect(translate(\"algorithm\")).to.equal(\"algorithmway\");", "assert.deepEqual(translate(\"algorithm\"), \"algorithmway\", 'message: <code>translate(\"algorithm\")</code> should return \"algorithmway\".');",
"expect(translate(\"eight\")).to.equal(\"eightway\");" "assert.deepEqual(translate(\"eight\"), \"eightway\", 'message: <code>translate(\"eight\")</code> should return \"eightway\".');"
], ],
"difficulty": "2.04",
"description": [ "description": [
"Translate the provided string to pig latin.", "Translate the provided string to pig latin.",
"<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target=\"_blank\">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".", "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target=\"_blank\">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
@ -222,17 +258,16 @@
"id": "afd15382cdfb22c9efe8b7de", "id": "afd15382cdfb22c9efe8b7de",
"title": "DNA Pairing", "title": "DNA Pairing",
"tests": [ "tests": [
"assert.deepEqual(pair(\"ATCGA\"),[['A','T'],['T','A'],['C','G'],['G','C'],['A','T']], 'should return the dna pair');", "assert.deepEqual(pair(\"ATCGA\"),[[\"A\",\"T\"],[\"T\",\"A\"],[\"C\",\"G\"],[\"G\",\"C\"],[\"A\",\"T\"]], 'message: <code>pair(\"ATCGA\")</code> should return <code>[[\"A\",\"T\"],[\"T\",\"A\"],[\"C\",\"G\"],[\"G\",\"C\"],[\"A\",\"T\"]]</code>.');",
"assert.deepEqual(pair(\"TTGAG\"),[['T','A'],['T','A'],['G','C'],['A','T'],['G','C']], 'should return the dna pair');", "assert.deepEqual(pair(\"TTGAG\"),[[\"T\",\"A\"],[\"T\",\"A\"],[\"G\",\"C\"],[\"A\",\"T\"],[\"G\",\"C\"]], 'message: <code>pair(\"TTGAG\")</code> should return <code>[[\"T\",\"A\"],[\"T\",\"A\"],[\"G\",\"C\"],[\"A\",\"T\"],[\"G\",\"C\"]]</code>.');",
"assert.deepEqual(pair(\"CTCTA\"),[['C','G'],['T','A'],['C','G'],['T','A'],['A','T']], 'should return the dna pair');" "assert.deepEqual(pair(\"CTCTA\"),[[\"C\",\"G\"],[\"T\",\"A\"],[\"C\",\"G\"],[\"T\",\"A\"],[\"A\",\"T\"]], 'message: <code>pair(\"CTCTA\")</code> should return <code>[[\"C\",\"G\"],[\"T\",\"A\"],[\"C\",\"G\"],[\"T\",\"A\"],[\"A\",\"T\"]]</code>.');"
], ],
"difficulty": "2.05",
"description": [ "description": [
"The DNA strand is missing the pairing element. Take each character, get its pair, and return the results as a 2d array.", "The DNA strand is missing the pairing element. Take each character, get its pair, and return the results as a 2d array.",
"<a href=\"http://en.wikipedia.org/wiki/Base_pair\" target=\"_blank\">Base pairs</a> are a pair of AT and CG. Match the missing element to the provided character.", "<a href=\"http://en.wikipedia.org/wiki/Base_pair\" target=\"_blank\">Base pairs</a> 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.", "Return the provided character as the first element in each array.",
"For example, for the input GCG, return [['G', 'C'], ['C','G'],['G', 'C']]", "For example, for the input GCG, return [[\"G\", \"C\"], [\"C\",\"G\"],[\"G\", \"C\"]]",
"The charater and its pair are paired up in an array, and all the arrays are grouped into one encapsulating array.", "The character and its pair are paired up in an array, and all the arrays are grouped into one encapsulating array.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
@ -262,7 +297,6 @@
{ {
"id": "af7588ade1100bde429baf20", "id": "af7588ade1100bde429baf20",
"title": "Missing letters", "title": "Missing letters",
"difficulty": "2.05",
"description": [ "description": [
"Find the missing letter in the passed letter range and return it.", "Find the missing letter in the passed letter range and return it.",
"If all letters are present in the range, return undefined.", "If all letters are present in the range, return undefined.",
@ -273,13 +307,13 @@
" return str;", " return str;",
"}", "}",
"", "",
"fearNotLetter('abce');" "fearNotLetter(\"abce\");"
], ],
"tests": [ "tests": [
"expect(fearNotLetter('abce')).to.equal('d');", "assert.deepEqual(fearNotLetter(\"abce\"), \"d\", 'message: <code>fearNotLetter(\"abce\")</code> should return \"d\".');",
"expect(fearNotLetter('bcd')).to.be.undefined;", "assert.deepEqual(fearNotLetter(\"abcdefghjklmno\"), \"i\", 'message: <code>fearNotLetter(\"abcdefghjklmno\")</code> should return \"i\".');",
"expect(fearNotLetter('abcdefghjklmno')).to.equal('i');", "assert.isUndefined(fearNotLetter(\"bcd\"), 'message: <code>fearNotLetter(\"bcd\")</code> should return undefined.');",
"expect(fearNotLetter('yz')).to.be.undefined;" "assert.isUndefined(fearNotLetter(\"yz\"), 'message: <code>fearNotLetter(\"yz\")</code> should return undefined.');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.charCodeAt()", "String.charCodeAt()",
@ -301,7 +335,6 @@
{ {
"id": "a77dbc43c33f39daa4429b4f", "id": "a77dbc43c33f39daa4429b4f",
"title": "Boo who", "title": "Boo who",
"difficulty": "2.06",
"description": [ "description": [
"Check if a value is classified as a boolean primitive. Return true or false.", "Check if a value is classified as a boolean primitive. Return true or false.",
"Boolean primitives are true and false.", "Boolean primitives are true and false.",
@ -316,14 +349,14 @@
"boo(null);" "boo(null);"
], ],
"tests": [ "tests": [
"assert.strictEqual(boo(true), true);", "assert.strictEqual(boo(true), true, 'message: <code>boo(true)</code> should return true.');",
"assert.strictEqual(boo(false), true);", "assert.strictEqual(boo(false), true, 'message: <code>boo(false)</code> should return true.');",
"assert.strictEqual(boo([1, 2, 3]), false);", "assert.strictEqual(boo([1, 2, 3]), false, 'message: <code>boo([1, 2, 3])</code> should return false.');",
"assert.strictEqual(boo([].slice), false);", "assert.strictEqual(boo([].slice), false, 'message: <code>boo([].slice)</code> should return false.');",
"assert.strictEqual(boo({ 'a': 1 }), false);", "assert.strictEqual(boo({ \"a\": 1 }), false, 'message: <code>boo({ \"a\": 1 })</code> should return false.');",
"assert.strictEqual(boo(1), false);", "assert.strictEqual(boo(1), false, 'message: <code>boo(1)</code> should return false.');",
"assert.strictEqual(boo(NaN), false);", "assert.strictEqual(boo(NaN), false, 'message: <code>boo(NaN)</code> should return true.');",
"assert.strictEqual(boo('a'), false);" "assert.strictEqual(boo(\"a\"), false, 'message: <code>boo(\"a\")</code> should return false.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Boolean Objects" "Boolean Objects"
@ -344,7 +377,6 @@
{ {
"id": "a105e963526e7de52b219be9", "id": "a105e963526e7de52b219be9",
"title": "Sorted Union", "title": "Sorted Union",
"difficulty": "2.07",
"description": [ "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.", "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.", "In other words, all values present from all arrays should be included in their original order, but with no duplicates in the final array.",
@ -360,10 +392,10 @@
"unite([1, 3, 2], [5, 2, 1, 4], [2, 1]);" "unite([1, 3, 2], [5, 2, 1, 4], [2, 1]);"
], ],
"tests": [ "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], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4], 'message: <code>unite([1, 3, 2], [5, 2, 1, 4], [2, 1])</code> should return <code>[1, 3, 2, 5, 4]</code>.');",
"assert.deepEqual(unite([1, 3, 2], [1, [5]], [2, [4]]), [1, 3, 2, [5], [4]], 'should not flatten nested arrays');", "assert.deepEqual(unite([1, 3, 2], [1, [5]], [2, [4]]), [1, 3, 2, [5], [4]], 'message: <code>unite([1, 3, 2], [1, [5]], [2, [4]])</code> should return <code>[1, 3, 2, [5], [4]]</code>.');",
"assert.deepEqual(unite([1, 2, 3], [5, 2, 1]), [1, 2, 3, 5], 'should correctly handle exactly two arguments');", "assert.deepEqual(unite([1, 2, 3], [5, 2, 1]), [1, 2, 3, 5], 'message: <code>unite([1, 2, 3], [5, 2, 1])</code> should return <code>[1, 2, 3, 5]</code>.');",
"assert.deepEqual(unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]), [ 1, 2, 3, 5, 4, 6, 7, 8 ], 'should correctly handle higher numbers of arguments');" "assert.deepEqual(unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]), [1, 2, 3, 5, 4, 6, 7, 8], 'message: <code>unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8])</code> should return <code>[1, 2, 3, 5, 4, 6, 7, 8]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Arguments object", "Arguments object",
@ -385,7 +417,6 @@
{ {
"id": "a6b0bb188d873cb2c8729495", "id": "a6b0bb188d873cb2c8729495",
"title": "Convert HTML Entities", "title": "Convert HTML Entities",
"difficulty": "2.07",
"description": [ "description": [
"Convert the characters \"&\", \"<\", \">\", '\"' (double quote), and \"'\" (apostrophe), in a string to their corresponding HTML entities.", "Convert the characters \"&\", \"<\", \">\", '\"' (double quote), and \"'\" (apostrophe), in a string to their corresponding HTML entities.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -396,16 +427,16 @@
" return str;", " return str;",
"}", "}",
"", "",
"convert('Dolce & Gabbana');" "convert(\"Dolce & Gabbana\");"
], ],
"tests": [ "tests": [
"assert.match(convert('Dolce & Gabbana'), /Dolce &(amp|AMP|#x00026|#38); Gabbana/, 'should escape characters');", "assert.match(convert(\"Dolce & Gabbana\"), /Dolce &amp; Gabbana/, 'message: <code>convert(\"Dolce & Gabbana\")</code> should return <code>Dolce &&#8203;amp; Gabbana</code>.');",
"assert.match(convert('Hamburgers < Pizza < Tacos'), /Hamburgers &(lt|LT|#x0003C|#60); Pizza &(lt|LT|#x0003C|#60); Tacos/, 'should escape characters');", "assert.match(convert(\"Hamburgers < Pizza < Tacos\"), /Hamburgers &lt; Pizza &lt; Tacos/, 'message: <code>convert(\"Hamburgers < Pizza < Tacos\")</code> should return <code>Hamburgers &&#8203;lt; Pizza &&#8203;lt; Tacos</code>.');",
"assert.match(convert('Sixty > twelve'), /Sixty &(gt|GT|#x0003E|#62); twelve/, 'should escape characters');", "assert.match(convert(\"Sixty > twelve\"), /Sixty &gt; twelve/, 'message: <code>convert(\"Sixty > twelve\")</code> should return <code>Sixty &&#8203;gt; twelve</code>.');",
"assert.match(convert('Stuff in \"quotation marks\"'), /Stuff in &(quot|QUOT|#x00022|#34);quotation marks&(quot|QUOT|#x00022|#34);/, 'should escape characters');", "assert.match(convert('Stuff in \"quotation marks\"'), /Stuff in &quot;quotation marks&quot;/, 'message: <code>convert(&apos;Stuff in \"quotation marks\"&apos;)</code> should return <code>Stuff in &&#8203;quot;quotation marks&&#8203;quot;</code>.');",
"assert.match(convert(\"Shindler's List\"), /Shindler&(apos|#x00027|#39);s List/, 'should escape characters');", "assert.match(convert(\"Shindler's List\"), /Shindler&apos;s List/, 'message: <code>convert(\"Shindler&apos;s List\")</code> should return <code>Shindler&&#8203;apos;s List</code>.');",
"assert.match(convert('<>'), /&(lt|LT|#x0003C|#60);&(gt|GT|#x0003E|#62);/, 'should escape characters');", "assert.match(convert('<>'), /&lt;&gt;/, 'message: <code>convert(\"<>\")</code> should return <code>&&#8203;lt;&&#8203;gt;</code>.');",
"assert.strictEqual(convert('abc'), 'abc', 'should handle strings with nothing to escape');" "assert.strictEqual(convert('abc'), 'abc', 'message: <code>convert(\"abc\")</code> should return <code>abc</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"RegExp", "RegExp",
@ -427,7 +458,6 @@
{ {
"id": "a103376db3ba46b2d50db289", "id": "a103376db3ba46b2d50db289",
"title": "Spinal Tap Case", "title": "Spinal Tap Case",
"difficulty": "2.08",
"description": [ "description": [
"Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.", "Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -442,10 +472,10 @@
"spinalCase('This Is Spinal Tap');" "spinalCase('This Is Spinal Tap');"
], ],
"tests": [ "tests": [
"assert.strictEqual(spinalCase('This Is Spinal Tap'), 'this-is-spinal-tap', 'should return spinal case from string with spaces');", "assert.deepEqual(spinalCase(\"This Is Spinal Tap\"), \"this-is-spinal-tap\", 'message: <code>spinalCase(\"This Is Spinal Tap\")</code> should return <code>\"this-is-spinal-tap\"</code>.');",
"assert.strictEqual(spinalCase('thisIsSpinalTap'), 'this-is-spinal-tap', 'should return spinal case from string with camel case');", "assert.strictEqual(spinalCase('thisIsSpinalTap'), \"this-is-spinal-tap\", 'message: <code>spinalCase(\"thisIsSpinalTap\")</code> should return <code>\"this-is-spinal-tap\"</code>.');",
"assert.strictEqual(spinalCase('The_Andy_Griffith_Show'), 'the-andy-griffith-show', 'should return spinal case from string with snake case');", "assert.strictEqual(spinalCase(\"The_Andy_Griffith_Show\"), \"the-andy-griffith-show\", 'message: <code>spinalCase(\"The_Andy_Griffith_Show\")</code> should return <code>\"the-andy-griffith-show\"</code>.');",
"assert.strictEqual(spinalCase('Teletubbies say Eh-oh'), 'teletubbies-say-eh-oh', 'should return spinal case from string with spaces and hyphens');" "assert.strictEqual(spinalCase(\"Teletubbies say Eh-oh\"), \"teletubbies-say-eh-oh\", 'message: <code>spinalCase(\"Teletubbies say Eh-oh\")</code> should return <code>\"teletubbies-say-eh-oh\"</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"RegExp", "RegExp",
@ -467,7 +497,6 @@
{ {
"id": "a5229172f011153519423690", "id": "a5229172f011153519423690",
"title": "Sum All Odd Fibonacci Numbers", "title": "Sum All Odd Fibonacci Numbers",
"difficulty": "2.09",
"description": [ "description": [
"Return the sum of all odd Fibonacci numbers up to and including the passed number if it is a Fibonacci number.", "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.", "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.",
@ -482,12 +511,12 @@
"sumFibs(4);" "sumFibs(4);"
], ],
"tests": [ "tests": [
"expect(sumFibs(1)).to.be.a('number');", "assert(typeof(sumFibs(1)) === \"number\", 'message: <code>sumFibs()</code> should return a number.');",
"expect(sumFibs(1000)).to.equal(1785);", "assert.deepEqual(sumFibs(1000), 1785, 'message: <code>sumFibs(1000)</code> should return 1785.');",
"expect(sumFibs(4000000)).to.equal(4613732);", "assert.deepEqual(sumFibs(4000000), 4613732, 'message: <code>sumFibs(4000000)</code> should return 4613732.');",
"expect(sumFibs(4)).to.equal(5);", "assert.deepEqual(sumFibs(4), 5, 'message: <code>sumFibs(4)</code> should return 5.');",
"expect(sumFibs(75024)).to.equal(60696);", "assert.deepEqual(sumFibs(75024), 60696, 'message: <code>sumFibs(75024)</code> should return 60696.');",
"expect(sumFibs(75025)).to.equal(135721);" "assert.deepEqual(sumFibs(75025), 135721, 'message: <code>sumFibs(75025)</code> should return 135721.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Remainder" "Remainder"
@ -508,7 +537,6 @@
{ {
"id": "a3bfc1673c0526e06d3ac698", "id": "a3bfc1673c0526e06d3ac698",
"title": "Sum All Primes", "title": "Sum All Primes",
"difficulty": "2.10",
"description": [ "description": [
"Sum all the prime numbers up to and including the provided number.", "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.", "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.",
@ -523,9 +551,9 @@
"sumPrimes(10);" "sumPrimes(10);"
], ],
"tests": [ "tests": [
"expect(sumPrimes(10)).to.be.a('number');", "assert.deepEqual(typeof(sumPrimes(10)), \"number\", 'message: <code>sumPrimes()</code> should return a number.');",
"expect(sumPrimes(10)).to.equal(17);", "assert.deepEqual(sumPrimes(10), 17, 'message: <code>sumPrimes(10)</code> should return 17.');",
"expect(sumPrimes(977)).to.equal(73156);" "assert.deepEqual(sumPrimes(977), 73156, 'message: <code>sumPrimes(977)</code> should return 73156.');"
], ],
"MDNlinks": [ "MDNlinks": [
"For Loops", "For Loops",
@ -547,11 +575,10 @@
{ {
"id": "ae9defd7acaf69703ab432ea", "id": "ae9defd7acaf69703ab432ea",
"title": "Smallest Common Multiple", "title": "Smallest Common Multiple",
"difficulty": "2.11",
"description": [ "description": [
"Find the smallest number that is evenly divisible by all numbers in the provided range.", "Find the smallest common multiple of the provided parameters that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters.",
"In other words, given the range [3,7], you will need to find the least common multiple of 3, 4, 5, 6, and 7.",
"The range will be an array of two numbers that will not necessarily be in numerical order.", "The range will be an array of two numbers that will not necessarily be in numerical order.",
"e.g. for 1 and 3 - find the smallest common multiple of both 1 and 3 that is evenly divisible by all numbers <em>between</em> 1 and 3.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
], ],
"challengeSeed": [ "challengeSeed": [
@ -563,10 +590,10 @@
"smallestCommons([1,5]);" "smallestCommons([1,5]);"
], ],
"tests": [ "tests": [
"expect(smallestCommons([1,5])).to.be.a('number');", "assert.deepEqual(typeof(smallestCommons([1, 5])), \"number\", 'message: <code>smallestCommons()</code> should return a number.');",
"expect(smallestCommons([1,5])).to.equal(60);", "assert.deepEqual(smallestCommons([1, 5]), 60, 'message: <code>smallestCommons([1, 5])</code> should return 60.');",
"expect(smallestCommons([5,1])).to.equal(60);", "assert.deepEqual(smallestCommons([5, 1]), 60, 'message: <code>smallestCommons([5, 1])</code> should return 60.');",
"expect(smallestCommons([1,13])).to.equal(360360);" "assert.deepEqual(smallestCommons([1, 13]), 360360, 'message: <code>smallestCommons([1, 13])</code> should return 360360.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Smallest Common Multiple" "Smallest Common Multiple"
@ -587,7 +614,6 @@
{ {
"id": "a6e40f1041b06c996f7b2406", "id": "a6e40f1041b06c996f7b2406",
"title": "Finders Keepers", "title": "Finders Keepers",
"difficulty": "2.12",
"description": [ "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).", "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).",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -601,8 +627,8 @@
"find([1, 2, 3, 4], function(num){ return num % 2 === 0; });" "find([1, 2, 3, 4], function(num){ return num % 2 === 0; });"
], ],
"tests": [ "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, 8, 9, 10], function(num) { return num % 2 === 0; }), 8, 'message: <code>find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; })</code> should return 8.');",
"assert.strictEqual(find([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'should return undefined if not found');" "assert.strictEqual(find([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'message: <code>find([1, 3, 5, 9], function(num) { return num % 2 === 0; })</code> should return undefined.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.some()" "Array.some()"
@ -623,7 +649,6 @@
{ {
"id": "a5deed1811a43193f9f1c841", "id": "a5deed1811a43193f9f1c841",
"title": "Drop it", "title": "Drop it",
"difficulty": "2.13",
"description": [ "description": [
"Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true.", "Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -637,9 +662,10 @@
"drop([1, 2, 3], function(n) {return n < 3; });" "drop([1, 2, 3], function(n) {return n < 3; });"
], ],
"tests": [ "tests": [
"expect(drop([1, 2, 3, 4], function(n) {return n >= 3; })).to.eqls([3, 4]);", "assert.deepEqual(drop([1, 2, 3, 4], function(n) {return n>= 3;}), [3, 4], 'message: <code>drop([1, 2, 3, 4], function(n) {return n>= 3;})</code> should return <code>[3, 4]</code>.');",
"expect(drop([1, 2, 3], function(n) {return n > 0; })).to.eqls([1, 2, 3]);", "assert.deepEqual(drop([1, 2, 3], function(n) {return n > 0; }), [1, 2, 3], 'message: <code>drop([1, 2, 3], function(n) {return n > 0; })</code> should return <code>[1, 2, 3]</code>.');",
"expect(drop([1, 2, 3, 4], function(n) {return n > 5; })).to.eqls([]);" "assert.deepEqual(drop([1, 2, 3, 4], function(n) {return n > 5;}), [], 'message: <code>drop([1, 2, 3, 4], function(n) {return n > 5;})</code> should return <code>[]</code>.');",
"assert.deepEqual(drop([1, 2, 3, 7, 4], function(n) {return n > 3}), [7, 4], 'message: <code>drop([1, 2, 3, 7, 4], function(n) {return n>= 3})</code> should return <code>[7, 4]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Arguments object", "Arguments object",
@ -661,7 +687,6 @@
{ {
"id": "ab306dbdcc907c7ddfc30830", "id": "ab306dbdcc907c7ddfc30830",
"title": "Steamroller", "title": "Steamroller",
"difficulty": "2.14",
"description": [ "description": [
"Flatten a nested array. You must account for varying levels of nesting.", "Flatten a nested array. You must account for varying levels of nesting.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
@ -675,10 +700,10 @@
"steamroller([1, [2], [3, [[4]]]]);" "steamroller([1, [2], [3, [[4]]]]);"
], ],
"tests": [ "tests": [
"assert.deepEqual(steamroller([[['a']], [['b']]]), ['a', 'b'], 'should flatten nested arrays');", "assert.deepEqual(steamroller([[[\"a\"]], [[\"b\"]]]), [\"a\", \"b\"], 'message: <code>steamroller([[[\"a\"]], [[\"b\"]]])</code> should return <code>[\"a\", \"b\"]</code>.');",
"assert.deepEqual(steamroller([1, [2], [3, [[4]]]]), [1, 2, 3, 4], 'should flatten nested arrays');", "assert.deepEqual(steamroller([1, [2], [3, [[4]]]]), [1, 2, 3, 4], 'message: <code>steamroller([1, [2], [3, [[4]]]])</code> should return <code>[1, 2, 3, 4]</code>.');",
"assert.deepEqual(steamroller([1, [], [3, [[4]]]]), [1, 3, 4], 'should work with empty arrays');", "assert.deepEqual(steamroller([1, [], [3, [[4]]]]), [1, 3, 4], 'message: <code>steamroller([1, [], [3, [[4]]]])</code> should return <code>[1, 3, 4]</code>.');",
"assert.deepEqual(steamroller([1, {}, [3, [[4]]]]), [1, {}, 3, 4], 'should work with actual objects');" "assert.deepEqual(steamroller([1, {}, [3, [[4]]]]), [1, {}, 3, 4], 'message: <code>steamroller([1, {}, [3, [[4]]]])</code> should return <code>[1, {}, 3, 4]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.isArray()" "Array.isArray()"
@ -699,7 +724,6 @@
{ {
"id": "a8d97bd4c764e91f9d2bda01", "id": "a8d97bd4c764e91f9d2bda01",
"title": "Binary Agents", "title": "Binary Agents",
"difficulty": "2.15",
"description": [ "description": [
"Return an English translated sentence of the passed binary string.", "Return an English translated sentence of the passed binary string.",
"The binary string will be space separated.", "The binary string will be space separated.",
@ -710,11 +734,11 @@
" return 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');" "binaryAgent(\"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111\");"
], ],
"tests": [ "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!?\");", "assert.deepEqual(binaryAgent('01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111'), \"Aren't bonfires fun!?\", 'message: <code>binaryAgent(\"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111\")</code> should return \"Aren&#39;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!\");" "assert.deepEqual(binaryAgent(\"01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001\"), \"I love FreeCodeCamp!\", 'message: <code>binaryAgent(\"01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001\"</code> should return \"I love FreeCodeCamp!\"');"
], ],
"MDNlinks": [ "MDNlinks": [
"String.charCodeAt()", "String.charCodeAt()",
@ -736,7 +760,6 @@
{ {
"id": "a10d2431ad0c6a099a4b8b52", "id": "a10d2431ad0c6a099a4b8b52",
"title": "Everything Be True", "title": "Everything Be True",
"difficulty": "2.21",
"description": [ "description": [
"Check if the predicate (second argument) returns truthy (defined) for all elements of a collection (first argument).", "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.", "For this, check to see if the property defined in the second argument is present on every element of the collection.",
@ -749,12 +772,12 @@
" return pre;", " return pre;",
"}", "}",
"", "",
"every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex');" "every([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], \"sex\");"
], ],
"tests": [ "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\"), true, 'message: <code>every([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], \"sex\")</code> should return true.');",
"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');", "assert.strictEqual(every([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], {\"sex\": \"female\"}), false, 'message: <code>every([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], {\"sex\": \"female\"})</code> should return false.');",
"assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'female'}, {'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');" "assert.strictEqual(every([{\"user\": \"Tinky-Winky\", \"sex\": \"female\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], {\"sex\": \"female\"}), false, 'message: <code>every([{\"user\": \"Tinky-Winky\", \"sex\": \"female\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], {\"sex\": \"female\"})</code> should return false.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Object.hasOwnProperty()", "Object.hasOwnProperty()",
@ -776,10 +799,12 @@
{ {
"id": "a97fd23d9b809dac9921074f", "id": "a97fd23d9b809dac9921074f",
"title": "Arguments Optional", "title": "Arguments Optional",
"difficulty": "2.22",
"description": [ "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.", "Create a function that sums two arguments together. If only one argument is provided, then return a function that expects one argument and returns 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 <code>var sum2And = add(2); return sum2And(3); // 5</code>", "For example, <code>add(2, 3)</code> should return <code>5</code>, and <code>add(2)</code> should return a function.",
"Calling this returned function with a single argument will then return the sum:",
"<code>var sumTwoAnd = add(2);</code>",
"<code>sumTwoAnd(3)</code> returns <code>5</code>.",
"If either argument isn't a valid number, return undefined.", "If either argument isn't a valid number, return undefined.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code." "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
], ],
@ -791,11 +816,11 @@
"add(2,3);" "add(2,3);"
], ],
"tests": [ "tests": [
"expect(add(2, 3)).to.equal(5);", "assert.deepEqual(add(2, 3), 5, 'message: <code>add(2, 3)</code> should return 5.');",
"expect(add(2)(3)).to.equal(5);", "assert.deepEqual(add(2)(3), 5, 'message: <code>add(2)(3)</code> should return 5.');",
"expect(add('http://bit.ly/IqT6zt')).to.be.undefined;", "assert.isUndefined(add(\"http://bit.ly/IqT6zt\"), 'message: <code>add(\"http://bit.ly/IqT6zt\")</code> should return undefined.');",
"expect(add(2, '3')).to.be.undefined;", "assert.isUndefined(add(2, \"3\"), 'message: <code>add(2, \"3\")</code> should return undefined.');",
"expect(add(2)([3])).to.be.undefined;" "assert.isUndefined(add(2)([3]), 'message: <code>add(2)([3])</code> should return undefined.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Global Function Object", "Global Function Object",

View File

@ -1,26 +1,123 @@
{ {
"name": "Intermediate Front End Development Projects", "name": "Intermediate Front End Development Projects",
"order": 0.015, "order": 11,
"challenges": [ "challenges": [
{ {
"id": "bd7158d8c442eddfaeb5bd10",
"title": "Show the Local Weather",
"challengeSeed": ["126415127"],
"description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/AdventureBear/full/yNBJRj' target='_blank'>http://codepen.io/AdventureBear/full/yNBJRj</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can see the weather in my current location.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can see an icon depending on the weather.",
"<span class='text-info'>Bonus User Story:</span> As a user, I see a different background image (e.g. snowy mountain, hot desert) depending on the weather.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can push a button to toggle between Fahrenheit and Celsius.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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 from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"type": "zipline",
"challengeType": 3,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "Покажите местную погоду",
"descriptionRu": [
"<span class='text-info'>Задание:</span> Создайте <a href='http://codepen.io' target='_blank'>CodePen.io</a> который успешно копирует вот этот: <a href='http://codepen.io/AdventureBear/full/yNBJRj' target='_blank'>http://codepen.io/AdventureBear/full/yNBJRj</a>.",
"<span class='text-info'>Правило #1:</span> Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.",
"<span class='text-info'>Правило #2:</span> Можете использовать любые библиотеки или API, которые потребуются.",
"<span class='text-info'>Правило #3:</span> Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.",
"Реализуйте следующие <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>пользовательские истории</a>, сделайте также бонусные по желанию:",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу узнать погоду с учетом моего текущего местоположения.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу в зависимости от погоды видеть различные температурные значки.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу в зависимости от погоды видеть различные фоновые изображения (снежные горы, знойная пустыня).",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу нажать на кнопку чтобы переключится между градусами по Цельсию или по Фаренгейту.",
"Если что-то не получается, воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>.",
"Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.",
"Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "bd7158d8c442eddfaeb5bd1f",
"title": "Use the Twitch.tv JSON API",
"challengeSeed": ["126411564"],
"description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/GJKRxZ' target='_blank'>http://codepen.io/GeoffStorbeck/full/GJKRxZ</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can see whether Free Code Camp is currently streaming on Twitch.tv.",
"<span class='text-info'>User Story:</span> As a user, I can click the status output and be sent directly to the Free Code Camp's Twitch.tv channel.",
"<span class='text-info'>User Story:</span> As a user, if Free Code Camp is streaming, I can see additional details about what they are streaming.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can search through the streams listed.",
"<span class='text-info'>Bonus User Story:</span> As a user, I will see a placeholder notification if a streamer has closed their Twitch account. You can verify this works by adding brunofin and comster404 to your array of Twitch streamers.",
"<span class='text-info'>Hint:</span> Here's an example call to Twitch.tv's JSON API: <code>https://api.twitch.tv/kraken/streams/freecodecamp</code>.",
"<span class='text-info'>Hint:</span> The relevant documentation about this API call is here: <a href='https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel' target='_blank'>https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel</a>.",
"<span class='text-info'>Hint:</span> Here's an array of the Twitch.tv usernames of people who regularly stream coding: <code>[\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]</code>",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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 from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"type": "zipline",
"challengeType": 3,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "Используйте Twitch.tv JSON API",
"descriptionRu": [
"<span class='text-info'>Задание:</span> Создайте <a href='http://codepen.io' target='_blank'>CodePen.io</a> который успешно копирует вот этот: <a href='http://codepen.io/GeoffStorbeck/full/GJKRxZ' target='_blank'>http://codepen.io/GeoffStorbeck/full/GJKRxZ</a>.",
"<span class='text-info'>Правило #1:</span> Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.",
"<span class='text-info'>Правило #2:</span> Можете использовать любые библиотеки или API, которые потребуются.",
"<span class='text-info'>Правило #3:</span> Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.",
"Реализуйте следующие <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>пользовательские истории</a>, сделайте также бонусные по желанию:",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу увидеть идет ли в данный момент на Twitch.tv трансляция Free Code Camp.",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу, кликнув на описание трансляции, перейти на канал Free Code Camp.",
"<span class='text-info'>Пользовательская история:</span> В качестве пользователя, я могу видеть дополнительную информацию о текущей трансляции Free Code Camp.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу произвести поиск среди перечисленных каналов.",
"<span class='text-info'>Бонусная пользовательская история:</span> В качестве пользователя, я могу видеть уведомление, если создатель канала закрыл свой аккаунт на Twitch.tv. Добавьте в массив имена пользователей brunofin и comster404, чтобы убедиться, что эта функция реализована правильно.",
"<span class='text-info'>Подсказка:</span> Пример запроса к Twitch.tv JSON API: <code>https://api.twitch.tv/kraken/streams/freecodecamp</code>.",
"<span class='text-info'>Подсказка:</span> Документацию об этом запросе можно найти по ссылке: <a href='https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel' target='_blank'>https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel</a>.",
"<span class='text-info'>Подсказка:</span> В этом массиве приведены имена пользователей, которые регулярно пишут код онлайн: <code>[\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"comster404\",\"brunofin\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]</code>",
"Если что-то не получается, воспользуйтесь <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a>.",
"Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.",
"Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "bd7158d8c442eddfaeb5bd18", "id": "bd7158d8c442eddfaeb5bd18",
"title": "Stylize Stories on Camper News", "title": "Stylize Stories on Camper News",
"difficulty": 1.02,
"challengeSeed": ["126415129"], "challengeSeed": ["126415129"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/Wveezv' target='_blank'>http://codepen.io/GeoffStorbeck/full/Wveezv</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/MarufSarker/full/ZGPZLq/' target='_blank'>http://codepen.io/MarufSarker/full/ZGPZLq/</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.", "<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.", "<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.", "<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:", "Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can browse recent posts from Camper News.", "<span class='text-info'>User Story:</span> As a user, I can browse recent posts from Camper News.",
"<span class='text-info'>User Story:</span> As a user, I can click on a post to be taken to the story's original URL.", "<span class='text-info'>User Story:</span> As a user, I can click on a post to be taken to the story's original URL.",
"<span class='text-info'>User Story:</span> As a user, I can click a link to go directly to the post's discussion page.",
"<span class='text-info'>Bonus User Story:</span> As a user, I can see how many upvotes each story has.", "<span class='text-info'>Bonus User Story:</span> As a user, I can see how many upvotes each story has.",
"<span class='text-info'>Hint:</span> Here's the Camper News Hot Stories API endpoint: <code>http://www.freecodecamp.com/news/hot</code>.", "<span class='text-info'>Hint:</span> Here's the Camper News Hot Stories API endpoint: <code>http://www.freecodecamp.com/news/hot</code>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -38,8 +135,7 @@
}, },
{ {
"id": "bd7158d8c442eddfaeb5bd19", "id": "bd7158d8c442eddfaeb5bd19",
"title": "Wikipedia Viewer", "title": "Build a Wikipedia Viewer",
"difficulty": 1.03,
"challengeSeed": ["126415131"], "challengeSeed": ["126415131"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/MwgQea' target='_blank'>http://codepen.io/GeoffStorbeck/full/MwgQea</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/MwgQea' target='_blank'>http://codepen.io/GeoffStorbeck/full/MwgQea</a>.",
@ -53,39 +149,7 @@
"<span class='text-info'>Hint:</span> Here's an entry on using Wikipedia's API: <code>http://www.mediawiki.org/wiki/API:Main_page</code>.", "<span class='text-info'>Hint:</span> Here's an entry on using Wikipedia's API: <code>http://www.mediawiki.org/wiki/API:Main_page</code>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
],
"type": "zipline",
"challengeType": 3,
"tests": [],
"nameCn": "",
"descriptionCn": [],
"nameFr": "",
"descriptionFr": [],
"nameRu": "",
"descriptionRu": [],
"nameEs": "",
"descriptionEs": [],
"namePt": "",
"descriptionPt": []
},
{
"id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator",
"difficulty": 1.05,
"challengeSeed": ["126411565"],
"description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/GeoffStorbeck/full/zxgaqw' target='_blank'>http://codepen.io/GeoffStorbeck/full/zxgaqw</a>.",
"<span class='text-info'>Rule #1:</span> Don't look at the example project's code on CodePen. Figure it out for yourself.",
"<span class='text-info'>Rule #2:</span> You may use whichever libraries or APIs you need.",
"<span class='text-info'>Rule #3:</span> Reverse engineer the example project's functionality, and also feel free to personalize it.",
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
"<span class='text-info'>User Story:</span> As a user, I can add, subtract, multiply and divide two numbers.",
"<span class='text-info'>Bonus User Story:</span> I can clear the input field with a clear button.",
"<span class='text-info'>Bonus User Story:</span> I can keep chaining mathematical operations together until I hit the clear button, and the calculator will tell me the correct output.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -104,7 +168,6 @@
{ {
"id": "bd7158d8c442eedfaeb5bd1c", "id": "bd7158d8c442eedfaeb5bd1c",
"title": "Build a Tic Tac Toe Game", "title": "Build a Tic Tac Toe Game",
"difficulty": 1.06,
"challengeSeed": ["126415123"], "challengeSeed": ["126415123"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/alex-dixon/full/JogOpQ/' target='_blank'>http://codepen.io/alex-dixon/full/JogOpQ/</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/alex-dixon/full/JogOpQ/' target='_blank'>http://codepen.io/alex-dixon/full/JogOpQ/</a>.",
@ -118,7 +181,7 @@
"<span class='text-info'>Bonus User Story:</span> As a user, I can choose whether I want to play as X or O.", "<span class='text-info'>Bonus User Story:</span> As a user, I can choose whether I want to play as X or O.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,
@ -137,7 +200,6 @@
{ {
"id": "bd7158d8c442eddfaeb5bd1c", "id": "bd7158d8c442eddfaeb5bd1c",
"title": "Build a Simon Game", "title": "Build a Simon Game",
"difficulty": 1.07,
"challengeSeed": ["137213633"], "challengeSeed": ["137213633"],
"description": [ "description": [
"<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/Em-Ant/full/QbRyqq/' target='_blank'>http://codepen.io/dting/full/QbRyqq/</a>.", "<span class='text-info'>Objective:</span> Build a <a href='http://codepen.io' target='_blank'>CodePen.io</a> app that successfully reverse-engineers this: <a href='http://codepen.io/Em-Ant/full/QbRyqq/' target='_blank'>http://codepen.io/dting/full/QbRyqq/</a>.",
@ -157,7 +219,7 @@
"<span class='text-info'>Hint:</span> Here are mp3s you can use for each button: <code>https://s3.amazonaws.com/freecodecamp/simonSound1.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound2.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound3.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound4.mp3</code>.", "<span class='text-info'>Hint:</span> Here are mp3s you can use for each button: <code>https://s3.amazonaws.com/freecodecamp/simonSound1.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound2.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound3.mp3</code>, <code>https://s3.amazonaws.com/freecodecamp/simonSound4.mp3</code>.",
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.", "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
"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.", "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.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>" "If you'd like immediate feedback on your project from fellow campers, click this button and paste in a link to your CodePen project. <br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
], ],
"type": "zipline", "type": "zipline",
"challengeType": 3, "challengeType": 3,

View File

@ -1,11 +1,10 @@
{ {
"name": "jQuery", "name": "jQuery",
"order": 0.004, "order": 4,
"challenges": [ "challenges": [
{ {
"id": "bad87fee1348bd9acdd08826", "id": "bad87fee1348bd9acdd08826",
"title": "Learn how Script Tags and Document Ready Work", "title": "Learn how Script Tags and Document Ready Work",
"difficulty": 3.01,
"description": [ "description": [
"Now we're ready to learn jQuery, the most popular JavaScript tool of all time. Don't worry about JavaScript itself - we will cover it soon.", "Now we're ready to learn jQuery, the most popular JavaScript tool of all time. Don't worry about JavaScript itself - we will cover it soon.",
"Before we can start using jQuery, we need to add some things to our HTML.", "Before we can start using jQuery, we need to add some things to our HTML.",
@ -16,8 +15,8 @@
"tests": [ "tests": [
"assert(editor.match(/<script>/g), 'Create a <code>script</code> element.')", "assert(editor.match(/<script>/g), 'Create a <code>script</code> element.')",
"assert(editor.match(/<\\/script>/g) && editor.match(/<script/g) && editor.match(/<\\/script>/g).length === editor.match(/<script/g).length, 'Make sure your <code>script</code> element has a closing tag.')", "assert(editor.match(/<\\/script>/g) && editor.match(/<script/g) && editor.match(/<\\/script>/g).length === editor.match(/<script/g).length, 'Make sure your <code>script</code> element has a closing tag.')",
"assert(editor.match(/\\$\\s*?\\(\\s*?document\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'Add <code>$(document).ready(function() {</code> to the beginning of your <code>script</code> element.')", "assert(editor.match(/\\$\\s*?\\(\\s*?document\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'You should add <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> to the beginning of your <code>script</code> element.')",
"assert(editor.match(/\\n*?\\s*?\\}\\s*?\\);/g), 'Close your <code>$(document).ready(function() {</code> function with <code>});</code>.')" "assert(editor.match(/\\n*?\\s*?\\}\\s*?\\);/g), 'Close your <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> function with <code>}&#41;;</code>.')"
], ],
"challengeSeed": [ "challengeSeed": [
"", "",
@ -52,13 +51,12 @@
{ {
"id": "bad87fee1348bd9bedc08826", "id": "bad87fee1348bd9bedc08826",
"title": "Target HTML Elements with Selectors Using jQuery", "title": "Target HTML Elements with Selectors Using jQuery",
"difficulty": 3.02,
"description": [ "description": [
"Now we have a <code>document ready function</code>. We'll learn more about <code>functions</code> later. The important thing to know is that code you put inside this <code>function</code> will run as soon as your browser has loaded your page.", "Now we have a <code>document ready function</code>. We'll learn more about <code>functions</code> later. The important thing to know is that code you put inside this <code>function</code> will run as soon as your browser has loaded your page.",
"This is important because without your <code>document ready function</code>, your code may run before your HTML is rendered, which would cause bugs.", "This is important because without your <code>document ready function</code>, your code may run before your HTML is rendered, which would cause bugs.",
"Now let's write our first jQuery statement. All jQuery functions start with a <code>$</code>, usually referred to as a <code>dollar sign operator</code>, or simply as <code>bling</code>.", "Now let's write our first jQuery statement. All jQuery functions start with a <code>$</code>, usually referred to as a <code>dollar sign operator</code>, or simply as <code>bling</code>.",
"jQuery often selects an HTML element with a <code>selector</code>, then does something to that element.", "jQuery often selects an HTML element with a <code>selector</code>, then does something to that element.",
"For example, let's make all of your <code>button</code> elements bounce. Just add this code inside your <code>document ready function</code>: <code>$(\"button\").addClass(\"animated bounce\")</code>.", "For example, let's make all of your <code>button</code> elements bounce. Just add this code inside your document ready function: <code>$(\"button\").addClass(\"animated bounce\")</code>.",
"Note that we've already included both the jQuery library and the Animate.css library in your code editor. So you are using jQuery to apply the Animate.css <code>bounce</code> class to your <code>button</code> elements." "Note that we've already included both the jQuery library and the Animate.css library in your code editor. So you are using jQuery to apply the Animate.css <code>bounce</code> class to your <code>button</code> elements."
], ],
"tests": [ "tests": [
@ -102,7 +100,6 @@
{ {
"id": "bad87fee1348bd9aedc08826", "id": "bad87fee1348bd9aedc08826",
"title": "Target Elements by Class Using jQuery", "title": "Target Elements by Class Using jQuery",
"difficulty": 3.03,
"description": [ "description": [
"You see how we made all of your <code>button</code> elements bounce? We selected them with <code>$(\"button\")</code>, then we added some CSS classes to them with <code>.addClass(\"animated bounce\");</code>.", "You see how we made all of your <code>button</code> elements bounce? We selected them with <code>$(\"button\")</code>, then we added some CSS classes to them with <code>.addClass(\"animated bounce\");</code>.",
"You just used jQuery's <code>.addClass()</code> function, which allows you to add classes to elements.", "You just used jQuery's <code>.addClass()</code> function, which allows you to add classes to elements.",
@ -152,7 +149,6 @@
{ {
"id": "bad87fee1348bd9aeda08826", "id": "bad87fee1348bd9aeda08826",
"title": "Target Elements by ID Using jQuery", "title": "Target Elements by ID Using jQuery",
"difficulty": 3.04,
"description": [ "description": [
"You can also target elements by their id attributes.", "You can also target elements by their id attributes.",
"First target your <code>button</code> element with the id <code>target3</code> by using the <code>$(\"#target3\")</code> selector.", "First target your <code>button</code> element with the id <code>target3</code> by using the <code>$(\"#target3\")</code> selector.",
@ -161,8 +157,8 @@
"Here's how you'd make the <code>button</code> element with the id <code>target6</code> fade out: <code>$(\"#target6\").addClass(\"animated fadeOut\")</code>." "Here's how you'd make the <code>button</code> element with the id <code>target6</code> fade out: <code>$(\"#target6\").addClass(\"animated fadeOut\")</code>."
], ],
"tests": [ "tests": [
"assert($(\"#target3\").hasClass(\"animated\"), 'Select the <code>button</code>element with the <code>id</code> of <code>target3</code> and use the jQuery <code>addClass&#40&#41</code> function to give it the class of <code>animated</code>.');", "assert($(\"#target3\").hasClass(\"animated\"), 'Select the <code>button</code>element with the <code>id</code> of <code>target3</code> and use the jQuery <code>addClass&#40&#41</code> function to give it the class of <code>animated</code>.')",
"assert($(\"#target3\").hasClass(\"fadeOut\") || $(\"#target3\").hasClass(\"fadeout\"), 'Target the element with the id <code>target3</code> and use the jQuery <code>addClass&#40&#41</code> function to give it the class <code>fadeOut</code>.')", "assert(($(\"#target3\").hasClass(\"fadeOut\") || $(\"#target3\").hasClass(\"fadeout\")) && editor.match(/\\$\\(.#target3.\\)/g), 'Target the element with the id <code>target3</code> and use the jQuery <code>addClass&#40&#41</code> function to give it the class <code>fadeOut</code>.')",
"assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')" "assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -204,7 +200,6 @@
{ {
"id": "bad87fee1348bd9aeda08726", "id": "bad87fee1348bd9aeda08726",
"title": "Delete your jQuery Functions", "title": "Delete your jQuery Functions",
"difficulty": 3.05,
"description": [ "description": [
"These animations were cool at first, but now they're getting kind of distracting.", "These animations were cool at first, but now they're getting kind of distracting.",
"Delete all three of these jQuery functions from your <code>document ready function</code>, but leave your <code>document ready function</code> itself intact." "Delete all three of these jQuery functions from your <code>document ready function</code>, but leave your <code>document ready function</code> itself intact."
@ -256,16 +251,15 @@
{ {
"id": "bad87fee1348bd9aed908626", "id": "bad87fee1348bd9aed908626",
"title": "Target the same element with multiple jQuery Selectors", "title": "Target the same element with multiple jQuery Selectors",
"difficulty": 3.06,
"description": [ "description": [
"Now you know three ways of targeting elements: by type: <code>$(\"button\")</code>, by class: <code>$(\".btn\")</code>, and by id <code>$(\"#target1\")</code>.", "Now you know three ways of targeting elements: by type: <code>$(\"button\")</code>, by class: <code>$(\".btn\")</code>, and by id <code>$(\"#target1\")</code>.",
"Use each of these jQuery selectors to target your <code>button</code> element with the class <code>btn</code> and the id <code>target1</code>.", "Use each of these jQuery selectors to target your <code>button</code> element with the class <code>btn</code> and the id <code>target1</code>.",
"Use the <code>addClass()</code> jQuery function to give the element one new class for each selector: <code>animated</code>, <code>shake</code>, and <code>btn-primary</code>." "Use the <code>addClass()</code> jQuery function to give the element one new class for each selector: <code>animated</code>, <code>shake</code>, and <code>btn-primary</code>."
], ],
"tests": [ "tests": [
"assert(editor.match(/\\$\\(.*button/g), 'Use the <code>$&#40\"button\"&#41</code> selector.')", "assert(editor.match(/\\$\\s*?\\(\\s*?(?:'|\")\\s*?button\\s*?(?:'|\")/gi), 'Use the <code>$&#40\"button\"&#41</code> selector.')",
"assert(editor.match(/\\$\\(.*\\.btn/g), 'Use the <code>$&#40\".btn\"&#41</code> selector.')", "assert(editor.match(/\\$\\s*?\\(\\s*?(?:'|\")\\s*?\\.btn\\s*?(?:'|\")/gi), 'Use the <code>$&#40\".btn\"&#41</code> selector.')",
"assert(editor.match(/\\$\\(.*#target1/g), 'Use the <code>$&#40\"#target1\"&#41</code> selector.')", "assert(editor.match(/\\$\\s*?\\(\\s*?(?:'|\")\\s*?#target1\\s*?(?:'|\")/gi), 'Use the <code>$&#40\"#target1\"&#41</code> selector.')",
"assert(editor.match(/addClass/g) && editor.match(/addClass/g).length > 2, 'Only add one class with each of your three selectors.')", "assert(editor.match(/addClass/g) && editor.match(/addClass/g).length > 2, 'Only add one class with each of your three selectors.')",
"assert($(\"#target1\").hasClass(\"animated\") && $(\"#target1\").hasClass(\"shake\") && $(\"#target1\").hasClass(\"btn-primary\"), 'Your <code>#target1</code> element should have the classes <code>animated</code>&#130; <code>shake</code> and <code>btn-primary</code>.')", "assert($(\"#target1\").hasClass(\"animated\") && $(\"#target1\").hasClass(\"shake\") && $(\"#target1\").hasClass(\"btn-primary\"), 'Your <code>#target1</code> element should have the classes <code>animated</code>&#130; <code>shake</code> and <code>btn-primary</code>.')",
"assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')" "assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')"
@ -307,15 +301,15 @@
{ {
"id": "bad87fee1348bd9aed918626", "id": "bad87fee1348bd9aed918626",
"title": "Remove Classes from an element with jQuery", "title": "Remove Classes from an element with jQuery",
"difficulty": 3.07,
"description": [ "description": [
"In the same way you can add classes to an element with jQuery's <code>addClass()</code> function, you can remove them with jQuery's <code>removeClass()</code> function.", "In the same way you can add classes to an element with jQuery's <code>addClass()</code> function, you can remove them with jQuery's <code>removeClass()</code> function.",
"Let's remove the <code>btn-default</code> class from all of our <code>button</code> elements.", "Here's how you would do this for a specific button, add <code>$(\"#target2\").removeClass(\"btn-default\");</code>",
"Here's how you would do this for a specific button, add <code>$(\"#target2\").removeClass(\"btn-default\");</code>" "Let's remove the <code>btn-default</code> class from all of our <code>button</code> elements."
], ],
"tests": [ "tests": [
"assert($(\".btn-default\").length === 0, 'Remove the <code>btn-default</code> class from all of your <code>button</code> elements.')", "assert($(\".btn-default\").length === 0, 'Remove the <code>btn-default</code> class from all of your <code>button</code> elements.')",
"assert(editor.match(/btn btn-default/g), 'Only use jQuery to remove this class from the element.')" "assert(editor.match(/btn btn-default/g), 'Only use jQuery to remove this class from the element.')",
"assert(editor.match(/\\.[\\v\\s]*removeClass[\\s\\v]*\\([\\s\\v]*('|\")\\s*btn-default\\s*('|\")[\\s\\v]*\\)/gm), 'Only remove the <code>btn-default</code> class.')"
], ],
"challengeSeed": [ "challengeSeed": [
"fccss", "fccss",
@ -357,14 +351,13 @@
{ {
"id": "bad87fee1348bd9aed908826", "id": "bad87fee1348bd9aed908826",
"title": "Change the CSS of an Element Using jQuery", "title": "Change the CSS of an Element Using jQuery",
"difficulty": 3.08,
"description": [ "description": [
"We can also change the CSS of an HTML element directly with jQuery.", "We can also change the CSS of an HTML element directly with jQuery.",
"Delete your jQuery selectors, leaving an empty <code>document ready function</code>.",
"Select <code>target1</code> and change its color to red.",
"jQuery has a function called <code>.css()</code> that allows you to change the CSS of an element.", "jQuery has a function called <code>.css()</code> that allows you to change the CSS of an element.",
"Here's how we would change its color to blue: <code>$(\"#target1\").css(\"color\", \"blue\");</code>", "Here's how we would change its color to blue: <code>$(\"#target1\").css(\"color\", \"blue\");</code>",
"This is slightly different from a normal CSS declaration, because the CSS property and its value are in quotes, and separated with a comma instead of a colon." "This is slightly different from a normal CSS declaration, because the CSS property and its value are in quotes, and separated with a comma instead of a colon.",
"Delete your jQuery selectors, leaving an empty <code>document ready function</code>.",
"Select <code>target1</code> and change its color to red."
], ],
"tests": [ "tests": [
"assert($(\"#target1\").css(\"color\") === 'rgb(255, 0, 0)', 'Your <code>target1</code> element should have red text.')", "assert($(\"#target1\").css(\"color\") === 'rgb(255, 0, 0)', 'Your <code>target1</code> element should have red text.')",
@ -411,7 +404,6 @@
{ {
"id": "bad87fee1348bd9aed808826", "id": "bad87fee1348bd9aed808826",
"title": "Disable an Element Using jQuery", "title": "Disable an Element Using jQuery",
"difficulty": 3.09,
"description": [ "description": [
"You can also change the non-CSS properties of HTML elements with jQuery. For example, you can disable buttons.", "You can also change the non-CSS properties of HTML elements with jQuery. For example, you can disable buttons.",
"When you disable a button, it will become grayed-out and can no longer be clicked.", "When you disable a button, it will become grayed-out and can no longer be clicked.",
@ -462,7 +454,6 @@
{ {
"id": "bad87fee1348bd9aed708826", "id": "bad87fee1348bd9aed708826",
"title": "Remove an Element Using jQuery", "title": "Remove an Element Using jQuery",
"difficulty": 3.10,
"description": [ "description": [
"Now let's remove an HTML element from your page using jQuery.", "Now let's remove an HTML element from your page using jQuery.",
"jQuery has a function called <code>.remove()</code> that will remove an HTML element entirely", "jQuery has a function called <code>.remove()</code> that will remove an HTML element entirely",
@ -511,7 +502,6 @@
{ {
"id": "bad87fee1348bd9aed608826", "id": "bad87fee1348bd9aed608826",
"title": "Use appendTo to Move Elements with jQuery", "title": "Use appendTo to Move Elements with jQuery",
"difficulty": 3.11,
"description": [ "description": [
"Now let's try moving elements from one <code>div</code> to another.", "Now let's try moving elements from one <code>div</code> to another.",
"jQuery has a function called <code>appendTo()</code> that allows you to select HTML elements and append them to another element.", "jQuery has a function called <code>appendTo()</code> that allows you to select HTML elements and append them to another element.",
@ -563,7 +553,6 @@
{ {
"id": "bad87fee1348bd9aed508826", "id": "bad87fee1348bd9aed508826",
"title": "Clone an Element Using jQuery", "title": "Clone an Element Using jQuery",
"difficulty": 3.12,
"description": [ "description": [
"In addition to moving elements, you can also copy them from one place to another.", "In addition to moving elements, you can also copy them from one place to another.",
"jQuery has a function called <code>clone()</code> that makes a copy of an element.", "jQuery has a function called <code>clone()</code> that makes a copy of an element.",
@ -617,17 +606,17 @@
{ {
"id": "bad87fee1348bd9aed308826", "id": "bad87fee1348bd9aed308826",
"title": "Target the Parent of an Element Using jQuery", "title": "Target the Parent of an Element Using jQuery",
"difficulty": 3.13,
"description": [ "description": [
"Every HTML element has a <code>parent</code> element from which it <code>inherits</code> properties.", "Every HTML element has a <code>parent</code> element from which it <code>inherits</code> properties.",
"For example, your <code>jQuery Playground</code> <code>h3</code> element has the parent element of <code>&#60;div class=\"container-fluid\"&#62</code>, which itself has the parent <code>body</code>.", "For example, your <code>jQuery Playground</code> <code>h3</code> element has the parent element of <code>&#60;div class=\"container-fluid\"&#62</code>, which itself has the parent <code>body</code>.",
"jQuery has a function called <code>parent()</code> that allows you to access the parent of whichever element you've selected.", "jQuery has a function called <code>parent()</code> that allows you to access the parent of whichever element you've selected.",
"Give the parent of the <code>#target1</code> element background-color of red.", "Here's an example of how you would use the <code>parent()</code> function if you wanted to give the parent element of the <code>left-well</code> element a background color of blue: <code>$(\"#left-well\").parent().css(\"background-color\", \"blue\")</code>",
"Here's an example of how you would use the <code>parent()</code> function: <code>$(\"#left-well\").parent().css(\"background-color\", \"blue\")</code>" "Give the parent of the <code>#target1</code> element a background-color of red."
], ],
"tests": [ "tests": [
"assert($(\"#left-well\").css(\"background-color\") === 'red' || $(\"#left-well\").css(\"background-color\") === 'rgb(255, 0, 0)' || $(\"#left-well\").css(\"background-color\").toLowerCase() === '#ff0000' || $(\"#left-well\").css(\"background-color\").toLowerCase() === '#f00', 'Your <code>left-well</code> element should have a red background.')", "assert($(\"#left-well\").css(\"background-color\") === 'red' || $(\"#left-well\").css(\"background-color\") === 'rgb(255, 0, 0)' || $(\"#left-well\").css(\"background-color\").toLowerCase() === '#ff0000' || $(\"#left-well\").css(\"background-color\").toLowerCase() === '#f00', 'Your <code>left-well</code> element should have a red background.')",
"assert(editor.match(/\\.parent\\(\\)\\.css/g), 'You should use the <code>parent()</code> function to modify this element.')", "assert(editor.match(/\\.parent\\(\\)\\.css/g), 'You should use the <code>&#46;parent&#40;&#41;</code> function to modify this element.')",
"assert(editor.match(/\\$\\s*?\\(\\s*?(?:'|\")\\s*?#target1\\s*?(?:'|\")\\s*?\\)\\.parent/gi), 'The <code>&#46;parent&#40;&#41;</code> method should be called on the <code>&#35;target1</code> element.')",
"assert(editor.match(/<div class=\"well\" id=\"left-well\">/g), 'Only use jQuery to add these classes to the element.')" "assert(editor.match(/<div class=\"well\" id=\"left-well\">/g), 'Only use jQuery to add these classes to the element.')"
], ],
"challengeSeed": [ "challengeSeed": [
@ -672,16 +661,15 @@
{ {
"id": "bad87fee1348bd9aed208826", "id": "bad87fee1348bd9aed208826",
"title": "Target the Children of an Element Using jQuery", "title": "Target the Children of an Element Using jQuery",
"difficulty": 3.14,
"description": [ "description": [
"Many HTML elements have <code>children</code> elements from which they <code>inherit</code> their properties.", "Many HTML elements have <code>children</code> which <code>inherit</code> their properties from their parent HTML elements.",
"For example, every HTML element is a child of your <code>body</code> element, and your \"jQuery Playground\" <code>h3</code> element is a child of your <code>&#60;div class=\"container-fluid\"&#62</code> element.", "For example, every HTML element is a child of your <code>body</code> element, and your \"jQuery Playground\" <code>h3</code> element is a child of your <code>&#60;div class=\"container-fluid\"&#62</code> element.",
"jQuery has a function called <code>children()</code> that allows you to access the children of whichever element you've selected.", "jQuery has a function called <code>children()</code> that allows you to access the children of whichever element you've selected.",
"Give all the children of your <code>#right-well</code> element a color of green.", "Here's an example of how you would use the <code>children()</code> function to give the children of your <code>left-well</code> element the color of blue: <code>$(\"#left-well\").children().css(\"color\", \"blue\")</code>",
"Here's an example of how you would use the <code>children()</code> function: <code>$(\"#left-well\").children().css(\"color\", \"blue\")</code>" "Give all the children of your <code>#right-well</code> element a color of green."
], ],
"tests": [ "tests": [
"assert($(\"#target6\").css(\"color\") === 'rgb(0, 128, 0)', 'Your <code>target6</code> element should have green text.')", "assert($(\"#right-well\").children().css(\"color\") === 'rgb(0, 128, 0)', 'All children of <code>#right-well</code> should have green text.')",
"assert(editor.match(/\\.children\\(\\)\\.css/g), 'You should use the <code>children&#40&#41</code> function to modify these elements.')", "assert(editor.match(/\\.children\\(\\)\\.css/g), 'You should use the <code>children&#40&#41</code> function to modify these elements.')",
"assert(editor.match(/<div class=\"well\" id=\"right-well\">/g), 'Only use jQuery to add these classes to the element.')" "assert(editor.match(/<div class=\"well\" id=\"right-well\">/g), 'Only use jQuery to add these classes to the element.')"
], ],
@ -728,16 +716,15 @@
{ {
"id": "bad87fee1348bd9aed108826", "id": "bad87fee1348bd9aed108826",
"title": "Target a Specific Child of an Element Using jQuery", "title": "Target a Specific Child of an Element Using jQuery",
"difficulty": 3.15,
"description": [ "description": [
"You've seen why id attributes are so convenient for targeting with jQuery selectors. But you won't always have such neat ids to work with.", "You've seen why id attributes are so convenient for targeting with jQuery selectors. But you won't always have such neat ids to work with.",
"Fortunately, jQuery has some other tricks for targeting the right elements.", "Fortunately, jQuery has some other tricks for targeting the right elements.",
"jQuery uses CSS Selectors to target elements. <code>target:nth-child(n)</code> css selector allows you to select all the nth element with the target class or element type.", "jQuery uses CSS Selectors to target elements. <code>target:nth-child(n)</code> css selector allows you to select all the nth element with the target class or element type.",
"Make the second child in each of your well elements bounce.", "Make the second child in each of your well elements bounce. You must target the children of element with the <code>target</code> class.",
"Here's how you would give the third element in each well bounce: <code>$(\".target:nth-child(3)\").addClass(\"animated bounce\");</code>" "Here's how you would give the third element in each well bounce: <code>$(\".target:nth-child(3)\").addClass(\"animated bounce\");</code>"
], ],
"tests": [ "tests": [
"assert($(\".target:nth-child(2)\").hasClass(\"animated\") && $(\".target:nth-child(2)\").hasClass(\"bounce\"), 'The second element in each of your <code>well</code> elements should bounce.')", "assert($(\".target:nth-child(2)\").hasClass(\"animated\") && $(\".target:nth-child(2)\").hasClass(\"bounce\"), 'The second element in your <code>target</code> elements should bounce.')",
"assert(editor.match(/\\:nth-child\\(/g), 'You should use the <code>&#58;nth-child&#40&#41</code> function to modify these elements.')", "assert(editor.match(/\\:nth-child\\(/g), 'You should use the <code>&#58;nth-child&#40&#41</code> function to modify these elements.')",
"assert(editor.match(/<button class=\"btn btn-default target\" id=\"target2\">/g), 'Only use jQuery to add these classes to the element.')" "assert(editor.match(/<button class=\"btn btn-default target\" id=\"target2\">/g), 'Only use jQuery to add these classes to the element.')"
], ],
@ -785,10 +772,10 @@
{ {
"id": "bad87fee1348bd9aed008826", "id": "bad87fee1348bd9aed008826",
"title": "Target Even Numbered Elements Using jQuery", "title": "Target Even Numbered Elements Using jQuery",
"difficulty": 3.16,
"description": [ "description": [
"You can also target all the even-numbered elements.", "You can also target all the even-numbered elements.",
"Here's how you would target all the odd-numbered elements with class <code>target</code> and give them classes: <code>$(\".target:odd\").addClass(\"animated shake\");</code>", "Here's how you would target all the odd-numbered elements with class <code>target</code> and give them classes: <code>$(\".target:odd\").addClass(\"animated shake\");</code>",
"Note that jQuery is zero-indexed, meaning that, counter-intuitively, <code>:odd</code> selects the second element, fourth element, and so on.",
"Try selecting all the even-numbered elements - that is, what your browser will consider even-numbered elements - and giving them the classes of <code>animated</code> and <code>shake</code>." "Try selecting all the even-numbered elements - that is, what your browser will consider even-numbered elements - and giving them the classes of <code>animated</code> and <code>shake</code>."
], ],
"tests": [ "tests": [
@ -842,7 +829,6 @@
{ {
"id": "bad87fee1348bd9aecb08826", "id": "bad87fee1348bd9aecb08826",
"title": "Use jQuery to Modify the Entire Page", "title": "Use jQuery to Modify the Entire Page",
"difficulty": 3.20,
"description": [ "description": [
"We're done playing with our jQuery playground. Let's tear it down!", "We're done playing with our jQuery playground. Let's tear it down!",
"jQuery can target the <code>body</code> element as well.", "jQuery can target the <code>body</code> element as well.",

View File

@ -0,0 +1,23 @@
{
"name": "JSON APIs and Ajax",
"order": 10,
"challenges": [
{
"id": "bad88fee1348bd9ae8c08416",
"title": "Stand in challenge",
"dashedName": "waypoint-stand-in-challenge",
"difficulty": 3.24,
"description": [
""
],
"tests": [
],
"challengeSeed": [
""
],
"challengeType": 0,
"type": "waypoint"
}
]
}

View File

@ -1,21 +1,20 @@
{ {
"name": "MongoDB", "name": "MongoDB",
"order" : 0.018, "order" : 19,
"challenges": [ "challenges": [
{ {
"id": "bd7243d8c341eddeaeb5bd0f", "id": "bd7243d8c341eddeaeb5bd0f",
"title": "Store Data in MongoDB", "title": "Store Data in MongoDB",
"difficulty": 0.01,
"challengeSeed": ["133316035"], "challengeSeed": ["133316035"],
"description": [ "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.", "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 <a href='http://c9.io' target='_blank'>http://c9.io</a>.", "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
"Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.", "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> 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.", "Click on the \"+\" icon at the top right of the c9.io page to create a new workspace.",
"Give your workspace a name.", "Give your workspace a name and an optional description.",
"Choose Node.js in the selection area below the name field.", "Choose Node.js in the selection area below the name field.",
"Click the Create button. Then click into your new workspace.", "Click the \"Create workspace\" 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.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.",
"Install <code>learnyoumongo</code> with this command: <code>npm install learnyoumongo -g</code>", "Install <code>learnyoumongo</code> with this command: <code>npm install learnyoumongo -g</code>",
"Now start the tutorial by running <code>learnyoumongo</code>.", "Now start the tutorial by running <code>learnyoumongo</code>.",
"Whenever you run a command that includes <code>mongod</code> on c9.io, be sure to also use the <code>--nojournal</code> flag, like this: <code>mongod --nojournal</code>.", "Whenever you run a command that includes <code>mongod</code> on c9.io, be sure to also use the <code>--nojournal</code> flag, like this: <code>mongod --nojournal</code>.",

View File

@ -1,11 +1,10 @@
{ {
"name": "Node.js and Express.js", "name": "Node.js and Express.js",
"order" : 0.017, "order" : 18,
"challenges": [ "challenges": [
{ {
"id": "bd7153d8c441eddfaeb5bd0f", "id": "bd7153d8c441eddfaeb5bd0f",
"title": "Manage Packages with NPM", "title": "Manage Packages with NPM",
"difficulty": 0.39,
"challengeSeed": ["126433450"], "challengeSeed": ["126433450"],
"description": [ "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.", "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
@ -59,17 +58,16 @@
{ {
"id": "bd7153d8c441eddfaeb5bdff", "id": "bd7153d8c441eddfaeb5bdff",
"title": "Start a Node.js Server", "title": "Start a Node.js Server",
"difficulty": 0.40,
"challengeSeed": ["126411561"], "challengeSeed": ["126411561"],
"description": [ "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. We'll do the first 7 steps of Node School's LearnYouNode challenges.", "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud. We'll do the first 7 steps of Node School's LearnYouNode challenges.",
"If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.", "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
"Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.", "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> 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.", "Click on the \"+\" icon at the top right of the c9.io page to create a new workspace.",
"Give your workspace a name.", "Give your workspace a name and an optional description.",
"Choose Node.js in the selection area below the name field.", "Choose Node.js in the selection area below the name field.",
"Click the Create button. Then click into your new workspace.", "Click the \"Create workspace\" 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.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.",
"Run this command: <code>sudo npm install -g learnyounode</code>", "Run this command: <code>sudo npm install -g learnyounode</code>",
"Now start this tutorial by running <code>learnyounode</code>", "Now start this tutorial by running <code>learnyounode</code>",
"Note that you can resize the c9.io's windows by dragging their borders.", "Note that you can resize the c9.io's windows by dragging their borders.",
@ -101,7 +99,6 @@
{ {
"id": "bd7153d8c441eddfaeb5bdfe", "id": "bd7153d8c441eddfaeb5bdfe",
"title": "Continue working with Node.js Servers", "title": "Continue working with Node.js Servers",
"difficulty": 0.41,
"challengeSeed": ["128836506"], "challengeSeed": ["128836506"],
"description": [ "description": [
"Let's continue the LearnYouNode Node School challenge. For this Waypoint, we'll do challenges 8 through 10.", "Let's continue the LearnYouNode Node School challenge. For this Waypoint, we'll do challenges 8 through 10.",
@ -130,7 +127,6 @@
{ {
"id": "bd7153d8c441eddfaeb5bdfd", "id": "bd7153d8c441eddfaeb5bdfd",
"title": "Finish working with Node.js Servers", "title": "Finish working with Node.js Servers",
"difficulty": 0.42,
"challengeSeed": ["128836507"], "challengeSeed": ["128836507"],
"description": [ "description": [
"Let's continue the LearnYouNode Node School challenge. For this Waypoint, we'll do challenges 11 through 13.", "Let's continue the LearnYouNode Node School challenge. For this Waypoint, we'll do challenges 11 through 13.",
@ -159,7 +155,6 @@
{ {
"id": "bd7153d8c441eddfaeb5bd1f", "id": "bd7153d8c441eddfaeb5bd1f",
"title": "Build Web Apps with Express.js", "title": "Build Web Apps with Express.js",
"difficulty": 0.43,
"challengeSeed": [ "challengeSeed": [
"126411559" "126411559"
], ],
@ -167,21 +162,23 @@
"We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.", "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 <a href='http://c9.io' target='_blank'>http://c9.io</a>.", "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
"Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.", "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> 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.", "Click on the \"+\" icon at the top right of the c9.io page to create a new workspace.",
"Give your workspace a name.", "Give your workspace a name and an optional description.",
"Choose Node.js in the selection area below the name field.", "Choose Node.js in the selection area below the name field.",
"Click the Create button. Then click into your new workspace.", "Click the \"Create workspace\" 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.", "Once C9 builds and loads your workspace, you should see a terminal window in the lower right hand corner. In this window use the following commands. You don't need to know what these mean at this point.",
"Run this command: <code>git clone http://github.com/reddock/fcc_express && chmod 744 fcc_express/setup.sh && fcc_express/setup.sh && source ~/.profile</code>", "Run this command: <code>git clone http://github.com/reddock/fcc_express && chmod 744 fcc_express/setup.sh && fcc_express/setup.sh && source ~/.profile</code>",
"Now start this tutorial by running <code>expressworks</code>", "Now start this tutorial by running <code>expressworks</code>",
"Note that you can resize the c9.io's windows by dragging their borders.", "Note that you can resize the c9.io's windows by dragging their borders.",
"Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.", "Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.",
"You can view this Node School module's source code on GitHub at <a href='https://github.com/azat-co/expressworks'>https://github.com/azat-co/expressworks</a>.", "You can view this Node School module's source code on GitHub at <a href='https://github.com/azat-co/expressworks'>https://github.com/azat-co/expressworks</a>.",
"Complete \"Hello World\"", "Complete \"Hello World!\"",
"Complete \"Static\"",
"Complete \"Jade\"", "Complete \"Jade\"",
"Complete \"Good Old Form\"", "Complete \"Good Old Form\"",
"Complete \"Stylish CSS\"", "Complete \"Stylish CSS\"",
"Complete \"Session and Cookie\"", "Complete \"Param Pam Pam\"",
"Complete \"What's In Query\"",
"Complete \"JSON Me\"", "Complete \"JSON Me\"",
"Once you've completed these steps, move on to our next challenge." "Once you've completed these steps, move on to our next challenge."
], ],

View File

@ -1,6 +1,6 @@
{ {
"name": "Object Oriented and Functional Programming", "name": "Object Oriented and Functional Programming",
"order": 0.010, "order": 6,
"note": [ "note": [
"Methods", "Methods",
"Closures", "Closures",
@ -20,9 +20,9 @@
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers." "Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
], ],
"tests":[ "tests":[
"assert(typeof(motorBike.engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');", "assert(typeof(motorBike.engines) === 'number', 'message: <code>motorBike</code> should have a <code>engines</code> attribute set to a number.');",
"assert(typeof(motorBike.wheels) === 'number', '<code>wheels</code> should be have a <code>engines</code> attribute set to a number.');", "assert(typeof(motorBike.wheels) === 'number', 'message: <code>motorBike</code> should have a <code>wheels</code> attribute set to a number.');",
"assert(typeof(motorBike.seats) === 'number', '<code>seats</code> should be have a <code>engines</code> attribute set to a number.');" "assert(typeof(motorBike.seats) === 'number', 'message: <code>motorBike</code> should have a <code>seats</code> attribute set to a number.');"
], ],
"challengeSeed":[ "challengeSeed":[
"//Here is a sample Object", "//Here is a sample Object",
@ -54,12 +54,12 @@
"difficulty":0, "difficulty":0,
"description":[ "description":[
"We are also able to create objects using <code>constructor</code> functions.", "We are also able to create objects using <code>constructor</code> functions.",
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers." "Give your <code>myMotorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
], ],
"tests":[ "tests":[
"assert(typeof((new MotorBike()).engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');", "assert(typeof((new MotorBike()).engines) === 'number', 'message: <code>myMotorBike</code> should have a <code>engines</code> attribute set to a number.');",
"assert(typeof((new MotorBike()).wheels) === 'number', '<code>wheels</code> should be have a <code>engines</code> attribute set to a number.');", "assert(typeof((new MotorBike()).wheels) === 'number', 'message: <code>myMotorBike</code> should have a <code>wheels</code> attribute set to a number.');",
"assert(typeof((new MotorBike()).seats) === 'number', '<code>seats</code> should be have a <code>engines</code> attribute set to a number.');" "assert(typeof((new MotorBike()).seats) === 'number', 'message: <code>myMotorBike</code> should have a <code>seats</code> attribute set to a number.');"
], ],
"challengeSeed":[ "challengeSeed":[
"// Let's add the properties engines and seats to the car in the same way that the property wheels has been added below. They should both be numbers.", "// Let's add the properties engines and seats to the car in the same way that the property wheels has been added below. They should both be numbers.",
@ -98,12 +98,12 @@
"See if you can keep <code>myBike.speed</code> and <code>myBike.addUnit</code> private, while making <code>myBike.getSpeed</code> publicly accessible." "See if you can keep <code>myBike.speed</code> and <code>myBike.addUnit</code> private, while making <code>myBike.getSpeed</code> publicly accessible."
], ],
"tests":[ "tests":[
"assert(typeof(myBike.getSpeed)!=='undefined' && typeof(myBike.getSpeed) === 'function', 'The method getSpeed of myBike should be accessible outside the object');", "assert(typeof(myBike.getSpeed)!=='undefined' && typeof(myBike.getSpeed) === 'function', 'message: The method getSpeed of myBike should be accessible outside the object.');",
"assert(typeof(myBike.speed) === 'undefined', '<code>myBike.speed</code> should remain undefined.');", "assert(typeof(myBike.speed) === 'undefined', 'message: <code>myBike.speed</code> should remain undefined.');",
"assert(typeof(myBike.addUnit) === 'undefined', '<code>myBike.addUnit</code> should remain undefined.');" "assert(typeof(myBike.addUnit) === 'undefined', 'message: <code>myBike.addUnit</code> should remain undefined.');"
], ],
"challengeSeed":[ "challengeSeed":[
"//Let's create an object with a two functions. One attached as a property and one not.", "//Let's create an object with two functions. One attached as a property and one not.",
"var Car = function() {", "var Car = function() {",
" this.gear = 1;", " this.gear = 1;",
" function addStyle(styleMe){", " function addStyle(styleMe){",
@ -149,10 +149,10 @@
"Then you can give the instance new properties." "Then you can give the instance new properties."
], ],
"tests":[ "tests":[
"assert((new Car()).wheels === 4, 'The property <code>wheels</code> should still be 4 like in the object constructor');", "assert((new Car()).wheels === 4, 'message: The property <code>wheels</code> should still be 4 like in the object constructor.');",
"assert(typeof((new Car()).engines) === 'undefined', 'There should not be a property engine in the object constructor');", "assert(typeof((new Car()).engines) === 'undefined', 'message: There should not be a property <code>engines</code> in the object constructor.');",
"assert(myCar.wheels === 4, 'The property wheels of myCar should be four');", "assert(myCar.wheels === 4, 'message: The property <code>wheels</code> of myCar should equal 4.');",
"assert(typeof(myCar.engines) === 'number', 'The property engine of myCar should be a number');" "assert(typeof(myCar.engines) === 'number', 'message: The property <code>engines</code> of myCar should be a number.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var Car = function() {", "var Car = function() {",
@ -184,9 +184,9 @@
"Use the map function to add 3 to every value in the variable <code>array</code>" "Use the map function to add 3 to every value in the variable <code>array</code>"
], ],
"tests":[ "tests":[
"assert.deepEqual(array, [4,5,6,7,8], 'You should have added three to each value in the array');", "assert.deepEqual(array, [4,5,6,7,8], 'message: You should add three to each value in the array.');",
"assert(editor.getValue().match(/\\.map\\(/gi), 'You should be making use of the map method');", "assert(editor.getValue().match(/\\.map\\(/gi), 'message: You should be making use of the map method.');",
"assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\]/gi), 'You should only modify the array with .map');" "assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\]/gi), 'message: You should only modify the array with <code>.map</code>.');"
], ],
"challengeSeed":[ "challengeSeed":[
"//Use map to add three to each value in the array", "//Use map to add three to each value in the array",
@ -212,8 +212,8 @@
"<code>});</code>" "<code>});</code>"
], ],
"tests":[ "tests":[
"assert(singleVal == 30, 'singleVal should have been set to the result of you reduce operation');", "assert(singleVal == 30, 'message: <code>singleVal</code> should have been set to the result of you reduce operation.');",
"assert(editor.getValue().match(/\\.reduce\\(/gi), 'You should have made use of the reduce method');" "assert(editor.getValue().match(/\\.reduce\\(/gi), 'message: You should have made use of the reduce method.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var array = [4,5,6,7,8];", "var array = [4,5,6,7,8];",
@ -236,13 +236,13 @@
"filter is a useful method that can filter out values that don't match a certain criteria", "filter is a useful method that can filter out values that don't match a certain criteria",
"Let's remove all the values greater than five", "Let's remove all the values greater than five",
"<code>array = array.filter(function(val) {</code>", "<code>array = array.filter(function(val) {</code>",
"<code>&thinsp;&thinsp;return val<4;</code>", "<code>&thinsp;&thinsp;return val <= 5;</code>",
"<code>});</code>" "<code>});</code>"
], ],
"tests":[ "tests":[
"assert.deepEqual(array, [1,2,3,4,5], 'You should have removed all the values from the array that are greater than five');", "assert.deepEqual(array, [1,2,3,4], 'message: You should have removed all the values from the array that are greater than 4.');",
"assert(editor.getValue().match(/array\\.filter\\(/gi), 'You should be using the filter method to remove the values from the array');", "assert(editor.getValue().match(/array\\.filter\\(/gi), 'message: You should be using the filter method to remove the values from the array.');",
"assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\,6\\,7\\,8\\,9\\,10\\]/gi), 'You should only be using .filter to modify the contents of the array');" "assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\,6\\,7\\,8\\,9\\,10\\]/gi), 'message: You should only be using <code>.filter</code> to modify the contents of the array.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var array = [1,2,3,4,5,6,7,8,9,10];", "var array = [1,2,3,4,5,6,7,8,9,10];",
@ -267,9 +267,9 @@
"This will return <code>[1, 2, 3]</code>" "This will return <code>[1, 2, 3]</code>"
], ],
"tests":[ "tests":[
"assert.deepEqual(array, ['alpha', 'beta', 'charlie'], 'You should have sorted the array alphabetically');", "assert.deepEqual(array, ['alpha', 'beta', 'charlie'], 'message: You should have sorted the array alphabetically.');",
"assert(editor.getValue().match(/\\[\\'beta\\'\\,\\s\\'alpha\\'\\,\\s'charlie\\'\\];/gi), 'You should be sorting the array using sort');", "assert(editor.getValue().match(/\\[\\'beta\\'\\,\\s\\'alpha\\'\\,\\s'charlie\\'\\];/gi), 'message: You should be sorting the array using sort.');",
"assert(editor.getValue().match(/\\.sort\\(\\)/gi), 'You should have made use of the sort method');" "assert(editor.getValue().match(/\\.sort\\(\\)/gi), 'message: You should have made use of the sort method.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var array = ['beta', 'alpha', 'charlie'];", "var array = ['beta', 'alpha', 'charlie'];",
@ -286,14 +286,13 @@
{ {
"id": "cf1111c1c16feddfaeb2bdef", "id": "cf1111c1c16feddfaeb2bdef",
"title": "Reverse Arrays with .reverse", "title": "Reverse Arrays with .reverse",
"difficulty": 0,
"description": [ "description": [
"You can use the <code>.reverse()</code> function to reverse the contents of an array." "You can use the <code>.reverse()</code> function to reverse the contents of an array."
], ],
"tests": [ "tests": [
"assert.deepEqual(array, [7,6,5,4,3,2,1], 'You should reverse the array');", "assert.deepEqual(array, [7,6,5,4,3,2,1], 'message: You should reverse the array.');",
"assert(editor.getValue().match(/\\.reverse\\(\\)/gi), '');", "assert(editor.getValue().match(/\\.reverse\\(\\)/gi), 'message: You should use the reverse method.');",
"assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\,6\\,7/gi), '');" "assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\,6\\,7/gi), 'message: You should return <code>[7,6,5,4,3,2,1]</code>.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var array = [1,2,3,4,5,6,7];", "var array = [1,2,3,4,5,6,7];",
@ -310,15 +309,14 @@
{ {
"id": "cf1111c1c16feddfaeb3bdef", "id": "cf1111c1c16feddfaeb3bdef",
"title": "Concatenate Strings with .concat", "title": "Concatenate Strings with .concat",
"difficulty": 0,
"description": [ "description": [
"<code>.concat()</code> can be used to merge the contents of two arrays into one.", "<code>.concat()</code> can be used to merge the contents of two arrays into one.",
"<code>array = array.concat(otherArray);</code>" "<code>array = array.concat(otherArray);</code>"
], ],
"tests": [ "tests": [
"assert.deepEqual(array, [1,2,3,4,5,6], 'You should concat the two arrays together');", "assert.deepEqual(array, [1,2,3,4,5,6], 'You should concat the two arrays together.');",
"assert(editor.getValue().match(/\\.concat\\(/gi), 'You should be using the concat method to merge the two arrays');", "assert(editor.getValue().match(/\\.concat\\(/gi), 'message: You should be use the concat method to merge the two arrays.');",
"assert(editor.getValue().match(/\\[1\\,2\\,3\\]/gi) && editor.getValue().match(/\\[4\\,5\\,6\\]/gi), 'You should only modify the two arrays without changing the origional ones');" "assert(editor.getValue().match(/\\[1\\,2\\,3\\]/gi) && editor.getValue().match(/\\[4\\,5\\,6\\]/gi), 'message: You should only modify the two arrays without changing the origional ones.');"
], ],
"challengeSeed": [ "challengeSeed": [
"var array = [1,2,3];", "var array = [1,2,3];",
@ -344,8 +342,8 @@
"<code>array = string.split(' ');</code>" "<code>array = string.split(' ');</code>"
], ],
"tests":[ "tests":[
"assert(typeof(array) === 'object' && array.length === 5, 'You should have split the string by it\\'s spaces');", "assert(typeof(array) === 'object' && array.length === 5, 'message: You should split the string by its spaces.');",
"assert(/\\.split\\(/gi, 'You should have made use of the split method on the string');" "assert(/\\.split\\(/gi, 'message: You should use the split method on the string.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var string = \"Split me into an array\";", "var string = \"Split me into an array\";",
@ -368,8 +366,8 @@
"<code>var joinMe = joinMe.join(\" \");</code>" "<code>var joinMe = joinMe.join(\" \");</code>"
], ],
"tests":[ "tests":[
"assert(typeof(joinMe) === 'string' && joinMe === \"Split me into an array\", 'You should have joined the arrays by it\\'s spaces');", "assert(typeof(joinMe) === 'string' && joinMe === \"Split me into an array\", 'message: You should join the arrays by their spaces.');",
"assert(/\\.join\\(/gi, 'You should have made use of the join method on the array');" "assert(/\\.join\\(/gi, 'message: You should use of the join method on the array.');"
], ],
"challengeSeed":[ "challengeSeed":[
"var joinMe = [\"Split\",\"me\",\"into\",\"an\",\"array\"];", "var joinMe = [\"Split\",\"me\",\"into\",\"an\",\"array\"];",

View File

@ -1,11 +1,10 @@
{ {
"name": "Upper Intermediate Algorithm Scripting", "name": "Upper Intermediate Algorithm Scripting",
"order": 0.011, "order": 13,
"challenges": [ "challenges": [
{ {
"id": "a2f1d72d9b908d0bd72bb9f6", "id": "a2f1d72d9b908d0bd72bb9f6",
"title": "Make a Person", "title": "Make a Person",
"difficulty": "3.01",
"description": [ "description": [
"Fill in the object constructor with the methods specified in the tests.", "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).", "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).",
@ -22,20 +21,13 @@
"bob.getFullName();" "bob.getFullName();"
], ],
"tests": [ "tests": [
"expect(Object.keys(bob).length).to.eql(6);", "assert.deepEqual(Object.keys(bob).length, 6, 'message: <code>Object.keys(bob).length</code> should return 6.');",
"expect(bob instanceof Person).to.be.true;", "assert.deepEqual(bob instanceof Person, true, 'message: <code>bob instanceof Person</code> should return true.');",
"expect(bob.firstName).to.be.undefined();", "assert.deepEqual(bob.firstName, undefined, 'message: <code>bob.firstName</code> should return undefined.');",
"expect(bob.lastName).to.be.undefined();", "assert.deepEqual(bob.lastName, undefined, 'message: <code>bob.lastName</code> should return undefined.');",
"expect(bob.getFirstName()).to.eql('Bob');", "assert.deepEqual(bob.getFirstName(), 'Bob', 'message: <code>bob.getFirstName()</code> should return \"Bob\".');",
"expect(bob.getLastName()).to.eql('Ross');", "assert.deepEqual(bob.getLastName(), 'Ross', 'message: <code>bob.getLastName()</code> should return \"Ross\".');",
"expect(bob.getFullName()).to.eql('Bob Ross');", "assert.deepEqual(bob.getFullName(), 'Bob Ross', 'message: <code>bob.getFullName()</code> should return \"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": [ "MDNlinks": [
"Closures", "Closures",
@ -58,7 +50,6 @@
"id": "af4afb223120f7348cdfc9fd", "id": "af4afb223120f7348cdfc9fd",
"title": "Map the Debris", "title": "Map the Debris",
"dashedName": "bonfire-map-the-debris", "dashedName": "bonfire-map-the-debris",
"difficulty": "3.02",
"description": [ "description": [
"Return a new array that transforms the element's average altitude into their orbital periods.", "Return a new array that transforms the element's average altitude into their orbital periods.",
"The array will contain objects in the format <code>{name: 'name', avgAlt: avgAlt}</code>.", "The array will contain objects in the format <code>{name: 'name', avgAlt: avgAlt}</code>.",
@ -77,8 +68,8 @@
"orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);" "orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);"
], ],
"tests": [ "tests": [
"expect(orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}])).to.eqls([{name: \"sputnik\", orbitalPeriod: 86400}]);", "assert.deepEqual(orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]), [{name: \"sputnik\", orbitalPeriod: 86400}], 'message: <code>orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}])</code> should return <code>[{name: \"sputnik\", orbitalPeriod: 86400}]</code>.');",
"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}]);" "assert.deepEqual(orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}]), [{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}], 'message: <code>orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}])</code> should return <code>[{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}]</code>.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Math.pow()" "Math.pow()"
@ -99,7 +90,6 @@
{ {
"id": "a3f503de51cfab748ff001aa", "id": "a3f503de51cfab748ff001aa",
"title": "Pairwise", "title": "Pairwise",
"difficulty": "3.03",
"description": [ "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.", "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.", "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.",
@ -114,11 +104,11 @@
"pairwise([1,4,2,3,0,5], 7);" "pairwise([1,4,2,3,0,5], 7);"
], ],
"tests": [ "tests": [
"expect(pairwise([1, 4, 2, 3, 0, 5], 7)).to.equal(11);", "assert.deepEqual(pairwise([1, 4, 2, 3, 0, 5], 7), 11, 'message: <code>pairwise([1, 4, 2, 3, 0, 5], 7)</code> should return 11.');",
"expect(pairwise([1, 3, 2, 4], 4)).to.equal(1);", "expect(pairwise([1, 3, 2, 4], 4), 1, 'message: <code>pairwise([1, 3, 2, 4], 4), 1</code> should return 1.');",
"expect(pairwise([1,1,1], 2)).to.equal(1);", "expect(pairwise([1,1,1], 2), 1, 'message: <code>pairwise([1,1,1], 2)</code> should return 1.');",
"expect(pairwise([0, 0, 0, 0, 1, 1], 1)).to.equal(10);", "expect(pairwise([0, 0, 0, 0, 1, 1], 1), 10, 'message: <code>pairwise([0, 0, 0, 0, 1, 1], 1)</code> should return 10.');",
"expect(pairwise([], 100)).to.equal(0);" "expect(pairwise([], 100), 0, 'message: <code>pairwise([], 100)</code> should return 0.');"
], ],
"MDNlinks": [ "MDNlinks": [
"Array.reduce()" "Array.reduce()"

View File

@ -5,8 +5,11 @@
{ {
"id": "bad87fed1348bd9aeca08826", "id": "bad87fed1348bd9aeca08826",
"title": "Trigger on click Events with jQuery", "title": "Trigger on click Events with jQuery",
"difficulty": 3.19,
"description": [ "description": [
"With jQuery we are able to get data from APIs via Ajax",
"This data normally comes in the form of JSON",
"Let's get the <code>Get Message</code> button to set the text of a div",
"We will later use this to display the result of out API request",
"<code>$(\"#getMessage\").on(\"click\", function(){</code>", "<code>$(\"#getMessage\").on(\"click\", function(){</code>",
"<code>&thinsp;&thinsp;$(\".message\").html(\"Here is the message\");</code>", "<code>&thinsp;&thinsp;$(\".message\").html(\"Here is the message\");</code>",
"<code>});</code>" "<code>});</code>"
@ -48,11 +51,60 @@
"challengeType": 0, "challengeType": 0,
"type": "waypoint" "type": "waypoint"
}, },
{
"id": "bad87fee1348bd9aebc08726",
"title": "Learn JSON Syntax",
"description": [
"JSON stands for \"JavaScript Object Notation\". It\"s how you create objects in JavaScript.",
"JSON is a series of \"key-value pairs\". Everything on the left of the colon (<code>:</code>) is the \"key\" you use to unlock the \"value\" on the right of the colon."
],
"tests": [
"assert(typeof data != \"undefined\", \"Whoops! It looks like you deleted the <code>data</code> variable!\");",
"assert(typeof getAnId != \"undefined\", \"Whoops! It looks like you deleted the <code>getAnId</code> function!\");",
"assert(data[0]['id'] === getAnId(), \"The duntion getFirstId should return the id of the first element in the array\");"
],
"challengeSeed": [
"fccss",
"var data = [",
" {",
" \"id\": 0,",
" \"imageLink\": \"http://rs611.pbsrc.com/albums/tt194/allypopper423/Funny-Cat-Green-Avacado.jpg~c200\",",
" \"codeNames\": [",
" \"Juggernaut\",",
" \"Mrs. Wallace\",",
" \"Buttercup\"",
" ]",
" },",
" {",
" \"id\": 1,",
" \"imageLink\": \"http://cdn.grumpycats.com/wp-content/uploads/2012/09/GC-Gravatar-copy.png\",",
" \"codeNames\": [",
" \"Oscar\",",
" \"Scrooge\",",
" \"Tyrion\"",
" ]",
" },",
" {",
" \"id\": 2,",
" \"imageLink\": \"http://www.kittenspet.com/wp-content/uploads/2012/08/cat_with_funny_face_3-200x200.jpg\",",
" \"codeNames\": [",
" \"The Doctor\",",
" \"Loki\",",
" \"Joker\"",
" ]",
" }",
"]",
"function getAnId(){",
" return();",
"}",
"fcces"
],
"challengeType": 0,
"type": "waypoint"
},
{ {
"id": "bad87fee1348bd9aeca08826", "id": "bad87fee1348bd9aeca08826",
"title": "Learn how JSON works", "title": "Displaying JSON data in HTML",
"difficulty": 3.19,
"description": [ "description": [
"JSON stands for \"JavaScript Object Notation\". It\"s how you create objects in JavaScript.", "JSON stands for \"JavaScript Object Notation\". It\"s how you create objects in JavaScript.",
"JSON is a series of \"key-value pairs\". Everything on the left of the colon (<code>:</code>) is the \"key\" you use to unlock the \"value\" on the right of the colon." "JSON is a series of \"key-value pairs\". Everything on the left of the colon (<code>:</code>) is the \"key\" you use to unlock the \"value\" on the right of the colon."
@ -99,7 +151,6 @@
"id": "bad84fee1348bd9aecc48826", "id": "bad84fee1348bd9aecc48826",
"title": "Read Data from an Element Using jQuery", "title": "Read Data from an Element Using jQuery",
"dashedName": "waypoint-read-data-from-an-element-using-jquery", "dashedName": "waypoint-read-data-from-an-element-using-jquery",
"difficulty": 3.17,
"description": [ "description": [
"Let's make everything roll with <code>rollOut</code>." "Let's make everything roll with <code>rollOut</code>."
], ],
@ -138,7 +189,6 @@
"id": "bad84fee1348bd9aecc38826", "id": "bad84fee1348bd9aecc38826",
"title": "Read Data from an Element Using jQuery", "title": "Read Data from an Element Using jQuery",
"dashedName": "waypoint-read-data-from-an-element-using-jquery", "dashedName": "waypoint-read-data-from-an-element-using-jquery",
"difficulty": 3.17,
"description": [ "description": [
"Let's make everything roll with <code>rollOut</code>." "Let's make everything roll with <code>rollOut</code>."
], ],
@ -178,7 +228,6 @@
"id": "bad84fee1348bd9aecc28826", "id": "bad84fee1348bd9aecc28826",
"title": "Read Data from an Element Using jQuery", "title": "Read Data from an Element Using jQuery",
"dashedName": "waypoint-read-data-from-an-element-using-jquery", "dashedName": "waypoint-read-data-from-an-element-using-jquery",
"difficulty": 3.17,
"description": [ "description": [
"Let's make everything roll with <code>rollOut</code>." "Let's make everything roll with <code>rollOut</code>."
], ],
@ -218,7 +267,6 @@
"id": "bad84fee1348bd9aecc18826", "id": "bad84fee1348bd9aecc18826",
"title": "Read Data from an Element Using jQuery", "title": "Read Data from an Element Using jQuery",
"dashedName": "waypoint-read-data-from-an-element-using-jquery", "dashedName": "waypoint-read-data-from-an-element-using-jquery",
"difficulty": 3.17,
"description": [ "description": [
], ],
@ -258,7 +306,6 @@
"id": "bad87fee1348bd9aecc08826", "id": "bad87fee1348bd9aecc08826",
"title": "Trigger onHover Events with jQuery", "title": "Trigger onHover Events with jQuery",
"dashedName": "waypoint-trigger-onhover-events-with-jquery", "dashedName": "waypoint-trigger-onhover-events-with-jquery",
"difficulty": 3.18,
"description": [ "description": [
], ],
@ -272,57 +319,10 @@
"type": "waypoint" "type": "waypoint"
}, },
{
"id": "bad87fee1348bd9aebc08726",
"title": "Learn how JSON Works",
"description": [
"JSON stands for \"JavaScript Object Notation\". It\"s how you create objects in JavaScript.",
"JSON is a series of \"key-value pairs\". Everything on the left of the colon (<code>:</code>) is the \"key\" you use to unlock the \"value\" on the right of the colon."
],
"tests": [
],
"challengeSeed": [
"[",
" {",
" \"id\": 0,",
" \"imageLink\": \"http://rs611.pbsrc.com/albums/tt194/allypopper423/Funny-Cat-Green-Avacado.jpg~c200\",",
" \"codeNames\": [",
" \"Juggernaut\",",
" \"Mrs. Wallace\",",
" \"Buttercup\"",
" ]",
" },",
" {",
" \"id\": 1,",
" \"imageLink\": \"http://cdn.grumpycats.com/wp-content/uploads/2012/09/GC-Gravatar-copy.png\",",
" \"codeNames\": [",
" \"Oscar\",",
" \"Scrooge\",",
" \"Tyrion\"",
" ]",
" },",
" {",
" \"id\": 2,",
" \"imageLink\": \"http://www.kittenspet.com/wp-content/uploads/2012/08/cat_with_funny_face_3-200x200.jpg\",",
" \"codeNames\": [",
" \"The Doctor\",",
" \"Loki\",",
" \"Joker\"",
" ]",
" }",
"]"
],
"challengeType": 0,
"type": "waypoint"
},
{ {
"id": "bad87fee1348bd9aebc08826", "id": "bad87fee1348bd9aebc08826",
"title": "Get Data from an URL Using jQuery", "title": "Get Data from an URL Using jQuery",
"dashedName": "waypoint-get-data-from-a-url-using-jquery", "dashedName": "waypoint-get-data-from-a-url-using-jquery",
"difficulty": 3.21,
"description": [ "description": [
], ],
@ -356,7 +356,6 @@
"id": "bad87fee1348bd9ae9c08826", "id": "bad87fee1348bd9ae9c08826",
"title": "Loop through JSON Data Using jQuery", "title": "Loop through JSON Data Using jQuery",
"dashedName": "waypoint-loop-through-json-data-using-jquery", "dashedName": "waypoint-loop-through-json-data-using-jquery",
"difficulty": 3.22,
"description": [ "description": [
], ],
@ -390,7 +389,6 @@
"id": "bad88fee1348bd9ae8c08726", "id": "bad88fee1348bd9ae8c08726",
"title": "Wire AJAX Call into a jQuery Click Event", "title": "Wire AJAX Call into a jQuery Click Event",
"dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event", "dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event",
"difficulty": 3.24,
"description": [ "description": [
"<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">" "<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">"
], ],
@ -424,7 +422,6 @@
"id": "bad88fee1348bd9ae8c08626", "id": "bad88fee1348bd9ae8c08626",
"title": "Wire AJAX Call into a jQuery Click Event", "title": "Wire AJAX Call into a jQuery Click Event",
"dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event", "dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event",
"difficulty": 3.24,
"description": [ "description": [
"<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">" "<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">"
], ],
@ -458,7 +455,6 @@
"id": "bad88fee1348bd9ae8c08526", "id": "bad88fee1348bd9ae8c08526",
"title": "Wire AJAX Call into a jQuery Click Event", "title": "Wire AJAX Call into a jQuery Click Event",
"dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event", "dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event",
"difficulty": 3.24,
"description": [ "description": [
"<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">" "<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">"
], ],
@ -492,7 +488,6 @@
"id": "bad88fee1348bd9ae8c08426", "id": "bad88fee1348bd9ae8c08426",
"title": "Wire AJAX Call into a jQuery Click Event", "title": "Wire AJAX Call into a jQuery Click Event",
"dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event", "dashedName": "waypoint-wire-ajax-call-into-a-jquery-click-event",
"difficulty": 3.24,
"description": [ "description": [
"<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">" "<img src=\"https://www.evernote.com/l/AjmAQ5BxGrFGRrWl_j2eSpGZMfrunfse89gB/image.png\">"
], ],

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import Router from 'react-router'; import { RoutingContext } from 'react-router';
import Fetchr from 'fetchr'; import Fetchr from 'fetchr';
import Location from 'react-router/lib/Location'; import { createLocation } from 'history';
import debugFactory from 'debug'; import debugFactory from 'debug';
import { app$ } from '../../common/app'; import { app$ } from '../../common/app';
import { RenderToString } from 'thundercats-react'; import { RenderToString } from 'thundercats-react';
@ -13,7 +13,8 @@ const debug = debugFactory('freecc:react-server');
const routes = [ const routes = [
'/hikes', '/hikes',
'/hikes/*', '/hikes/*',
'/jobs' '/jobs',
'/jobs/*'
]; ];
export default function reactSubRouter(app) { export default function reactSubRouter(app) {
@ -29,25 +30,25 @@ export default function reactSubRouter(app) {
function serveReactApp(req, res, next) { function serveReactApp(req, res, next) {
const services = new Fetchr({ req }); const services = new Fetchr({ req });
const location = new Location(req.path, req.query); const location = createLocation(req.path);
// returns a router wrapped app // returns a router wrapped app
app$(location) app$({ location })
// if react-router does not find a route send down the chain // if react-router does not find a route send down the chain
.filter(function({ initialState }) { .filter(function({ props}) {
if (!initialState) { if (!props) {
debug('react tried to find %s but got 404', location.pathname); debug('react tried to find %s but got 404', location.pathname);
return next(); return next();
} }
return !!initialState; return !!props;
}) })
.flatMap(function({ initialState, AppCat }) { .flatMap(function({ props, AppCat }) {
// call thundercats renderToString // call thundercats renderToString
// prefetches data and sets up it up for current state // prefetches data and sets up it up for current state
debug('rendering to string'); debug('rendering to string');
return RenderToString( return RenderToString(
AppCat(null, services), AppCat(null, services),
React.createElement(Router, initialState) React.createElement(RoutingContext, props)
); );
}) })
// makes sure we only get one onNext and closes subscription // makes sure we only get one onNext and closes subscription

View File

@ -14,7 +14,6 @@ import {
import { import {
userMigration, userMigration,
ifNoUserRedirectTo,
ifNoUserSend ifNoUserSend
} from '../utils/middleware'; } from '../utils/middleware';
@ -27,32 +26,63 @@ const challengeView = {
2: 'coursewares/showVideo', 2: 'coursewares/showVideo',
3: 'coursewares/showZiplineOrBasejump', 3: 'coursewares/showZiplineOrBasejump',
4: 'coursewares/showZiplineOrBasejump', 4: 'coursewares/showZiplineOrBasejump',
5: 'coursewares/showBonfire' 5: 'coursewares/showBonfire',
7: 'coursewares/showStep'
}; };
const dasherize = utils.dasherize; const dasherize = utils.dasherize;
const unDasherize = utils.unDasherize; const unDasherize = utils.unDasherize;
const getMDNLinks = utils.getMDNLinks; const getMDNLinks = utils.getMDNLinks;
function makeChallengesUnique(challengeArr) {
// clone and reverse challenges
// then filter by unique id's
// then reverse again
return _.uniq(challengeArr.slice().reverse(), 'id').reverse();
}
function numberWithCommas(x) { function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
} }
function updateUserProgress(user, challengeId, completedChallenge) { function updateUserProgress(user, challengeId, completedChallenge) {
const alreadyCompleted = user.completedChallenges.some(({ id }) => { let { completedChallenges } = user;
return id === challengeId;
// migrate user challenges object to remove
if (!user.isUniqMigrated) {
user.isUniqMigrated = true;
completedChallenges = user.completedChallenges =
makeChallengesUnique(completedChallenges);
}
const indexOfChallenge = _.findIndex(completedChallenges, {
id: challengeId
}); });
const alreadyCompleted = indexOfChallenge !== -1;
if (!alreadyCompleted) { if (!alreadyCompleted) {
user.progressTimestamps.push({ user.progressTimestamps.push({
timestamp: Date.now(), timestamp: Date.now(),
completedChallenge completedChallenge: challengeId
}); });
}
user.completedChallenges.push(completedChallenge); user.completedChallenges.push(completedChallenge);
return user; return user;
} }
const oldCompletedChallenge = completedChallenges[indexOfChallenge];
user.completedChallenges[indexOfChallenge] =
Object.assign(
{},
completedChallenge,
{
completedDate: oldCompletedChallenge.completedDate,
lastUpdated: completedChallenge.completedDate
}
);
return user;
}
module.exports = function(app) { module.exports = function(app) {
const router = app.loopback.Router(); const router = app.loopback.Router();
@ -100,9 +130,6 @@ module.exports = function(app) {
const userCount$ = observeMethod(User, 'count'); const userCount$ = observeMethod(User, 'count');
const send200toNonUser = ifNoUserSend(true); const send200toNonUser = ifNoUserSend(true);
const redirectNonUser = ifNoUserRedirectTo(
'/challenges/learn-how-free-code-camp-works'
);
router.post( router.post(
'/completed-challenge/', '/completed-challenge/',
@ -125,26 +152,17 @@ module.exports = function(app) {
router.get('/map', challengeMap); router.get('/map', challengeMap);
router.get( router.get(
'/challenges/next-challenge', '/challenges/next-challenge',
redirectNonUser,
returnNextChallenge returnNextChallenge
); );
router.get('/challenges/:challengeName', returnIndividualChallenge); router.get('/challenges/:challengeName', returnIndividualChallenge);
router.get(
'/challenges/',
redirectNonUser,
returnCurrentChallenge
);
app.use(router); app.use(router);
function returnNextChallenge(req, res, next) { function returnNextChallenge(req, res, next) {
let nextChallengeName = firstChallenge; let nextChallengeName = firstChallenge;
const challengeId = req.user.currentChallenge ? const challengeId = req.query.id;
req.user.currentChallenge.challengeId :
'bd7123c8c441eddfaeb5bdef';
// find challenge // find challenge
return challenge$ return challenge$
@ -199,16 +217,13 @@ module.exports = function(app) {
nextChallengeName = nextChallenge.dashedName; nextChallengeName = nextChallenge.dashedName;
return nextChallengeName; return nextChallengeName;
}) })
.flatMap(() => {
return saveUser(req.user);
})
.subscribe( .subscribe(
function() {}, function() {},
next, next,
function() { function() {
debug('next challengeName', nextChallengeName); debug('next challengeName', nextChallengeName);
if (!nextChallengeName || nextChallengeName === firstChallenge) { if (!nextChallengeName || nextChallengeName === firstChallenge) {
req.flash('errors', { req.flash('info', {
msg: dedent` msg: dedent`
Once you have completed all of our challenges, you should Once you have completed all of our challenges, you should
join our <a href=\"//gitter.im/freecodecamp/HalfWayClub\" join our <a href=\"//gitter.im/freecodecamp/HalfWayClub\"
@ -223,36 +238,9 @@ module.exports = function(app) {
); );
} }
function returnCurrentChallenge(req, res, next) {
Observable.just(req.user)
.flatMap(user => {
if (!req.user.currentChallenge) {
return challenge$
.first()
.flatMap(challenge => {
user.currentChallenge = {
challengeId: challenge.id,
challengeName: challenge.name,
dashedName: challenge.dashedName
};
return saveUser(user);
});
}
return Observable.just(user);
})
.map(user => user.currentChallenge.dashedName)
.subscribe(
function(challengeName) {
res.redirect('/challenges/' + challengeName);
},
next,
function() {
}
);
}
function returnIndividualChallenge(req, res, next) { function returnIndividualChallenge(req, res, next) {
const origChallengeName = req.params.challengeName; const origChallengeName = req.params.challengeName;
const solutionCode = req.query.solution;
const unDashedName = unDasherize(origChallengeName); const unDashedName = unDasherize(origChallengeName);
const challengeName = challengesRegex.test(unDashedName) ? const challengeName = challengesRegex.test(unDashedName) ?
@ -282,25 +270,21 @@ module.exports = function(app) {
} }
if (dasherize(challenge.name) !== origChallengeName) { if (dasherize(challenge.name) !== origChallengeName) {
return Observable.just('/challenges/' + dasherize(challenge.name)); return Observable.just(
} '/challenges/' +
dasherize(challenge.name) +
if (challenge) { '?solution=' +
if (req.user) { encodeURIComponent(solutionCode)
req.user.currentChallenge = { );
challengeId: challenge.id,
challengeName: challenge.name,
dashedName: challenge.dashedName
};
} }
// save user does nothing if user does not exist // save user does nothing if user does not exist
return saveUser(req.user) return Observable.just({
.map(() => ({
title: challenge.name, title: challenge.name,
dashedName: origChallengeName, dashedName: origChallengeName,
name: challenge.name, name: challenge.name,
details: challenge.description, details: challenge.description,
description: challenge.description,
tests: challenge.tests, tests: challenge.tests,
challengeSeed: challenge.challengeSeed, challengeSeed: challenge.challengeSeed,
verb: utils.randomVerb(), verb: utils.randomVerb(),
@ -317,8 +301,7 @@ module.exports = function(app) {
MDNlinks: getMDNLinks(challenge.MDNlinks), MDNlinks: getMDNLinks(challenge.MDNlinks),
// htmls specific // htmls specific
environment: utils.whichEnvironment() environment: utils.whichEnvironment()
})); });
}
}) })
.subscribe( .subscribe(
function(data) { function(data) {
@ -526,6 +509,7 @@ module.exports = function(app) {
} }
function challengeMap({ user = {} }, res, next) { function challengeMap({ user = {} }, res, next) {
let lastCompleted;
const daysRunning = moment().diff(new Date('10/15/2014'), 'days'); const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
// if user // if user
@ -568,7 +552,13 @@ module.exports = function(app) {
}) })
.filter(({ name }) => name !== 'Hikes') .filter(({ name }) => name !== 'Hikes')
// turn stream of blocks into a stream of an array // turn stream of blocks into a stream of an array
.toArray(); .toArray()
.doOnNext((blocks) => {
const lastCompletedBlock = _.findLast(blocks, (block) => {
return block.completed === 100;
});
lastCompleted = lastCompletedBlock && lastCompletedBlock.name || null;
});
Observable.combineLatest( Observable.combineLatest(
camperCount$, camperCount$,
@ -581,6 +571,7 @@ module.exports = function(app) {
blocks, blocks,
daysRunning, daysRunning,
camperCount, camperCount,
lastCompleted,
title: "A map of all Free Code Camp's Challenges" title: "A map of all Free Code Camp's Challenges"
}); });
}, },

View File

@ -1,7 +1,7 @@
import { defaultProfileImage } from '../../common/utils/constantStrings.json'; import { defaultProfileImage } from '../../common/utils/constantStrings.json';
const message = const message =
'Learn to Code JavaScript and get a Coding Job by Helping Nonprofits'; 'Learn to Code and Build Projects for Nonprofits';
module.exports = function(app) { module.exports = function(app) {
var router = app.loopback.Router(); var router = app.loopback.Router();
@ -22,7 +22,7 @@ module.exports = function(app) {
function index(req, res) { function index(req, res) {
if (req.user) { if (req.user) {
return res.render('resources/get-started', { title: message }); return res.redirect('/map');
} }
res.render('home', { title: message }); res.render('home', { title: message });
} }

View File

@ -170,7 +170,6 @@ module.exports = function(app) {
title: story.headline, title: story.headline,
link: story.link, link: story.link,
originalStoryLink: dashedName, originalStoryLink: dashedName,
originalStoryAuthorEmail: story.author.email || '',
author: story.author, author: story.author,
rank: story.upVotes.length, rank: story.upVotes.length,
upVotes: story.upVotes, upVotes: story.upVotes,
@ -373,13 +372,11 @@ module.exports = function(app) {
author: { author: {
picture: req.user.picture, picture: req.user.picture,
userId: req.user.id, userId: req.user.id,
username: req.user.username, username: req.user.username
email: req.user.email
}, },
image: data.image, image: data.image,
storyLink: storyLink, storyLink: storyLink,
metaDescription: data.storyMetaDescription, metaDescription: data.storyMetaDescription
originalStoryAuthorEmail: req.user.email
}); });
return saveInstance(newStory); return saveInstance(newStory);
}); });

View File

@ -1,12 +1,12 @@
import _ from 'lodash'; import dedent from 'dedent';
import async from 'async';
import moment from 'moment'; import moment from 'moment';
import debugFactory from 'debug'; import debugFactory from 'debug';
import { ifNoUser401 } from '../utils/middleware'; import { ifNoUser401, ifNoUserRedirectTo } from '../utils/middleware';
const debug = debugFactory('freecc:boot:user'); const debug = debugFactory('freecc:boot:user');
const daysBetween = 1.5; const daysBetween = 1.5;
const sendNonUserToMap = ifNoUserRedirectTo('/map');
function calcCurrentStreak(cals) { function calcCurrentStreak(cals) {
const revCals = cals.concat([Date.now()]).slice().reverse(); const revCals = cals.concat([Date.now()]).slice().reverse();
@ -52,7 +52,7 @@ function dayDiff([head, tail]) {
module.exports = function(app) { module.exports = function(app) {
var router = app.loopback.Router(); var router = app.loopback.Router();
var User = app.models.User; var User = app.models.User;
var Story = app.models.Story; // var Story = app.models.Story;
router.get('/login', function(req, res) { router.get('/login', function(req, res) {
res.redirect(301, '/signin'); res.redirect(301, '/signin');
@ -68,14 +68,23 @@ module.exports = function(app) {
router.post('/reset-password', postReset); router.post('/reset-password', postReset);
router.get('/email-signup', getEmailSignup); router.get('/email-signup', getEmailSignup);
router.get('/email-signin', getEmailSignin); router.get('/email-signin', getEmailSignin);
router.get('/account/api', getAccountAngular); router.get(
'/toggle-lockdown-mode',
sendNonUserToMap,
toggleLockdownMode
);
router.post( router.post(
'/account/delete', '/account/delete',
ifNoUser401, ifNoUser401,
postDeleteAccount postDeleteAccount
); );
router.get('/account/unlink/:provider', getOauthUnlink); router.get(
router.get('/account', getAccount); '/account',
sendNonUserToMap,
getAccount
);
router.get('/vote1', vote1);
router.get('/vote2', vote2);
// Ensure this is the last route! // Ensure this is the last route!
router.get('/:username', returnUser); router.get('/:username', returnUser);
@ -114,18 +123,8 @@ module.exports = function(app) {
} }
function getAccount(req, res) { function getAccount(req, res) {
if (!req.user) { const { username } = req.user;
return res.redirect('/'); return res.redirect('/' + username);
}
res.render('account/account', {
title: 'Manage your Free Code Camp Account'
});
}
function getAccountAngular(req, res) {
res.json({
user: req.user || {}
});
} }
function returnUser(req, res, next) { function returnUser(req, res, next) {
@ -133,26 +132,18 @@ module.exports = function(app) {
const { path } = req; const { path } = req;
User.findOne( User.findOne(
{ where: { username } }, { where: { username } },
function(err, user) { function(err, profileUser) {
if (err) { if (err) {
return next(err); return next(err);
} }
if (!user) { if (!profileUser) {
req.flash('errors', { req.flash('errors', {
msg: `404: We couldn't find path ${ path }` msg: `404: We couldn't find path ${ path }`
}); });
return res.redirect('/'); return res.redirect('/');
} }
if (!user.isGithubCool && !user.isMigrationGrandfathered) {
req.flash('errors', {
msg: `
user ${ username } has not completed account signup
`
});
return res.redirect('/');
}
var cals = user var cals = profileUser
.progressTimestamps .progressTimestamps
.map(objOrNum => { .map(objOrNum => {
return typeof objOrNum === 'number' ? return typeof objOrNum === 'number' ?
@ -161,10 +152,10 @@ module.exports = function(app) {
}) })
.sort(); .sort();
user.currentStreak = calcCurrentStreak(cals); profileUser.currentStreak = calcCurrentStreak(cals);
user.longestStreak = calcLongestStreak(cals); profileUser.longestStreak = calcLongestStreak(cals);
const data = user const data = profileUser
.progressTimestamps .progressTimestamps
.map((objOrNum) => { .map((objOrNum) => {
return typeof objOrNum === 'number' ? return typeof objOrNum === 'number' ?
@ -179,39 +170,83 @@ module.exports = function(app) {
return data; return data;
}, {}); }, {});
const challenges = user.completedChallenges.filter(function(obj) { const baseAndZip = profileUser.completedChallenges.filter(
function(obj) {
return obj.challengeType === 3 || obj.challengeType === 4; return obj.challengeType === 3 || obj.challengeType === 4;
}); }
);
const bonfires = user.completedChallenges.filter(function(obj) { const bonfires = profileUser.completedChallenges.filter(function(obj) {
return obj.challengeType === 5 && (obj.name || '').match(/Bonfire/g); return obj.challengeType === 5 && (obj.name || '').match(/Bonfire/g);
}); });
const waypoints = profileUser.completedChallenges.filter(function(obj) {
return (obj.name || '').match(/^Waypoint/i);
});
res.render('account/show', { res.render('account/show', {
title: 'Camper ' + user.username + '\'s portfolio', title: 'Camper ' + profileUser.username + '\'s portfolio',
username: user.username, username: profileUser.username,
name: user.name, name: profileUser.name,
isMigrationGrandfathered: user.isMigrationGrandfathered, isMigrationGrandfathered: profileUser.isMigrationGrandfathered,
isGithubCool: user.isGithubCool, isGithubCool: profileUser.isGithubCool,
location: user.location, isLocked: !!profileUser.isLocked,
github: user.githubURL,
linkedin: user.linkedin, location: profileUser.location,
google: user.google,
facebook: user.facebook,
twitter: user.twitter,
picture: user.picture,
progressTimestamps: user.progressTimestamps,
calender: data, calender: data,
challenges: challenges,
bonfires: bonfires, github: profileUser.githubURL,
moment: moment, linkedin: profileUser.linkedin,
longestStreak: user.longestStreak, google: profileUser.google,
currentStreak: user.currentStreak facebook: profileUser.facebook,
twitter: profileUser.twitter,
picture: profileUser.picture,
progressTimestamps: profileUser.progressTimestamps,
baseAndZip,
bonfires,
waypoints,
moment,
longestStreak: profileUser.longestStreak,
currentStreak: profileUser.currentStreak
}); });
} }
); );
} }
function toggleLockdownMode(req, res, next) {
if (req.user.isLocked === true) {
req.user.isLocked = false;
return req.user.save(function(err) {
if (err) { return next(err); }
req.flash('success', {
msg: dedent`
Other people can now view all your challenge solutions.
You can change this back at any time in the "Manage My Account"
section at the bottom of this page.
`
});
res.redirect('/' + req.user.username);
});
}
req.user.isLocked = true;
return req.user.save(function(err) {
if (err) { return next(err); }
req.flash('success', {
msg: dedent`
All your challenge solutions are now hidden from other people.
You can change this back at any time in the "Manage My Account"
section at the bottom of this page.
`
});
res.redirect('/' + req.user.username);
});
}
function postDeleteAccount(req, res, next) { function postDeleteAccount(req, res, next) {
User.destroyById(req.user.id, function(err) { User.destroyById(req.user.id, function(err) {
if (err) { return next(err); } if (err) { return next(err); }
@ -221,25 +256,6 @@ module.exports = function(app) {
}); });
} }
function getOauthUnlink(req, res, next) {
var provider = req.params.provider;
User.findById(req.user.id, function(err, user) {
if (err) { return next(err); }
user[provider] = null;
user.tokens =
_.reject(user.tokens, function(token) {
return token.kind === provider;
});
user.save(function(err) {
if (err) { return next(err); }
req.flash('info', { msg: provider + ' account has been unlinked.' });
res.redirect('/account');
});
});
}
function getReset(req, res) { function getReset(req, res) {
if (!req.accessToken) { if (!req.accessToken) {
req.flash('errors', { msg: 'access token invalid' }); req.flash('errors', { msg: 'access token invalid' });
@ -312,6 +328,7 @@ module.exports = function(app) {
}); });
} }
/*
function updateUserStoryPictures(userId, picture, username, cb) { function updateUserStoryPictures(userId, picture, username, cb) {
Story.find({ 'author.userId': userId }, function(err, stories) { Story.find({ 'author.userId': userId }, function(err, stories) {
if (err) { return cb(err); } if (err) { return cb(err); }
@ -332,4 +349,35 @@ module.exports = function(app) {
}); });
}); });
} }
*/
function vote1(req, res, next) {
if (req.user) {
req.user.tshirtVote = 1;
req.user.save(function(err) {
if (err) { return next(err); }
req.flash('success', { msg: 'Thanks for voting!' });
res.redirect('/map');
});
} else {
req.flash('error', { msg: 'You must be signed in to vote.' });
res.redirect('/map');
}
}
function vote2(req, res, next) {
if (req.user) {
req.user.tshirtVote = 2;
req.user.save(function(err) {
if (err) { return next(err); }
req.flash('success', { msg: 'Thanks for voting!' });
res.redirect('/map');
});
} else {
req.flash('error', {msg: 'You must be signed in to vote.'});
res.redirect('/map');
}
}
}; };

View File

@ -4,5 +4,5 @@ files are generated at runtime and their content is determined by
the content of the files they are derived from. the content of the files they are derived from.
Since the build process is not exactly the same on every machine, Since the build process is not exactly the same on every machine,
this files are not tracked in github otherwise conflicts arise when these files are not tracked in github otherwise conflicts arise when
building on our servers. building on our servers.

View File

@ -12,20 +12,27 @@ const pathsOfNoReturn = [
'css' 'css'
]; ];
const pathsWhiteList = [
'news',
'challenges',
'map',
'news'
];
const pathsOfNoReturnRegex = new RegExp(pathsOfNoReturn.join('|'), 'i'); const pathsOfNoReturnRegex = new RegExp(pathsOfNoReturn.join('|'), 'i');
const whiteListRegex = new RegExp(pathsWhiteList.join('|'), 'i');
export default function addReturnToUrl() { export default function addReturnToUrl() {
return function(req, res, next) { return function(req, res, next) {
// Remember original destination before login. // Remember original destination before login.
var path = req.path.split('/')[1]; var path = req.path.split('/')[1];
if (req.method !== 'GET') { if (
return next(); req.method !== 'GET' ||
} pathsOfNoReturnRegex.test(path) ||
if (pathsOfNoReturnRegex.test(path)) { !whiteListRegex.test(path) ||
return next(); (/news/i).test(path) && (/hot/i).test(req.path)
} ) {
if (/\/stories\/\w+/i.test(req.path)) {
return next(); return next();
} }
req.session.returnTo = req.path; req.session.returnTo = req.path;

View File

@ -1,6 +1,8 @@
import manifest from '../rev-manifest.json'; import manifest from '../rev-manifest.json';
const __DEV__ = process.env.NODE_ENV === 'development'; const __DEV__ = process.env.NODE_ENV === 'development';
const manifestPath = '../rev-manifest.json';
export default function({ globalPrepend = '' } = {}) { export default function({ globalPrepend = '' } = {}) {
function rev(manifest, scopedPrepend, asset) { function rev(manifest, scopedPrepend, asset) {
@ -13,7 +15,10 @@ export default function({ globalPrepend = '' } = {}) {
// this means we do not need to restart server on every change to // this means we do not need to restart server on every change to
// client code // client code
if (__DEV__) { if (__DEV__) {
const manifest = require('../rev-manifest.json'); // we first need to remove the manifest from require cache
delete require.cache[require.resolve(manifestPath)];
// and re-require
const manifest = require(manifestPath);
res.locals.rev = rev.bind(null, manifest); res.locals.rev = rev.bind(null, manifest);
return next(); return next();
} }

View File

@ -2,8 +2,12 @@ export default function getJobServices(app) {
const { Job } = app.models; const { Job } = app.models;
return { return {
name: 'job', name: 'jobs',
read: (req, resource, params, config, cb) => { read: (req, resource, params, config, cb) => {
const id = params ? params.id : null;
if (id) {
return Job.findById(id, cb);
}
Job.find({}, (err, jobs) => { Job.find({}, (err, jobs) => {
cb(err, jobs); cb(err, jobs);
}); });

View File

@ -1,75 +0,0 @@
extends ../layout
block content
script.
var challengeName = 'Account View'
.panel.panel-info
.panel-heading.text-center Manage your account here
.panel-body
.row
.col-xs-12
if (!user.isGithubCool)
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
i.fa.fa-github
| Link my GitHub to unlock this profile
else
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
i.fa.fa-github
| Update my profile from GitHub
if (!user.twitter)
.col-xs-12
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
i.fa.fa-twitter
| Add my Twitter to my profile
if (!user.facebook)
.col-xs-12
a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
i.fa.fa-facebook
| Add my Facebook to my profile
if (!user.linkedin)
.col-xs-12
a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
i.fa.fa-linkedin
| Add my LinkedIn to my profile
if (!user.google)
.col-xs-12
a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
i.fa.fa-google-plus
| Add my Google+ to my profile
.big-spacer
.col-xs-12
a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
span.ion-android-exit
| Sign me out of Free Code Camp
.col-xs-12
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com')
span.ion-email
| Email us at team@freecodecamp.com
.col-xs-12
a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion
span.ion-trash-b
| Delete my Free Code Camp account
script.
$('.confirm-deletion').on("click", function() {
$('#modal-dialog').modal('show');
});
#modal-dialog.modal.animated.wobble
.modal-dialog
.modal-content
.modal-header
a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
h3 Are you really leaving us?
.modal-body
p Pro Tip: If you tweet feedback to&thinsp;
a(href="https://twitter.com/intent/tweet?text=Hey%20@freecodecamp") @FreeCodeCamp
| ,&thinsp;we'll act quickly on it!
.modal-footer
a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
span.ion-happy
| Nevermind, I'll stick around
br
form(action='/account/delete', method='POST')
input(type='hidden', name='_csrf', value=_csrf)
button.btn.btn-danger.btn-block(type='submit')
span.ion-trash-b
| Yes, delete my account

View File

@ -3,21 +3,43 @@ block content
script(src="/bower_components/cal-heatmap/cal-heatmap.min.js") script(src="/bower_components/cal-heatmap/cal-heatmap.min.js")
script. script.
var challengeName = 'Profile View'; var challengeName = 'Profile View';
if (user && user.username === username)
.panel.panel-info
.panel-heading.text-center Update Your Portfolio
.panel-body
.row
.col-xs-12
if (!user.isGithubCool)
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
i.fa.fa-github
| Link my GitHub to unlock this profile
else
a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
i.fa.fa-github
| Update my profile from GitHub
if (!user.twitter)
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
i.fa.fa-twitter
| Add my Twitter to my profile
if (!user.facebook)
a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
i.fa.fa-facebook
| Add my Facebook to my profile
if (!user.linkedin)
a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
i.fa.fa-linkedin
| Add my LinkedIn to my profile
if (!user.google)
a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
i.fa.fa-google-plus
| Add my Google+ to my profile
.panel.panel-info .panel.panel-info
.panel-heading.text-center .panel-heading.text-center
h1 #{username}'s portfolio h1 #{username}'s portfolio
.panel-body .panel-body
if (user && user.username === username)
.row.text-center
.col-xs-12.col-sm-10.col-sm-offset-1
a.btn.btn-big.btn-primary.btn-block(href="/account") Manage my account
.button-spacer
.col-xs-12.col-sm-10.col-sm-offset-1
a.btn.btn-big.btn-success.btn-block(href="/signout") Sign out of Free Code Camp
.spacer
.row .row
.col-xs-12 .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2.text-center
.col-xs-12.col-sm-12.col-md-5
if picture if picture
img.img-center.img-responsive.public-profile-img(src=picture) img.img-center.img-responsive.public-profile-img(src=picture)
else else
@ -33,18 +55,14 @@ block content
a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank') a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank')
if (google) if (google)
a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank') a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank')
.visible-md.visible-lg
.col-xs-12.col-sm-12.col-md-4.text-justify
h1.flat-top.wrappable= name h1.flat-top.wrappable= name
h3.flat-top.bolded.wrappable= location h1.flat-top.wrappable= location
.visible-xs.visible-sm h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]"
.col-xs-12.col-sm-12.col-md-4.text-center if (user && user.username !== username)
h1.flat-top.wrappable= name a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
h3.flat-top.bolded.wrappable= location i.fa.fa-plus-square
.col-xs-12.col-sm-12.col-md-3.text-center | Add them to my personal leaderboard
.background-svg.img-center
.points-on-top
= "[ " + (progressTimestamps.length) + " ]"
.spacer .spacer
.hidden-xs.hidden-sm.col-md-12 .hidden-xs.hidden-sm.col-md-12
#cal-heatmap.d3-centered #cal-heatmap.d3-centered
@ -79,23 +97,22 @@ block content
h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak + currentStreak === 1 ? ' day' : ' days'} h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak + currentStreak === 1 ? ' day' : ' days'}
if (challenges.length > 0) if (user && user.username == username || !isLocked)
if (baseAndZip.length > 0)
.col-sm-12 .col-sm-12
table.table.table-striped table.table.table-striped
thead thead
tr tr
th.col-xs-4 Challenge th.col-xs-4 Project
th.col-xs-2 Completed th.col-xs-2 Completed
th.col-xs-6 Link th.col-xs-6 Link
for challenge in challenges for challenge in baseAndZip
tr tr
td.col-xs-4 td.col-xs-4
a(href='/challenges/' + challenge.name, target='_blank')= challenge.name a(href='/challenges/' + challenge.name, target='_blank')= challenge.name
td.col-xs-2= moment(challenge.completedDate, 'x').format("MMM DD, YYYY") td.col-xs-2= moment(challenge.completedDate, 'x').format("MMM DD, YYYY")
td.col-xs-6 td.col-xs-6
a(href=challenge.solution, target='_blank') View my solution a(href=challenge.solution, target='_blank') View my project
if (user && user.username === username)
br
if (bonfires.length > 0) if (bonfires.length > 0)
.col-sm-12 .col-sm-12
table.table.table-striped table.table.table-striped
@ -106,9 +123,77 @@ block content
th.col-xs-6 Solution th.col-xs-6 Solution
for bonfire in bonfires for bonfire in bonfires
tr tr
td.col-xs-4 td.col-xs-4= bonfire.name
a(href='/challenges/' + bonfire.name, target='_blank')= bonfire.name
td.col-xs-2= moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") td.col-xs-2= moment(bonfire.completedDate, 'x').format("MMM DD, YYYY")
td.col-xs-6 td.col-xs-6
pre.wrappable= bonfire.solution a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(bonfire.solution), target='_blank') View my solution
br if (waypoints.length > 0)
.col-sm-12
table.table.table-striped
thead
tr
th.col-xs-4 Waypoints
th.col-xs-2 Completed
th.col-xs-6 Solution
for challenge in waypoints
tr
td.col-xs-4= challenge.name
td.col-xs-2= moment(challenge.completedDate, 'x').format("MMM DD, YYYY")
td.col-xs-6
if (challenge.solution)
a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(challenge.solution), target='_blank') View my solution
else
a(href='/challenges/' + challenge.name) View this challenge
if (user && user.username === username)
.panel.panel-info
.panel-heading.text-center Manage Your Account
.panel-body
.col-xs-12
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com')
span.ion-email
| Email us at team@freecodecamp.com
if (!user.isLocked)
.col-xs-12
a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode')
span.ion-locked
| Hide all my solutions from other people
else
.col-xs-12
a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode')
span.ion-unlocked
| Let other people see all my solutions
.col-xs-12
a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
span.ion-android-exit
| Sign me out of Free Code Camp
.col-xs-12
a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion
span.ion-trash-b
| Delete my Free Code Camp account
script.
$('.confirm-deletion').on("click", function () {
$('#modal-dialog').modal('show');
});
#modal-dialog.modal.animated.wobble
.modal-dialog
.modal-content
.modal-header
a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
h3 You don't really want to delete your account, do you?
.modal-body
p This will really delete all your data, including all your progress, news stories and brownie points.
p We won't be able to recover any of it for you later, even if you change your mind.
p If there's something we could do better, send us an email instead and we'll do our best: &thinsp;
a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
| .
.modal-footer
a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
span.ion-happy
| Nevermind, I don't want to delete all my progress
.btn-spacer
form(action='/account/delete', method='POST')
input(type='hidden', name='_csrf', value=_csrf)
button.btn.btn-danger.btn-block(type='submit')
span.ion-trash-b
| I am 100% sure I want to delete all my progress

View File

@ -5,9 +5,6 @@ block content
a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github') a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github')
i.fa.fa-github i.fa.fa-github
| Sign in with Github | Sign in with Github
a.btn.btn-lg.btn-block.btn-twitter.btn-social(href='/auth/twitter')
i.fa.fa-twitter
| Sign in with Twitter
a.btn.btn-lg.btn-block.btn-facebook.btn-social(href='/auth/facebook') a.btn.btn-lg.btn-block.btn-facebook.btn-social(href='/auth/facebook')
i.fa.fa-facebook i.fa.fa-facebook
| Sign in with Facebook | Sign in with Facebook
@ -17,8 +14,11 @@ block content
a.btn.btn-lg.btn-block.btn-linkedin.btn-social(href='/auth/linkedin') a.btn.btn-lg.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')
i.fa.fa-linkedin i.fa.fa-linkedin
| Sign in with LinkedIn | Sign in with LinkedIn
a.btn.btn-lg.btn-block.btn-twitter.btn-social(href='/auth/twitter')
i.fa.fa-twitter
| Sign in with Twitter
br br
p p
a(href="/email-signup") Or sign up using your email address here. a(href="/email-signup") Or sign up using your email address here.
p p
a(href="/email-signin") Sign in to your existing account with your email address here. a(href="/email-signin") If you originally signed up using your email address, you can sign in here.

View File

@ -9,7 +9,7 @@ block content
audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3')
else else
img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png')
.col-xs-12.col-md-10.col-md-offset-1 .col-xs-12.col-md-8.col-md-offset-2
h2.text-center h2.text-center
span.text-primary #{camperCount} &thinsp; span.text-primary #{camperCount} &thinsp;
| campers have joined our community | campers have joined our community
@ -18,6 +18,35 @@ block content
span.text-primary #{daysRunning} &thinsp; span.text-primary #{daysRunning} &thinsp;
| days ago. | days ago.
.spacer .spacer
if (user && !user.tshirtVote && user.progressTimestamps.length > 5)
h3.text-center Vote for the T-shirt design you like the most.
h4.text-center We'll announce the winning design during our Summit on Saturday at Noon EST on&thinsp;
a(href='https://twitch.tv/freecodecamp' target='_blank') Twitch.tv
| &thinsp;and it will become our community's first official t-shirt (in women's and men's sizes).
.row
.col-xs-6
a(href="http://i.imgur.com/LlXGa5y.png" data-lightbox="img-enlarge")
img.img-responsive(src='http://i.imgur.com/LlXGa5y.png' alt="t-shirt option 1 women's")
.col-xs-6
a(href="http://i.imgur.com/aefwnnv.png" data-lightbox="img-enlarge")
img.img-responsive(src='http://i.imgur.com/aefwnnv.png' alt="t-shirt option 2 women's")
.button-spacer
.row
.col-xs-6
a(href="http://i.imgur.com/aYH0aqf.png" data-lightbox="img-enlarge")
img.img-responsive(src='http://i.imgur.com/aYH0aqf.png' alt="t-shirt option 1 men's")
.col-xs-6
a(href="http://i.imgur.com/v9KlV4g.png" data-lightbox="img-enlarge")
img.img-responsive(src='http://i.imgur.com/v9KlV4g.png' alt="t-shirt option 2 men's")
.button-spacer
.row
.col-xs-6
h3.text-center "Minified JavaScript Logo"
a.button.btn.btn-block.btn-primary(href='/vote1') Vote for this Design
.col-xs-6
h3.text-center "Function Call Logo"
a.button.btn.btn-block.btn-primary(href='/vote2') Vote for this design
.spacer
.row .row
.col-xs-12.col-sm-8.col-sm-offset-2 .col-xs-12.col-sm-8.col-sm-offset-2
h3 800 Hours of Practice: h3 800 Hours of Practice:
@ -26,22 +55,22 @@ block content
.row .row
if (user) if (user)
if (challengeBlock.completed === 100) if (challengeBlock.completed === 100)
.hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.faded.negative-10 li.map-p.faded.negative-10
a(href='#' + challengeBlock.dashedName)= challengeBlock.name a(href='#' + challengeBlock.dashedName)= challengeBlock.name
else else
.hidden-xs.col-sm-3.col-md-2 .hidden-xs.col-sm-3.col-md-2
.progress.progress-bar-padding.text-center.thin-progress-bar .progress.progress-bar-padding.text-center.thin-progress-bar
.progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;')
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 li.map-p.negative-10
a(href='#' + challengeBlock.dashedName)= challengeBlock.name a(href='#' + challengeBlock.dashedName)= challengeBlock.name
else else
.hidden-xs.col-sm-3.col-md-2 .hidden-xs.col-sm-3.col-md-2
span.negative-10 span.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 li.map-p.negative-10
a(href='#' + challengeBlock.dashedName)= challengeBlock.name a(href='#' + challengeBlock.dashedName)= challengeBlock.name
.row .row
@ -51,21 +80,21 @@ block content
| : | :
ol ol
.row .row
.hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 100-hour Nonprofit Project li.map-p.negative-10 100-hour Nonprofit Project
.row .row
.hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 200-hour Nonprofit Project #1 li.map-p.negative-10 200-hour Nonprofit Project #1
.row .row
.hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 200-hour Nonprofit Project #2 li.map-p.negative-10 200-hour Nonprofit Project #2
.row .row
.hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 300-hour Nonprofit Project li.map-p.negative-10 300-hour Nonprofit Project
hr hr
for challengeBlock in blocks for challengeBlock in blocks
@ -82,9 +111,9 @@ block content
for challenge in challengeBlock.challenges for challenge in challengeBlock.challenges
if challenge.completed if challenge.completed
.row .row
.hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.large-p.negative-10 .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.faded.large-p.negative-10 li.faded.map-p.negative-10
a(href="/challenges/#{challenge.dashedName}") a(href="/challenges/#{challenge.dashedName}")
span.capitalize= challenge.type + ': ' span.capitalize= challenge.type + ': '
span= challenge.title span= challenge.title
@ -96,12 +125,21 @@ block content
.hidden-xs.col-sm-3.col-md-2 .hidden-xs.col-sm-3.col-md-2
span.negative-10 span.negative-10
.col-xs-12.col-sm-9.col-md-10 .col-xs-12.col-sm-9.col-md-10
li.large-p.negative-10 li.map-p.negative-10
a(href="/challenges/#{challenge.dashedName}") a(href="/challenges/#{challenge.dashedName}")
span.capitalize= challenge.type + ': ' span.capitalize= challenge.type + ': '
span= challenge.title span= challenge.title
span.sr-only= " Incomplete" span.sr-only= " Incomplete"
if (challengeBlock.completed === 100)
.button-spacer
.row
.col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden
a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your Portfolio with your friends.
.hidden(id="#{challengeBlock.name}")
script.
var username = !{JSON.stringify(user && user.username || '')};
var lastCompleted = !{JSON.stringify(lastCompleted || false)}
// #announcementModal.modal(tabindex='-1') // #announcementModal.modal(tabindex='-1')
// .modal-dialog.animated.fadeInUp.fast-animation // .modal-dialog.animated.fadeInUp.fast-animation
// .modal-content // .modal-content

View File

@ -1,9 +0,0 @@
//
Created by nathanleniz on 5/19/15.
extends ../layout-wide
block content
script.
var stuff = !{JSON.stringify(stuff)};
var challengeMapWithIds = !{JSON.stringify(stuffWithIds)};

View File

@ -11,60 +11,22 @@ block content
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css') link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css') link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css') link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
link(rel="stylesheet", href="//fonts.googleapis.com/css?family=Ubuntu+Mono") link(rel='stylesheet', href='/css/ubuntu.css')
script(type='text/javascript', src='/js/lib/codemirror/mode/javascript/javascript.js') script(type='text/javascript', src='/js/lib/codemirror/mode/javascript/javascript.js')
script(type='text/javascript', src='/js/lib/jailed/jailed.js') script(type='text/javascript', src='/js/lib/jailed/jailed.js')
.row(ng-controller="pairedWithController") .row(ng-controller="pairedWithController")
.col-xs-12.col-sm-12.col-md-4.col-lg-3 .col-md-4.col-lg-3
.scroll-locker(id = "scroll-locker") .scroll-locker(id = "scroll-locker")
.innerMarginFix(style=' width: 99%') .innerMarginFix(style=' width: 99%')
#testCreatePanel.well #testCreatePanel.well
h3.text-center.negative-10= name h3.text-center.negative-10= name
.positive-15.positive-15-bottom
h4.text-center.bonfire-flames Difficulty:&thinsp;
if (difficulty == "0")
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
if (difficulty == "1")
i.ion-ios-flame
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
if (difficulty == "2")
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame-outline
i.ion-ios-flame-outline
i.ion-ios-flame-outline
if (difficulty == "3")
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame-outline
i.ion-ios-flame-outline
if (difficulty == "4")
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame-outline
if (difficulty == "5")
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
i.ion-ios-flame
.row .row
.col-xs-12 .col-xs-12
.bonfire-instructions .bonfire-instructions
for sentence in details for sentence in details
p.wrappable.negative-10!= sentence p.wrappable.negative-10!= sentence
.negative-bottom-margin-30 .negative-30-bottom
#MDN-links #MDN-links
p.negative-10 Here are some helpful links: p.negative-10 Here are some helpful links:
for link, index in MDNlinks for link, index in MDNlinks
@ -82,7 +44,7 @@ block content
alert(type='danger') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Username not found | Username not found
label.negative-10.btn.btn-primary.btn-block#submitButton label.negative-10.btn.btn-primary.btn-block.btn-lg#submitButton
i.fa.fa-play i.fa.fa-play
| &nbsp; Run tests (ctrl + enter) | &nbsp; Run tests (ctrl + enter)
.button-spacer .button-spacer
@ -93,14 +55,15 @@ block content
label.btn.btn-success#trigger-help-modal label.btn.btn-success#trigger-help-modal
i.fa.fa-medkit i.fa.fa-medkit
| &nbsp; Help | &nbsp; Help
label.btn.btn-success#trigger-pair-modal
i.fa.fa-user-plus
| &nbsp; Pair
label.btn.btn-success#trigger-issue-modal label.btn.btn-success#trigger-issue-modal
i.fa.fa-bug i.fa.fa-bug
| &nbsp; Bug | &nbsp; Bug
if (!user)
.button-spacer
a.btn.signup-btn.btn-block.btn-block(href='/login') Sign in so you can save your progress
script.
var userLoggedIn = false;
.button-spacer .button-spacer
form.code form.code
.form-group.codeMirrorView .form-group.codeMirrorView
textarea#codeOutput(style='display: none;') textarea#codeOutput(style='display: none;')
@ -114,10 +77,11 @@ block content
var challenge_Name = !{JSON.stringify(name)}; var challenge_Name = !{JSON.stringify(name)};
var started = Math.floor(Date.now()); var started = Math.floor(Date.now());
var challengeType = !{JSON.stringify(challengeType)}; var challengeType = !{JSON.stringify(challengeType)};
var dashedName = !{JSON.stringify(dashedName)};
var _ = R; var _ = R;
var dashed = !{JSON.stringify(dashedName)}; var dashed = !{JSON.stringify(dashedName)};
.col-xs-12.col-sm-12.col-md-8 .col-md-8.col-lg-9
.editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;") .editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;")
#mainEditorPanel #mainEditorPanel
form.code form.code
@ -128,7 +92,7 @@ block content
editor.setOption("mode", "javascript"); editor.setOption("mode", "javascript");
#complete-courseware-dialog.modal(tabindex='-1') #complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header= compliment .modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
@ -140,14 +104,13 @@ block content
.spacer .spacer
.row .row
if (user) if (user)
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to next challenge #submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
if (user.progressTimestamps.length > 2) if (user.progressTimestamps.length > 2)
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(target="_blank", href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{dashedName}&hashtags=LearnToCode, JavaScript") a.btn.btn-lg.btn-block.btn-twitter(target="_blank", href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{dashedName}&hashtags=LearnToCode, JavaScript")
i.fa.fa-twitter &thinsp; i.fa.fa-twitter &thinsp;
= phrase = phrase
else else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
#reset-modal.modal(tabindex='-1') #reset-modal.modal(tabindex='-1')
.modal-dialog.animated.fadeInUp.fast-animation .modal-dialog.animated.fadeInUp.fast-animation
.modal-content .modal-content
@ -163,4 +126,3 @@ block content
if (!MDNlinks.length) { if (!MDNlinks.length) {
$('#MDN-links').addClass('collapse'); $('#MDN-links').addClass('collapse');
} }

View File

@ -11,7 +11,7 @@ block content
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css') link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css') link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css') link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono") link(rel='stylesheet', href='/css/ubuntu.css')
script(src='/js/lib/codemirror/mode/javascript/javascript.js') script(src='/js/lib/codemirror/mode/javascript/javascript.js')
script(src='/js/lib/jailed/jailed.js') script(src='/js/lib/jailed/jailed.js')
script(src='/js/lib/codemirror/mode/xml/xml.js') script(src='/js/lib/codemirror/mode/xml/xml.js')
@ -19,7 +19,7 @@ block content
script(src='/js/lib/codemirror/mode/htmlmixed/htmlmixed.js') script(src='/js/lib/codemirror/mode/htmlmixed/htmlmixed.js')
script(src='/js/lib/codemirror/addon/emmet/emmet.js') script(src='/js/lib/codemirror/addon/emmet/emmet.js')
.row.courseware-height .row.courseware-height
.col-xs-12.col-sm-12.col-md-3.col-lg-3 .col-md-3.col-lg-3
.scroll-locker(id = "scroll-locker") .scroll-locker(id = "scroll-locker")
.innerMarginFix(style = "width: 99%;") .innerMarginFix(style = "width: 99%;")
.well .well
@ -30,11 +30,9 @@ block content
for sentence in details for sentence in details
p.wrappable.negative-10!= sentence p.wrappable.negative-10!= sentence
.negative-bottom-margin-30 .negative-bottom-margin-30
label.negative-10.btn.btn-primary.btn-block#submitButton label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton
i.fa.fa-play i.fa.fa-play
| &nbsp; Run tests (ctrl + enter) | &nbsp; Run tests (ctrl + enter)
br
if (user)
.button-spacer .button-spacer
.btn-group.input-group.btn-group-justified .btn-group.input-group.btn-group-justified
label.btn.btn-success#trigger-reset-modal label.btn.btn-success#trigger-reset-modal
@ -48,13 +46,13 @@ block content
| &nbsp; Bug | &nbsp; Bug
script. script.
var userLoggedIn = true; var userLoggedIn = true;
else if (!user)
.button-spacer .button-spacer
a.btn.signup-btn.btn-block.btn-block.negative-15(href='/login') Sign in so you can save your progress a.btn.signup-btn.btn-block.btn-block(href='/login') Sign in so you can save your progress
script. script.
var userLoggedIn = false; var userLoggedIn = false;
.button-spacer .button-spacer
ul#testSuite.list-group #testSuite
br br
script(type="text/javascript"). script(type="text/javascript").
$('#next-courseware-button').attr('disabled', 'disabled'); $('#next-courseware-button').attr('disabled', 'disabled');
@ -63,9 +61,10 @@ block content
var challenge_Id = !{JSON.stringify(challengeId)}; var challenge_Id = !{JSON.stringify(challengeId)};
var challenge_Name = !{JSON.stringify(name)}; var challenge_Name = !{JSON.stringify(name)};
var prodOrDev = !{JSON.stringify(environment)}; var prodOrDev = !{JSON.stringify(environment)};
var dashedName = !{JSON.stringify(dashedName)};
var challengeType = !{JSON.stringify(challengeType)}; var challengeType = !{JSON.stringify(challengeType)};
var started = Math.floor(Date.now()); var started = Math.floor(Date.now());
.col-xs-12.col-sm-12.col-md-5.col-lg-6 .col-md-5.col-lg-6
.editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;") .editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;")
#mainEditorPanel #mainEditorPanel
form.code form.code
@ -80,7 +79,7 @@ block content
iframe.iphone.iframe-scroll#preview iframe.iphone.iframe-scroll#preview
.spacer .spacer
#complete-courseware-dialog.modal(tabindex='-1') #complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header .modal-header.challenge-list-header
= compliment = compliment
@ -91,9 +90,8 @@ block content
#challenge-checkmark.animated.zoomInDown.delay-half #challenge-checkmark.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary span.completion-icon.ion-checkmark-circled.text-primary
.spacer .spacer
.row
if(user) if(user)
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to next challenge #submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
else else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
include ../partials/challenge-modals include ../partials/challenge-modals

View File

@ -10,11 +10,11 @@ block content
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css') link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css') link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css') link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
link(rel="stylesheet", href="//fonts.googleapis.com/css?family=Ubuntu+Mono") link(rel='stylesheet', href='/css/ubuntu.css')
script(type='text/javascript', src='/js/lib/codemirror/mode/javascript/javascript.js') script(type='text/javascript', src='/js/lib/codemirror/mode/javascript/javascript.js')
script(type='text/javascript', src='/js/lib/jailed/jailed.js') script(type='text/javascript', src='/js/lib/jailed/jailed.js')
.row(ng-controller="pairedWithController") .row(ng-controller="pairedWithController")
.col-xs-12.col-sm-12.col-md-4.col-lg-3 .col-md-4.col-lg-3
.scroll-locker(id = "scroll-locker") .scroll-locker(id = "scroll-locker")
.innerMarginFix(style = "width: 99%;") .innerMarginFix(style = "width: 99%;")
#testCreatePanel.well #testCreatePanel.well
@ -35,7 +35,7 @@ block content
.form-group.text-center.negative-10 .form-group.text-center.negative-10
.col-xs-12 .col-xs-12
// extra field to distract password tools like lastpass from injecting css into our username field // extra field to distract password tools like lastpass from injecting css into our username field
label.negative-10.btn.btn-primary.btn-block#submitButton label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton
i.fa.fa-play i.fa.fa-play
| &nbsp; Run tests (ctrl + enter) | &nbsp; Run tests (ctrl + enter)
.button-spacer .button-spacer
@ -49,6 +49,11 @@ block content
label.btn.btn-success#trigger-issue-modal label.btn.btn-success#trigger-issue-modal
i.fa.fa-bug i.fa.fa-bug
| &nbsp; Bug | &nbsp; Bug
if (!user)
.button-spacer
a.btn.signup-btn.btn-block.btn-block(href='/login') Sign in so you can save your progress
script.
var userLoggedIn = false;
.button-spacer .button-spacer
form.code form.code
.form-group.codeMirrorView .form-group.codeMirrorView
@ -61,11 +66,12 @@ block content
var challengeSeed = !{JSON.stringify(challengeSeed)}; var challengeSeed = !{JSON.stringify(challengeSeed)};
var challenge_Id = !{JSON.stringify(challengeId)}; var challenge_Id = !{JSON.stringify(challengeId)};
var challenge_Name = !{JSON.stringify(name)}; var challenge_Name = !{JSON.stringify(name)};
var dashedName = !{JSON.stringify(dashedName)};
var started = Math.floor(Date.now()); var started = Math.floor(Date.now());
var challengeType = !{JSON.stringify(challengeType)}; var challengeType = !{JSON.stringify(challengeType)};
var _ = R; var _ = R;
var dashed = !{JSON.stringify(dashedName)}; var dashed = !{JSON.stringify(dashedName)};
.col-xs-12.col-sm-12.col-md-8 .col-md-8.col-lg-9
.editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;") .editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;")
#mainEditorPanel #mainEditorPanel
form.code form.code
@ -75,7 +81,7 @@ block content
script. script.
editor.setOption("mode", "javascript"); editor.setOption("mode", "javascript");
#complete-courseware-dialog.modal(tabindex='-1') #complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header= compliment .modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
@ -87,13 +93,9 @@ block content
.spacer .spacer
.row .row
if (user) if (user)
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to next challenge #submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
if (user.progressTimestamps.length > 2)
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(target="_blank", href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{dashedName}&hashtags=LearnToCode, JavaScript")
i.fa.fa-twitter &thinsp;
= phrase
else else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
include ../partials/challenge-modals include ../partials/challenge-modals
script. script.
var MDNlinks = !{JSON.stringify(MDNlinks)}; var MDNlinks = !{JSON.stringify(MDNlinks)};

View File

@ -0,0 +1,39 @@
extends ../layout-wide
block content
.row
.col-md-8.col-md-offset-2
.jumbotron
for step, index in description
.thumbnail.challenge-step(class=index !== 0 ? 'hidden': '')
img.gif-block.img-center.img-responsive.thumbnail(src='#{step[0]}' alt='#{step[1]}')
.caption
p.large-p= step[2]
if step[3]
a.btn.btn-block.btn-primary.challenge-step-btn-action(href='#{step[3]}' target='_blank') Go To Link
if index + 1 === description.length
.btn.btn-block.btn-primary.challenge-step-btn-finish(id='last' class=step[3] ? 'disabled' : '') Finish challenge
else
.btn.btn-block.btn-primary.challenge-step-btn-next(id='#{index}' class=step[3] ? 'disabled' : '') Go to my next step
#challenge-step-modal.modal(tabindex='-1')
.modal-dialog.animated.fadeIn.fast-animation
.modal-content
.modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body
.text-center
#checkmark-container.row
#challenge-checkmark.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary
.spacer
.row
if (user)
#challenge-step-btn-submit.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
else
a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
script(src=rev('/js', 'commonFramework.js'))
script.
var common = common || { init: [] };
common.challengeId = !{JSON.stringify(challengeId)};
common.challengeName = !{JSON.stringify(name)};
common.challengeType = 7;
common.dashedName = !{JSON.stringify(dashedName || '')};

View File

@ -15,21 +15,23 @@ block content
.col-xs-12.col-sm-12.col-md-8 .col-xs-12.col-sm-12.col-md-8
.embed-responsive.embed-responsive-16by9 .embed-responsive.embed-responsive-16by9
iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}') iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
br .spacer
if (user) if (user)
a.btn.btn-primary.btn-big.btn-block#completed-courseware-editorless I've completed this challenge (ctrl + enter) a.btn.btn-primary.btn-big.btn-block#completed-courseware-editorless I've completed this challenge (ctrl + enter)
else
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
script. script.
var userLoggedIn = true; var userLoggedIn = true;
.button-spacer .button-spacer
.btn-group.input-group.btn-group-justified .btn-group.input-group.btn-group-justified
.btn.btn-success.btn-big#trigger-help-modal-modal .btn.btn-success.btn-big#trigger-help-modal
i.fa.fa-medkit i.fa.fa-medkit
| &nbsp; Get help | &nbsp; Get help
.btn.btn-success.btn-big#trigger-issue-modal .btn.btn-success.btn-big#trigger-issue-modal
i.fa.fa-bug i.fa.fa-bug
| &nbsp; Report a bug | &nbsp; Report a bug
if (!user)
.button-spacer .button-spacer
else
a.btn.btn-big.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.btn.btn-big.signup-btn.btn-block(href='/login') Sign in so you can save your progress
script. script.
var userLoggedIn = false; var userLoggedIn = false;
@ -55,31 +57,25 @@ block content
}; };
#complete-courseware-editorless-dialog.modal(tabindex='-1') #complete-courseware-editorless-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header= compliment .modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body(ng-controller="pairedWithController") .modal-body(ng-controller="pairedWithController")
.text-center .text-center
.animated.zoomInDown.delay-half .animated.zoomInDown
span.completion-icon.ion-checkmark-circled.text-primary span.completion-icon.ion-checkmark-circled.text-primary
if (user) if (user)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf) On to my next challenge (ctrl + enter) a.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf) I've completed this challenge (ctrl + enter)
script. script.
$('#complete-courseware-editorless-dialog').bind('keypress', modalControlEnterHandler); $('#complete-courseware-editorless-dialog').bind('keypress', modalControlEnterHandler);
if (user.progressTimestamps.length > 2)
.button-spacer
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{dashedName}&hashtags=LearnToCode, JavaScript" target="_blank")
i.fa.fa-twitter &thinsp;
= phrase
else else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
h1 #{name}
script. script.
$('body').bind('keypress', controlEnterHandler); $('body').bind('keypress', controlEnterHandler);
script. script.
var challenge_Id = !{JSON.stringify(challengeId)}; var challenge_Id = !{JSON.stringify(challengeId)};
var challenge_Name = !{JSON.stringify(name)}; var challenge_Name = !{JSON.stringify(name)};
var challengeType = !{JSON.stringify(challengeType)}; var challengeType = !{JSON.stringify(challengeType)};
var dashedName = !{JSON.stringify(dashedName)};
include ../partials/challenge-modals include ../partials/challenge-modals

View File

@ -1,7 +1,7 @@
extends ../layout-wide extends ../layout-wide
block content block content
.row .row
.col-xs-12.col-sm-12.col-md-4.bonfire-top .col-md-4.bonfire-top
h1.text-center= name h1.text-center= name
.well .well
h4 h4
@ -12,28 +12,27 @@ block content
input(type='checkbox' class='challenge-list-checkbox') input(type='checkbox' class='challenge-list-checkbox')
.col-xs-9.col-sm-11.col-md-10 .col-xs-9.col-sm-11.col-md-10
li.step-text.wrappable!= step li.step-text.wrappable!= step
.col-xs-12.col-sm-12.col-md-8 .col-md-8
.embed-responsive.embed-responsive-16by9 .embed-responsive.embed-responsive-16by9
iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}') iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
br br
if (user) if (user)
a.btn.btn-primary.btn-big.btn-block#completed-zipline-or-basejump I've completed this challenge (ctrl + enter) a.btn.btn-primary.btn-big.btn-block#completed-zipline-or-basejump I've completed this challenge (ctrl + enter)
script.
var userLoggedIn = true;
else
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge (ctrl + enter)
.button-spacer .button-spacer
.btn-group.input-group.btn-group-justified .btn-group.input-group.btn-group-justified
.btn.btn-success.btn-big#trigger-help-modal .btn.btn-success.btn-big#trigger-help-modal
i.fa.fa-medkit i.fa.fa-medkit
| &nbsp; Help | &nbsp; Help
.btn.btn-success.btn-big#trigger-pair-modal
i.fa.fa-user-plus
| &nbsp; Pair
.btn.btn-success.btn-big#trigger-issue-modal .btn.btn-success.btn-big#trigger-issue-modal
i.fa.fa-bug i.fa.fa-bug
| &nbsp; Bug | &nbsp; Bug
if (!user)
.button-spacer .button-spacer
script. a.btn.btn-big.signup-btn.btn-block(href='/login') Sign in so you can save your progress
var userLoggedIn = true;
else
a.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
script. script.
var userLoggedIn = false; var userLoggedIn = false;
br br
@ -41,6 +40,7 @@ block content
var challenge_Id = !{JSON.stringify(challengeId)}; var challenge_Id = !{JSON.stringify(challengeId)};
var challenge_Name = !{JSON.stringify(name)}; var challenge_Name = !{JSON.stringify(name)};
var started = Math.floor(Date.now()); var started = Math.floor(Date.now());
var dashedName = !{JSON.stringify(dashedName)};
var challengeType = !{JSON.stringify(challengeType)}; var challengeType = !{JSON.stringify(challengeType)};
var controlEnterHandler = function (e) { var controlEnterHandler = function (e) {
$('body').unbind('keypress'); $('body').unbind('keypress');
@ -60,21 +60,21 @@ block content
}; };
#complete-zipline-or-basejump-dialog.modal(tabindex='-1') #complete-zipline-or-basejump-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header= compliment .modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body(ng-controller="pairedWithController") .modal-body(ng-controller="pairedWithController")
.text-center .text-center
.animated.zoomInDown.delay-half .animated.zoomInDown
span.completion-icon.ion-checkmark-circled.text-primary span.completion-icon.ion-checkmark-circled.text-primary
if (user) if (user)
form.form-horizontal(novalidate='novalidate', name='completedWithForm') form.form-horizontal(novalidate='novalidate', name='completedWithForm')
.form-group.text-center .form-group.text-center
.col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2.animated.fadeIn .col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2
// extra field to distract password tools like lastpass from injecting css into our username field // extra field to distract password tools like lastpass from injecting css into our username field
input.form-control(ng-show="false") input.form-control(ng-show="false")
if (challengeType === 3) if (challengeType === "3")
input.form-control#public-url(type='url', name="solutionUrl", placeholder="http://codepen.io/your-pen-here", autofocus, required, ng-minlength="10", ng-model="deploymentUrl") input.form-control#public-url(type='url', name="solutionUrl", placeholder="http://codepen.io/your-pen-here", autofocus, required, ng-minlength="10", ng-model="deploymentUrl")
else else
input.form-control#public-url(type='url', name="solutionUrl", placeholder="http://yourapp.com", autofocus, required, ng-minlength="10", ng-model="deploymentUrl") input.form-control#public-url(type='url', name="solutionUrl", placeholder="http://yourapp.com", autofocus, required, ng-minlength="10", ng-model="deploymentUrl")
@ -87,11 +87,12 @@ block content
| Username not found | Username not found
if (user) if (user)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid') Go to my next challenge (ctrl + enter) a.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid') Go to my next challenge
.button-spacer
script. script.
$('#complete-zipline-or-basejump-dialog').on('keypress', modalControlEnterHandler); $('#complete-zipline-or-basejump-dialog').on('keypress', modalControlEnterHandler);
else else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
script. script.
$('body').on('keypress', controlEnterHandler); $('body').on('keypress', controlEnterHandler);
include ../partials/challenge-modals include ../partials/challenge-modals

View File

@ -3,12 +3,12 @@ block content
.jumbotron .jumbotron
.text-center .text-center
h1.hug-top Code with Us h1.hug-top Code with Us
h2 Let's learn to code by building projects for nonprofits h2 Let's learn to code and build projects for nonprofits
.row .row
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Get Connected h3.nowrap Get Connected
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career') img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career')
p.landing-p Join a community of busy, motivated professionals. p.landing-p Join a community of busy, motivated people.
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Learn JavaScript h3.nowrap Learn JavaScript
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript') img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript')
@ -77,18 +77,16 @@ block content
br br
br br
.big-break .big-break
h2 Why you should join our community right now: h2 Why you should join our open source community right now:
h3.col-xs-offset-0.col-sm-offset-1 h3.col-xs-offset-0.col-sm-offset-1
ul.text-left ul.text-left
li.ion-code &thinsp; We're thousands of professionals. We all learn to code together. li.ion-code &thinsp; You'll get help in real time from our community chat rooms.
li.ion-code &thinsp; We're building projects for dozens of nonprofits. li.ion-code &thinsp; You'll meet up with other coders in your city.
li.ion-code &thinsp; Our community is 100% free and open source.
li.ion-code &thinsp; You'll learn Full Stack JavaScript and become a Software Engineer.
li.ion-code &thinsp; You'll work through our focused, interactive courses and tutorials.
li.ion-code &thinsp; You'll learn to code at your own pace, in your browser or on your phone. li.ion-code &thinsp; You'll learn to code at your own pace, in your browser or on your phone.
li.ion-code &thinsp; You'll become qualified for thousands of jobs currently going unfilled. li.ion-code &thinsp; You'll work through our focused, interactive courses and tutorials.
li.ion-code &thinsp; You can get help in real time from our community chat rooms. li.ion-code &thinsp; You'll learn state-of-the-art full stack JavaScript technologies.
li.ion-code &thinsp; We all share one common goal: to boost our careers with code. li.ion-code &thinsp; You'll build projects that help nonprofits carry out their missions more effectively.
li.ion-code &thinsp; You'll assemble a portfolio of real apps used by real people.
.big-break .big-break
.row .row
.col-xs-12.col-sm-8.col-sm-offset-2 .col-xs-12.col-sm-8.col-sm-offset-2

View File

@ -1,10 +1,11 @@
doctype html doctype html
html(ng-app='profileValidation', lang='en') html(ng-app='profileValidation', lang='en')
head head
include partials/universal-head include partials/meta
include partials/stylesheets
body.no-top-and-bottom-margins.full-screen-body-background body.no-top-and-bottom-margins.full-screen-body-background
include partials/scripts
include partials/navbar include partials/navbar
include partials/flash include partials/flash
block content block content
include partials/footer include partials/footer
include partials/universal-tail

View File

@ -1,11 +1,12 @@
doctype html doctype html
html(ng-app='profileValidation', lang='en') html(ng-app='profileValidation', lang='en')
head head
include partials/meta
include partials/stylesheets
body.top-and-bottom-margins body.top-and-bottom-margins
include partials/universal-head include partials/scripts
include partials/navbar include partials/navbar
.container .container
include partials/flash include partials/flash
block content block content
include partials/footer include partials/footer
include partials/universal-tail

View File

@ -1,30 +1,17 @@
#pair-modal.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation
.modal-content
.modal-header.challenge-list-header Ready to pair program?
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body.text-center
h3 This will take you to our pair programming room where you can request a pair.
h3 You'll need &thinsp;
a(href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-install-Screenhero' target='_blank') Screenhero
| .
h3 Other campers may then message you about pair programming.
a.btn.btn-lg.btn-primary.btn-block.close-modal(href='https://gitter.im/FreeCodeCamp/LetsPair', target='_blank') Take me to the pair programming room
a.btn.btn-lg.btn-info.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
#issue-modal.modal(tabindex='-1') #issue-modal.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header Did you find a bug? .modal-header.challenge-list-header Did you find a bug?
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body.text-center .modal-body.text-center
h3 This will open our GitHub Issues page. h3 Before you submit a new issue, read "Help I've Found a Bug" and browse other issues with this challenge.
h3 Please tell us how to reproduce the bug and link us to screenshots if possible. a.btn.btn-lg.btn-success.btn-block#help-ive-found-a-bug-wiki-article(name='_csrf', value=_csrf) Read "Help I've Found a Bug"
a.btn.btn-lg.btn-success.btn-block#search-issue(name='_csrf', value=_csrf) Browse other issues with this challenge
a.btn.btn-lg.btn-primary.btn-block#report-issue(name='_csrf', value=_csrf) Create my GitHub issue a.btn.btn-lg.btn-primary.btn-block#report-issue(name='_csrf', value=_csrf) Create my GitHub issue
a.btn.btn-lg.btn-info.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel a.btn.btn-lg.btn-info.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
#help-modal.modal(tabindex='-1') #help-modal.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation .modal-dialog.animated.fadeIn.fast-animation
.modal-content .modal-content
.modal-header.challenge-list-header Need some help? .modal-header.challenge-list-header Need some help?
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
@ -46,3 +33,7 @@
h3 This will restore your code editor to its original state. h3 This will restore your code editor to its original state.
a.btn.btn-lg.btn-info.btn-block#reset-button(href='#', data-dismiss='modal', aria-hidden='true') Clear my code a.btn.btn-lg.btn-info.btn-block#reset-button(href='#', data-dismiss='modal', aria-hidden='true') Clear my code
a.btn.btn-lg.btn-primary.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel a.btn.btn-lg.btn-primary.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
script.
if (typeof localStorage !== 'undefined') {
localStorage.setItem('currentDashedName', typeof common !== 'undefined' && common.dashedName || dashedName || '');
}

View File

@ -1,29 +1,34 @@
meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='csrf-token', content=_csrf)
title #{title} | Free Code Camp
link(rel='canonical', href='http://freecodecamp.com') link(rel='canonical', href='http://freecodecamp.com')
meta(charset='utf-8') meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge') meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(name='viewport', content='width=device-width, initial-scale=1.0') meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='csrf-token', content=_csrf) meta(name='csrf-token', content=_csrf)
meta(name='keywords', content='learn to code, learn how to code, code, coding, software engineer, software developer, mean stack, pair programming, node.js, angular.js, express.js, mongoDB, coding bootcamp') meta(name='keywords', content='learn to code, learn to program, learn programming, learn javascript, learn coding, code, coding, programming, software engineer, software developer, mean stack, web development, development, engineering, learn node.js, learn angular.js, learn express.js, learn mongoDB, coding bootcamp, javascript, open source')
meta(property="og:title", content="Learn to code") meta(property="og:title", content="Learn to code and build projects for nonprofits")
meta(property="og:site_name", content="Free Code Camp") meta(property="og:site_name", content="Free Code Camp")
meta(name='twitter:widgets:csp', content='on') meta(name='twitter:widgets:csp', content='on')
meta(name='p:domain_verify', content='d0bc047a482c03c24f1168004c2a216a') meta(name='p:domain_verify', content='d0bc047a482c03c24f1168004c2a216a')
meta(property="og:url", content="http://www.freecodecamp.com") meta(property="og:url", content="http://www.freecodecamp.com")
meta(property="og:description", content="Learn to code by helping nonprofits. Build your full stack web development portfolio today.") meta(property="og:description", content="Learn to code and build projects for nonprofits. Build your full stack web development portfolio today.")
meta(property="og:image", content="https://s3.amazonaws.com/freecodecamp/curriculum-diagram-full.jpg") meta(property="og:image", content="https://s3.amazonaws.com/freecodecamp/curriculum-diagram-full.jpg")
meta(property="og:type", content="article") meta(property="og:type", content="article")
meta(property="article:publisher", content="https://www.facebook.com/freecodecamp") meta(property="article:publisher", content="https://www.facebook.com/freecodecamp")
meta(property="article:section", content="Responsive") meta(property="article:section", content="Responsive")
link(rel="publisher", href="https://plus.google.com/+Freecodecamp") link(rel="publisher", href="https://plus.google.com/+Freecodecamp")
link(rel="author", href="https://plus.google.com/+Freecodecamp") link(rel="author", href="https://plus.google.com/+Freecodecamp")
meta(name="description", content="Learn to code by helping nonprofits. Build your full stack web development portfolio today.") meta(name="description", content="Learn to code and build projects for nonprofits. Build your full stack web development portfolio today.")
meta(name="twitter:creator", content="@freecodecamp") meta(name="twitter:creator", content="@freecodecamp")
meta(name="twitter:url", content="http://www.freecodecamp.com") meta(name="twitter:url", content="http://www.freecodecamp.com")
meta(name="twitter:site", content="@freecodecamp") meta(name="twitter:site", content="@freecodecamp")
meta(name="twitter:card", content="summary_large_image") meta(name="twitter:card", content="summary_large_image")
meta(name="twitter:image:src", content="https://s3.amazonaws.com/freecodecamp/curriculum-diagram-full.jpg") meta(name="twitter:image:src", content="https://s3.amazonaws.com/freecodecamp/curriculum-diagram-full.jpg")
meta(name="twitter:title", content="Learn to code by helping nonprofits") meta(name="twitter:title", content="Learn to code and build projects for nonprofits")
meta(name="twitter:description", content="We're a community where you learn to code by helping nonprofits. Build your full stack JavaScript Portfolio today.") meta(name="twitter:description", content="We're an open source community of busy people who learn to code and build projects for nonprofits. Build your full stack web development portfolio today.")
meta(content="a40ee5d5dba3bb091ad783ebd2b1383f", name="p:domain_verify") meta(content="a40ee5d5dba3bb091ad783ebd2b1383f", name="p:domain_verify")
meta(name="msapplication-TileColor", content="#FFFFFF") meta(name="msapplication-TileColor", content="#FFFFFF")
meta(name="msapplication-TileImage", content="/") meta(name="msapplication-TileImage", content="/")

View File

@ -7,6 +7,8 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo') img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
.collapse.navbar-collapse .collapse.navbar-collapse
ul.nav.navbar-nav.navbar-right.hamburger-dropdown ul.nav.navbar-nav.navbar-right.hamburger-dropdown
li
a.learn-btn(href='#') Learn
li li
a(href='/map') Map a(href='/map') Map
li li
@ -20,15 +22,8 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
li li
a.btn.signup-btn.signup-btn-nav(href='/login') Sign in a.btn.signup-btn.signup-btn-nav(href='/login') Sign in
else else
if user.isGithubCool
li li
a(href='/' + user.username) [&thinsp;#{user.progressTimestamps.length}&thinsp;] a(href='/' + user.username) [&thinsp;#{user.progressTimestamps.length}&thinsp;]
.hidden-xs.hidden-sm .hidden-xs.hidden-sm
a(href='/' + user.username) a(href='/' + user.username)
img.profile-picture.float-right(src='#{user.picture}') img.profile-picture.float-right(src='#{user.picture}')
else
li
a(href='/account') [&thinsp;#{user.progressTimestamps.length}&thinsp;]
.hidden-xs.hidden-sm
a(href='/account')
img.profile-picture.float-right(src='#{user.picture}')

View File

@ -1,22 +1,7 @@
link(rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Lato:400|Inconsolata") script(src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js")
link(rel="stylesheet" type="text/css" href="/bower_components/cal-heatmap/cal-heatmap.css")
link(rel='stylesheet', href='/bower_components/font-awesome/css/font-awesome.min.css')
link(rel='stylesheet', href=rev('/css', 'main.css'))
// End **REQUIRED** includes
include meta
title #{title} | Free Code Camp
meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='csrf-token', content=_csrf)
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
script. script.
window.jQuery || document.write('<script src="/bower_components/jquery/dist/jquery.min.js"><\/script>'); window.jQuery || document.write('<script src="/bower_components/jquery/dist/jquery.min.js"><\/script>');
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js") script(src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.js")
script. script.
if (typeof window.angular === 'undefined') { if (typeof window.angular === 'undefined') {
document.write('<script src="/bower_components/angular/angular.min.js"><\/script>'); document.write('<script src="/bower_components/angular/angular.min.js"><\/script>');
@ -43,6 +28,7 @@ script.
script(src=rev('/js', 'main.js')) script(src=rev('/js', 'main.js'))
script(src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js") script(src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js")
script(src="/bower_components/ramda/dist/ramda.min.js") script(src="/bower_components/ramda/dist/ramda.min.js")
script(src='/bower_components/lightbox2/dist/js/lightbox.min.js')
script. script.
(function(i,s,o,g,r,a,m){ i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){ i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
@ -51,19 +37,3 @@ script.
ga('create', 'UA-55446531-1', 'auto'); ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures'); ga('require', 'displayfeatures');
ga('send', 'pageview'); ga('send', 'pageview');
script#inspectletjs(type='text/javascript').
window.__insp = window.__insp || [];
__insp.push(['wid', 561999918]);
(function() {
function __ldinsp() {
var insp = document.createElement('script');
insp.type = 'text/javascript';
insp.async = true;
insp.id = "inspsync";
insp.src = '//cdn.inspectlet.com/inspectlet.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(insp, x);
}
if (window.attachEvent) window.attachEvent('onload', __ldinsp);
else window.addEventListener('load', __ldinsp, false);
})();

View File

@ -1,6 +1,5 @@
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js") script(src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js")
script(src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js") script(src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js")
link(rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Lato:400|Inconsolata")
link(rel='stylesheet', href='/bower_components/font-awesome/css/font-awesome.min.css') link(rel='stylesheet', href='/bower_components/font-awesome/css/font-awesome.min.css')
link(rel='stylesheet', href=rev('/css', 'main.css')) link(rel='stylesheet', href=rev('/css', 'main.css'))
link(rel='stylesheet', href='/css/Vimeo.css') link(rel='stylesheet', href='/css/Vimeo.css')

View File

@ -0,0 +1,5 @@
link(rel='stylesheet', type='text/css' href='/css/lato.css')
link(rel="stylesheet" type="text/css" href="/bower_components/cal-heatmap/cal-heatmap.css")
link(rel='stylesheet', href='/bower_components/font-awesome/css/font-awesome.min.css')
link(rel='stylesheet', href='/bower_components/lightbox2/dist/css/lightbox.css')
link(rel='stylesheet', href=rev('/css', 'main.css'))

View File

@ -1,189 +0,0 @@
extends ../layout
block content
.jumbotron
h2.text-center Scroll down and follow along with this 8-minute guide.
br
| It will help you get the most out of Free Code Camp.
.thumbnail
img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt="a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits")
.caption
p.large-p Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/pYsTbjI.jpg' alt='a screenshot of our curriculum alongside a screenshot of our chat room.')
.caption
p.large-p Learning to code is hard. To succeed, you'll need lots of practice and support. That's why we've created a rigorous curriculum and supportive community.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='A graph of the rate of job growth against growth in computer science degree graduates. There are 1.4 million jobs and only 400 million people to fill them.')
.caption
p.large-p If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/dLx8nrg.jpg' alt='An illustration showing that you will learn HTML5, CSS3, JavaScript, Databases, Git, Node.js, Angular.js and Agile.')
.caption
p.large-p During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/yXyxbDd.jpg' alt='a screen shot of our nonprofit project directory.')
.caption
p.large-p During the last 800 hours, you'll build several real-life projects for nonprofits. By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a screenshot of our one of our Gitter chat rooms.')
.caption
p.large-p Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with. First you'll need a GitHub account.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/FEImaEN.gif' alt='A gif showing you to click the link below to go to GitHub. Fill in the necessary fields and click submit.')
.caption
p.large-p Try this:&thinsp;
a(href='https://github.com/join' target='_blank') Create an account with GitHub
| . Be sure to use your real email address - GitHub will keep this private.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/ALN6zPK.gif' alt='A gif showing you how to click the profile image in the upper right hand corner of GitHub. Upload a photo of yourself or you will continue to use the automatically generated pixel art. Then fill in the remaining form fields and click submit.')
.caption
p.large-p Try this:&thinsp;
| Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how your fellow campers will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/OXL3G3n.gif' alt="Click the link below to navigate to Free Code Camp's open-source repository. In the upper right hand corner, you can click the \"star\" button to star this repository.")
.caption
p.large-p Try this:&thinsp;
a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
| &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EZHzKCV.gif' alt='A gif showing you how to click the link below to go to our chat room and click the \"sign in with GitHub\" button. Then you can click into the text input field and type a message to your fellow campers.')
.caption
p.large-p Try this:&thinsp;
| Now that you have a GitHub account, you can&thinsp;
a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by logging in with GitHub
| . Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Ecs5XAd.gif' alt='A gif showing you how you can click the settings button in the upper right hand corner and modify your notification settings.')
.caption
p.large-p Try this:&thinsp;
| Our chat rooms are extremely active. You should change your settings so you're only notified if someone mentions you.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/T0bGJPe.gif' alt='A gif showing how you can click on a user profile image to initiate a private message with that user.')
.caption
p.large-p Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/vDTMJSh.gif' alt='A gif showing that you can tab back and forth between challenges and our chat rooms.')
.caption
p.large-p Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/SLQ27Gr.gif' alt='A gif showing how you can click the link below to download a native chat room app for your computer.')
.caption
p.large-p You can also&thinsp;
a(href='https://gitter.im/apps' target='_blank') download the chat room app
| &thinsp;to your computer or phone.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/DoOqkNW.gif' alt='A gif showing how you can click the "Wiki" button in your upper-right corner to access the wiki.')
.caption
p.large-p Try this: Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/FkEzbto.gif' alt='A gif showing how you can click your profile image in your upper right hand corner to access the account page and connect GitHub.')
.caption
p.large-p Try this: Check out your portfolio page. Click your picture your upper right hand corner. To activate your portfolio page, you'll need to link your GitHub account with Free Code Camp.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/WKzEr1q.gif' alt='A gif showing how you can access your profile page and hover over different days to see how many brownie points you got on those days.')
.caption
p.large-p Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/nmSiMy1.gif' alt='A gif showing how you can access our Camper News page and click the "upvote" button to upvote a story.')
.caption
p.large-p Try this:&thinsp;
| Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Elb3dfj.jpg' alt='A picture of some of our campers meeting in a local cafe. 3 men and 3 women are sitting around a table with laptops out, and are smiling and coding.')
.caption
p.large-p Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EZHzKCV.gif' alt="A gif showing how you can click the link below, find your city on the list of Campsites, then click on the Facebook link for your city and join your city's Facebook group.")
.caption
p.large-p Try this:&thinsp;
a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
| . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
| .
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/3AgvJQg.gif' alt="A gif showing how click the link below, find your city, and click the \"Gitter\" button to join your city's Gitter chat room")
.caption
p.large-p Try this:&thinsp;
a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
| and click "Gitter" to join your city's chat room.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/P7qfJXt.gif' alt='A gif showing how you can click the link below and fill in the necessary fields to add your Free Code Camp studies to your LinkedIn profile.')
.caption
p.large-p You can&thinsp;
a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
| . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EWWZBag.jpg' alt='An image with the text \"1. Read the error 2. Search Google 3. Ask for help.')
.caption
p.large-p Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: Read-Search-Ask.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/99BfAcK.jpg' alt='An image showing jQuery documentation')
.caption
p.large-p First, read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/GxvrsFb.gif' alt="A gif showing you how to do an advanced Google search. First, we enter the query \"jquery doesn't run when my page loads\". Then we click search tools button and change the \"Any time\" select box to \"within the last year\". Then we click on a result and read through the article and find our answer.")
.caption
p.large-p If that didn't help, 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.
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/LZYU7p2.gif' alt="A gif showing us following the link below to go to the help chat room and ask \"jquery doesn't run when my page loads\".")
.caption
p.large-p If that didn't help, ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
| .
.big-spacer
.thumbnail
img.gif-block.img-center.img-responsive(src='http://i.imgur.com/WsfzvVo.gif' alt='A gif showing us clicking the \"map\" button in our upper right hand corner and browsing our challenge map.')
.caption
p.large-p Now you're ready to start coding! Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.

View File

@ -1,3 +0,0 @@
extends ../layout
block content
iframe(src="https://docs.google.com/forms/d/1b8JYvQ5ibdwwC0owQ9e9EMRlg22O2wbJgqMvPjiILqs/viewform?embedded=true", frameborder="0", marginheight="0", marginwidth="0", width='102%', height=2100, scrolling="no") Loading...

View File

@ -48,7 +48,7 @@
(typeof username !== 'undefined' ? (typeof username !== 'undefined' ?
"<button id='" + data[i].id + "' class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost btn-upvote'>upvote</button>" : "<button id='" + data[i].id + "' class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost btn-upvote'>upvote</button>" :
"<a href='/signup' class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost btn-upvote'>upvote</a>") + "<a href='/signup' class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost btn-upvote'>upvote</a>") +
"<a class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost' href='/news/" + linkedName + "'>more info...</a>" + "<a class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost' href='/news/" + linkedName + "'>more info</a>" +
"</div>" + "</div>" +
"</div>" + "</div>" +
"<div class='hidden-xs row media-stories'>" + "<div class='hidden-xs row media-stories'>" +
@ -69,7 +69,7 @@
(typeof username !== 'undefined' ? (typeof username !== 'undefined' ?
"<button id='" + data[i].id + "' class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost btn-upvote'>upvote</button>" : "<button id='" + data[i].id + "' class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost btn-upvote'>upvote</button>" :
"<a href='/signin' class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost'>upvote</a>") + "<a href='/signin' class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost'>upvote</a>") +
" · <a class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost' href='/news/" + linkedName + "'>more info...</a> · " + " · <a class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost' href='/news/" + linkedName + "'>more info</a> · " +
rank + (rank > 1 ? " points" : " point") + " · posted " + rank + (rank > 1 ? " points" : " point") + " · posted " +
moment(data[i].timePosted).fromNow() + moment(data[i].timePosted).fromNow() +
" by <a href='/" + data[i].author.username + "'>@" + data[i].author.username + "</a> " + " by <a href='/" + data[i].author.username + "'>@" + data[i].author.username + "</a> " +

View File

@ -1,4 +1,10 @@
.row .row
.col-xs-12.col-sm-9
.input-group
input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='Search our links')
span.input-group-btn
button#searchbutton.btn.btn-big.btn-primary.btn-responsive(type='button') Search
.spacer
.col-xs-12.col-sm-3 .col-xs-12.col-sm-3
span span
a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit
@ -6,21 +12,6 @@
a.btn.btn-success.btn-big.btn-block.btn-responsive(href='/news/' class="#{ (page !== 'hot') ? '' : 'hidden' }") All a.btn.btn-success.btn-big.btn-block.btn-responsive(href='/news/' class="#{ (page !== 'hot') ? '' : 'hidden' }") All
.visible-xs .visible-xs
.button-spacer .button-spacer
.col-xs-12.col-sm-9
.input-group
input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='Search our links')
span.input-group-btn
button#searchbutton.btn.btn-big.btn-primary.btn-responsive(type='button') Search
.spacer
//.spacer
//.row
// .col-xs-12.col-sm-8.col-sm-offset-2.well
// h4.text-center Which other free resources do you use?
// img.img-responsive(src='https://www.evernote.com/l/AHRNhlwViM1Kh5qCm6iy7MSWrbdyxYbRkWkB/image.png')
// p Link us to your favorite free coding resources.
// p Use the headline: "Awesome Free Resource: (the name of the book, podcast, or video series)". We'll publish a list of the 25 most-upvoted resources (and the campers who submitted them) in Wednesday's blog post, and in an upcoming Field Guide article. Also - as always - you'll get 1 point every time someone upvotes your post.
//.spacer
#search-results #search-results
@ -53,11 +44,14 @@ script.
.fail(function (xhr, textStatus, errorThrown) { .fail(function (xhr, textStatus, errorThrown) {
$('#search-results').empty(); $('#search-results').empty();
var div = document.createElement("div"); var div = document.createElement("div");
$(div).html("<h3 class='negative-35 text-center text-warning dotted-underline'><em>No Results Found</em></h3>"); $(div).html("<h3 class='text-center text-warning dotted-underline'><em>No Results Found</em></h3>");
$(div).appendTo($('#search-results')); $(div).appendTo($('#search-results'));
}) })
.done(function (data, textStatus, xhr) { .done(function (data, textStatus, xhr) {
$('#search-results').empty(); $('#search-results').empty();
var spacer = document.createElement('div');
$(spacer).html("<div class='spacer'></div>");
$(spacer).appendTo($('#search-results'));
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var div = document.createElement('div'); var div = document.createElement('div');
var linkedName = getLinkedName(data[i].storyLink); var linkedName = getLinkedName(data[i].storyLink);
@ -84,7 +78,7 @@ script.
"</div>" + "</div>" +
"<div class='col-xs-12'>" + "<div class='col-xs-12'>" +
"<br>" + "<br>" +
"<a class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost' href='/news/" + linkedName + "'>more info...</a>" + "<a class='btn btn-no-shadow btn-primary btn-block btn-primary-ghost' href='/news/" + linkedName + "'>more info</a>" +
"</div>" + "</div>" +
"</div>" + "</div>" +
"</div>" + "</div>" +
@ -103,7 +97,7 @@ script.
"</a>" + "</a>" +
"</div>" + "</div>" +
"<div class='story-byline col-xs-12 wrappable'>" + "<div class='story-byline col-xs-12 wrappable'>" +
"<a class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost' href='/news/" + linkedName + "'>more info...</a> · " + "<a class='btn btn-no-shadow btn-primary btn-xs btn-primary-ghost' href='/news/" + linkedName + "'>more info</a> · " +
rank + (rank > 1 ? " points" : " point") + " · posted " + rank + (rank > 1 ? " points" : " point") + " · posted " +
moment(data[i].timePosted).fromNow() + moment(data[i].timePosted).fromNow() +
" by <a href='/" + data[i].author.username + "'>@" + data[i].author.username + " by <a href='/" + data[i].author.username + "'>@" + data[i].author.username +
@ -117,7 +111,7 @@ script.
$(div).appendTo($('#search-results')); $(div).appendTo($('#search-results'));
} }
var hr = document.createElement("div"); var hr = document.createElement("div");
$(hr).html("<h3 class='negative-35 text-center text-success dotted-underline'><em>End search results</em></h3>") $(hr).html("<h3 class='text-center text-success dotted-underline'><em>End search results</em></h3>")
$(hr).appendTo($('#search-results')); $(hr).appendTo($('#search-results'));
}); });
} }

View File

@ -1,7 +1,6 @@
script. script.
var storyId = !{JSON.stringify(id)}; var storyId = !{JSON.stringify(id)};
var originalStoryLink = !{JSON.stringify(originalStoryLink)}; var originalStoryLink = !{JSON.stringify(originalStoryLink)};
var originalStoryAuthorEmail = !{JSON.stringify(originalStoryAuthorEmail)};
var upVotes = !{JSON.stringify(upVotes)}; var upVotes = !{JSON.stringify(upVotes)};
var image = !{JSON.stringify(image)}; var image = !{JSON.stringify(image)};
var hasUserVoted = !{JSON.stringify(hasUserVoted)}; var hasUserVoted = !{JSON.stringify(hasUserVoted)};