diff --git a/.travis.yml b/.travis.yml index 5c2157f825..7839c292d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,15 @@ language: node_js node_js: - '4.2.1' - + env: - CXX=g++-4.8 - + addons: apt: sources: - ubuntu-toolchain-r-test packages: - - g++-4.8 - + - g++-4.8 + sudo: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 417ecc9e9b..c5aa78b5df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,15 +107,15 @@ Free Code Camp Issue Mods and staff are on hand to assist with Pull Request rela There are two methods of creating a Pull for Free Code Camp: - Editing files via the GitHub Interface -- Editing files on a local clone +- Editing files on a local clone -**Important: ALWAYS EDIT ON A BRANCH** +**Important: ALWAYS EDIT ON A BRANCH** Take away only one thing from this document, it should be this: Never, **EVER** make edits to the `staging` branch. ALWAYS make a new branch BEFORE you edit files. This is critical, because if your PR is not accepted, your copy of staging will be forever sullied and the only way to fix it is to delete your fork and re-fork. -_**Method 1: Editing via your Local Fork (Recommended)**_ +_**Method 1: Editing via your Local Fork (Recommended)**_ This is the recommended method. Read about How to Setup and Maintain a Local Instance of Free Code Camp. -1. Perform the maintenance step of rebasing `staging`. +1. Perform the maintenance step of rebasing `staging`. 2. Ensure you are on the `staging` branch using `git status`: ```bash @@ -127,7 +127,7 @@ nothing to commit, working directory clean ``` 3. If you are not on staging or your working directory is not clean, resolve any outstanding files/commits and checkout staging `git checkout staging` -4. Create a branch off of `staging` with git: `git checkout -B branch/name-here` +4. Create a branch off of `staging` with git: `git checkout -B branch/name-here` **Note:** Branch naming is important. Use a name like `fix/short-fix-description` or `feature/short-feature-description`. Review the [Contribution Guidelines](#contribution-guidelines) for more detail. 5. Edit your file(s) locally with the editor of your choice 6. Check your `git status` to see unstaged files. @@ -137,21 +137,21 @@ nothing to commit, working directory clean 10. Push your commits to your GitHub Fork: `git push -u origin branch/name-here` 11. Go to [Common Steps](#common-steps) -_**Method 2: Editing via the GitHub Interface**_ +_**Method 2: Editing via the GitHub Interface**_ -Note: Editing via the GitHub Interface is not recommended, since it is not possible to update your fork via GitHub's interface without deleting and recreating your fork. +Note: Editing via the GitHub Interface is not recommended, since it is not possible to update your fork via GitHub's interface without deleting and recreating your fork. Read the [Wiki article](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-To-Create-A-Pull-Request-for-Free-Code-Camp#editing-via-the-github-interface) for further information ## Common Steps -1. Once the edits have been committed, you will be prompted to create a pull request on your fork's Github Page. +1. Once the edits have been committed, you will be prompted to create a pull request on your fork's GitHub Page. 2. By default, all pull requests should be against the FCC main repo, `staging` branch. 3. Submit a [pull request](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Pull-Request-Contribute) from your branch to Free Code Camp's `staging` branch. -3. The title (also called the subject) of your PR should be descriptive of your changes and succinctly indicates what is being fixed. +3. The title (also called the subject) of your PR should be descriptive of your changes and succinctly indicates what is being fixed. - **Do not add the issue number in the PR title**. - Examples: `Add Test Cases to Bonfire Drop It` `Correct typo in Waypoint Size Your Images` 4. In the body of your PR include a more detailed summary of the changes you made and why. - - If the PR is meant to fix an existing bug/issue, then, at the end of your PR's commit message, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. + - If the PR is meant to fix an existing bug/issue, then, at the end of your PR's commit message, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. This tells GitHub to close the existing issue, if the PR is merged. 5. Indicate if you have tested on a local copy of the site or not. @@ -159,7 +159,7 @@ Read the [Wiki article](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-To **If your PR is accepted** -Once your PR is accepted, you may delete the branch you created to submit it. This keeps your working fork clean. +Once your PR is accepted, you may delete the branch you created to submit it. This keeps your working fork clean. You can do this with a press of a button on the GitHub PR interface. You can delete the local copy of the branch with: `git branch -D branch/to-delete-name` @@ -174,8 +174,8 @@ If you have a local copy of the repo, you can make the requested changes and ame Be sure to post in the PR conversation that you have made the requested changes. ##Other resources -- [Searching for Your Issue on Github](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Searching-for-Your-Issue-on-Github) -- [Creating a New Github Issue](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Creating-a-New-Github-Issue) +- [Searching for Your Issue on GitHub](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Searching-for-Your-Issue-on-GitHub) +- [Creating a New GitHub Issue](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Creating-a-New-GitHub-Issue) - [Select Issues for Contributing Using Labels](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Select-Issues-for-Contributing-Using-Labels) - [How to clone the FreeCodeCamp website on a Windows pc](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-to-clone-the-FreeCodeCamp-website-on-a-Windows-pc) - [How to log in to your local FCC site - using GitHub](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-To-Log-In-To-Your-Local-FCC-Site) diff --git a/client/less/challenge.less b/client/less/challenge.less index f50db78725..3ed3808178 100644 --- a/client/less/challenge.less +++ b/client/less/challenge.less @@ -97,7 +97,7 @@ iframe.iphone { height: 500px; } @media (min-width: 1200px) and (max-width: 1250px){ - right: 22px; + right: 22px; } } @@ -108,6 +108,6 @@ iframe.iphone { z-index: -1; right: -195px; @media (min-width: 1200px) and (max-width: 1250px){ - right: -207px; + right: -207px; } } diff --git a/client/less/lib/bootstrap-social/bootstrap-social.less b/client/less/lib/bootstrap-social/bootstrap-social.less index a2b61fae6c..a333b57a08 100755 --- a/client/less/lib/bootstrap-social/bootstrap-social.less +++ b/client/less/lib/bootstrap-social/bootstrap-social.less @@ -32,7 +32,7 @@ } &.btn-lg { padding-left: (@bs-height-lg + @padding-large-horizontal); - :first-child { + > :first-child { line-height: @bs-height-lg; width: @bs-height-lg; font-size: 1.8em; @@ -40,7 +40,7 @@ } &.btn-sm { padding-left: (@bs-height-sm + @padding-small-horizontal); - :first-child { + > :first-child { line-height: @bs-height-sm; width: @bs-height-sm; font-size: 1.4em; @@ -48,7 +48,7 @@ } &.btn-xs { padding-left: (@bs-height-xs + @padding-small-horizontal); - :first-child { + > :first-child { line-height: @bs-height-xs; width: @bs-height-xs; font-size: 1.2em; @@ -61,7 +61,7 @@ height: (@bs-height-base + 2); width: (@bs-height-base + 2); padding: 0; - :first-child { + > :first-child { border: none; text-align: center; width: 100%!important; @@ -86,29 +86,14 @@ } } -.btn-social(@color-bg, @color: @color-bg) { +.btn-social(@color-bg, @color: #fff) { background-color: @color-bg; .button-variant(@color, @color-bg, rgba(0,0,0,.2)); } -.btn-adn { .btn-social(#d87a68); } -.btn-bitbucket { .btn-social(#205081); } -.btn-dropbox { .btn-social(#1087dd); } .btn-facebook { .btn-social(#3b5998); } -.btn-flickr { .btn-social(#ff0084); } -.btn-foursquare { .btn-social(#f94877); } .btn-github { .btn-social(#444444); } -.btn-google-plus { .btn-social(#dd4b39); } -.btn-instagram { .btn-social(#3f729b); } +.btn-google { .btn-social(#dd4b39); } .btn-linkedin { .btn-social(#007bb6); } -.btn-microsoft { .btn-social(#2672ec); } -.btn-openid { .btn-social(#f7931e); } -.btn-pinterest { .btn-social(#cb2027); } -.btn-reddit { .btn-social(#eff7ff, #000); } -.btn-soundcloud { .btn-social(#ff5500); } -.btn-tumblr { .btn-social(#2c4762); } .btn-twitter { .btn-social(#55acee); } -.btn-vimeo { .btn-social(#1ab7ea); } -.btn-vk { .btn-social(#587ea3); } -.btn-yahoo { .btn-social(#720e9e); } diff --git a/client/less/lib/font-awesome-4.3.0/fonts/fontawesome-webfont.svg b/client/less/lib/font-awesome-4.3.0/fonts/fontawesome-webfont.svg index 1ee89d4368..744c88ad9c 100644 --- a/client/less/lib/font-awesome-4.3.0/fonts/fontawesome-webfont.svg +++ b/client/less/lib/font-awesome-4.3.0/fonts/fontawesome-webfont.svg @@ -562,4 +562,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/client/less/lib/ionicons/_ionicons-animation.less b/client/less/lib/ionicons/_ionicons-animation.less index 4e24467775..55f457ccd8 100644 --- a/client/less/lib/ionicons/_ionicons-animation.less +++ b/client/less/lib/ionicons/_ionicons-animation.less @@ -56,30 +56,30 @@ animation-timing-function: steps(8, start); } -.@{ionicons-prefix}loading-a:before { +.@{ionicons-prefix}loading-a:before { &:extend(.@{ionicons-prefix}load-a:before); } -.@{ionicons-prefix}loading-b:before { +.@{ionicons-prefix}loading-b:before { &:extend(.@{ionicons-prefix}load-b:before); } -.@{ionicons-prefix}loading-c:before { +.@{ionicons-prefix}loading-c:before { &:extend(.@{ionicons-prefix}load-c:before); } -.@{ionicons-prefix}loading-d:before { +.@{ionicons-prefix}loading-d:before { &:extend(.@{ionicons-prefix}load-d:before); } -.@{ionicons-prefix}looping:before { +.@{ionicons-prefix}looping:before { &:extend(.@{ionicons-prefix}loop:before); } -.@{ionicons-prefix}refreshing:before { +.@{ionicons-prefix}refreshing:before { &:extend(.@{ionicons-prefix}refresh:before); } -.@{ionicons-prefix}ios7-reloading:before { +.@{ionicons-prefix}ios7-reloading:before { &:extend(.@{ionicons-prefix}ios7-reload:before); } diff --git a/client/less/map.less b/client/less/map.less index 7b97e33e31..0c151c4ccd 100644 --- a/client/less/map.less +++ b/client/less/map.less @@ -134,12 +134,12 @@ position:absolute; display: block; height: 100%; - width: 100%; + width: 100%; } .map-accordion { - width:700px; - margin:155px auto 0; + width:700px; + margin:155px auto 0; position:relative; #nested { margin:0 10px; @@ -256,7 +256,7 @@ } } } - + .map-aside-action-item { display: -webkit-flex; display: flex; diff --git a/common/app/components/Footer/links.json b/common/app/components/Footer/links.json index 8089a868e4..acb50bde56 100644 --- a/common/app/components/Footer/links.json +++ b/common/app/components/Footer/links.json @@ -13,7 +13,7 @@ }, { "className": "ion-social-github", - "content": " Github ", + "content": " GitHub ", "href": "http://github.com/freecodecamp", "target": "_blank" }, diff --git a/common/app/routes/Hikes/components/Hike.jsx b/common/app/routes/Hikes/components/Hike.jsx index 5e147ea6e6..687c1474eb 100644 --- a/common/app/routes/Hikes/components/Hike.jsx +++ b/common/app/routes/Hikes/components/Hike.jsx @@ -1,6 +1,6 @@ import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; -import { Col, Row } from 'react-bootstrap'; +import { Col } from 'react-bootstrap'; import { createSelector } from 'reselect'; import Lecture from './Lecture.jsx'; @@ -55,18 +55,16 @@ export class Hike extends React.Component { return ( - -
-

{ title }

-
-
-
-
- { this.renderBody(shouldShowQuestions) } -
- +
+

{ title }

+
+
+
+
+ { this.renderBody(shouldShowQuestions) } +
); } diff --git a/common/app/routes/Hikes/components/Hikes.jsx b/common/app/routes/Hikes/components/Hikes.jsx index da41f8e4ca..1b34251659 100644 --- a/common/app/routes/Hikes/components/Hikes.jsx +++ b/common/app/routes/Hikes/components/Hikes.jsx @@ -1,7 +1,6 @@ import React, { PropTypes } from 'react'; import { compose } from 'redux'; import { connect } from 'react-redux'; -import { Row } from 'react-bootstrap'; import PureComponent from 'react-pure-render/component'; import { createSelector } from 'reselect'; // import debug from 'debug'; @@ -59,17 +58,14 @@ export class Hikes extends PureComponent { render() { const { hikes } = this.props; - const preventOverflow = { overflow: 'hidden' }; return (
- - { - // render sub-route - this.props.children || - // if no sub-route render hikes map - this.renderMap(hikes) - } - + { + // render sub-route + this.props.children || + // if no sub-route render hikes map + this.renderMap(hikes) + }
); } diff --git a/package.json b/package.json index 9ee266c0ac..739e202db7 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "express-state": "^1.2.0", "express-validator": "^2.18.0", "fetchr": "~0.5.12", - "frameguard": "~0.2.2", + "frameguard": "~1.1.0", "gulp": "^3.9.0", "gulp-babel": "^6.1.1", "gulp-concat": "^2.6.0", diff --git a/public/fonts/fontawesome-webfont.svg b/public/fonts/fontawesome-webfont.svg index 1ee89d4368..744c88ad9c 100644 --- a/public/fonts/fontawesome-webfont.svg +++ b/public/fonts/fontawesome-webfont.svg @@ -562,4 +562,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/fonts/ionicons.svg b/public/fonts/ionicons.svg index a0ed5a1673..98deb3b084 100644 --- a/public/fonts/ionicons.svg +++ b/public/fonts/ionicons.svg @@ -11,7 +11,7 @@ Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/images/freecodecamp_logo.svg b/public/images/freecodecamp_logo.svg index 62824cbd92..2c24007979 100644 --- a/public/images/freecodecamp_logo.svg +++ b/public/images/freecodecamp_logo.svg @@ -24,20 +24,20 @@ rdf:about="">image/svg+xml - - - - - - - - - - - - - - + + + + + + + + + + + + + + = 0; i--) { - if (this._indices[i]-1 == this._indices[i-1]) { - this._indices.pop(); - } else { - break; - } - } - } - - - /** - * Stores the given object and returns the refernce id instead - * - * @param {Object} obj to store - * - * @returns {Number} reference id of the stored object - */ - ReferenceStore.prototype.put = function(obj) { - var id = this._genId(); - this._store[id] = obj; - return id; - } - - - /** - * Retrieves previously stored object and releases its reference - * - * @param {Number} id of an object to retrieve - */ - ReferenceStore.prototype.fetch = function(id) { - var obj = this._store[id]; - this._store[id] = null; - delete this._store[id]; - this._releaseId(id); - return obj; - } - - -})(); - diff --git a/public/js/lib/jailed/_frame.html b/public/js/lib/jailed/_frame.html deleted file mode 100644 index 68b300d6e3..0000000000 --- a/public/js/lib/jailed/_frame.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/public/js/lib/jailed/_frame.js b/public/js/lib/jailed/_frame.js deleted file mode 100644 index fa310643fd..0000000000 --- a/public/js/lib/jailed/_frame.js +++ /dev/null @@ -1,56 +0,0 @@ - -/** - * Contains the code executed in the sandboxed frame under web-browser - * - * Creates a Web-Worker inside the frame, sets up the communication - * between the worker and the parent window - */ - - -var scripts = document.getElementsByTagName('script'); -var __jailed__path__ = scripts[scripts.length-1].src - .split('?')[0] - .split('/') - .slice(0, -1) - .join('/') + '/'; - -// creating worker as a blob enables import of local files -var blobCode = [ - ' self.addEventListener("message", function(m){ ', - ' if (m.data.type == "initImport") { ', - ' importScripts(m.data.url); ', - ' self.postMessage({type: "initialized"}); ', - ' } ', - ' }); ' -].join('\n'); - -var blobUrl; -try { - blobUrl = new Blob([blobCode], {type: 'application/javascript'}); -} catch (e) { - window.BlobBuilder = window.BlobBuilder - || window.WebKitBlobBuilder - || window.MozBlobBuilder; - blobUrl = new BlobBuilder(); - blobUrl.append(blobCode); - blobUrl = blobUrl.getBlob(); -} - -var worker = new Worker(URL.createObjectURL(blobUrl)); - -// telling worker to load _pluginWeb.js (see blob code above) -worker.postMessage({ - type: 'initImport', - url: __jailed__path__ + '_pluginWeb.js' -}); - - -// forwarding messages between the worker and parent window -worker.addEventListener('message', function(m) { - parent.postMessage(m.data, '*'); -}); - -window.addEventListener('message', function(m) { - worker.postMessage(m.data); -}); - diff --git a/public/js/lib/jailed/_pluginCore.js b/public/js/lib/jailed/_pluginCore.js deleted file mode 100644 index 6f75c07cc3..0000000000 --- a/public/js/lib/jailed/_pluginCore.js +++ /dev/null @@ -1,95 +0,0 @@ - -/** - * Core plugin script loaded into the plugin process/thread. - * - * Initializes the plugin-site API global methods. - */ - -(function(){ - - // localize - var site = new JailedSite(connection); - delete JailedSite; - delete connection; - - site.onGetInterface(function(){ - launchConnected(); - }); - - site.onRemoteUpdate(function(){ - application.remote = site.getRemote(); - }); - - - - /** - * Simplified clone of Whenable instance (the object can not be - * placed into a shared script, because the main library needs it - * before the additional scripts may load) - */ - var connected = false; - var connectedHandlers = []; - - var launchConnected = function() { - if (!connected) { - connected = true; - - var handler; - while(handler = connectedHandlers.pop()) { - handler(); - } - } - } - - var checkHandler = function(handler){ - var type = typeof handler; - if (type != 'function') { - var msg = - 'A function may only be subsribed to the event, ' - + type - + ' was provided instead' - throw new Error(msg); - } - - return handler; - } - - - /** - * Sets a function executed after the connection to the - * application is estaplished, and the initial interface-exchange - * messaging is completed - * - * @param {Function} handler to be called upon initialization - */ - application.whenConnected = function(handler) { - handler = checkHandler(handler); - if (connected) { - handler(); - } else { - connectedHandlers.push(handler); - } - } - - - /** - * Sets the plugin interface available to the application - * - * @param {Object} _interface to set - */ - application.setInterface = function(_interface) { - site.setInterface(_interface); - } - - - - /** - * Disconnects the plugin from the application (sending - * notification message) and destroys itself - */ - application.disconnect = function(_interface) { - site.disconnect(); - } - -})(); - diff --git a/public/js/lib/jailed/_pluginNode.js b/public/js/lib/jailed/_pluginNode.js deleted file mode 100644 index f3daa6f7e5..0000000000 --- a/public/js/lib/jailed/_pluginNode.js +++ /dev/null @@ -1,267 +0,0 @@ - -/** - * Contains the routines loaded by the plugin process under Node.js - * - * Initializes the Node.js environment version of the - * platform-dependent connection object for the plugin site - */ - -application = {}; -connection = {}; - - -/** - * Prints error message and its stack - * - * @param {Object} msg stack provided by error.stack or a message - */ -var printError = function(msg) { - console.error(); - console.error(msg); -} - - -/** - * Event lisener for the plugin message - */ -process.on('message', function(m) { - switch(m.type){ - case 'import': - importScript(m.url); - break; - case 'importJailed': - importScriptJailed(m.url); - break; - case 'execute': - execute(m.code); - break; - case 'message': - // unhandled exception would break the IPC channel - try { - conn._messageHandler(m.data); - } catch(e) { - printError(e.stack); - } - break; - } -}); - - -/** - * Checks if the given path is remote - * - * @param {String} path to check - * @returns {Boolean} true if path is remote - */ -var isRemote = function(path) { - return (path.substr(0,7).toLowerCase() == 'http://' || - path.substr(0,8).toLowerCase() == 'https://'); -} - - -/** - * Loads and executes the JavaScript file with the given url - * - * @param {String} url of the script to load - */ -var importScript = function(url) { - var sCb = function() { - process.send({type: 'importSuccess', url: url}); - } - - var fCb = function() { - process.send({type: 'importFailure', url: url}); - } - - var run = function(code) { - executeNormal(code, url, sCb, fCb); - } - - if (isRemote(url)) { - loadRemote(url, run, fCb); - } else { - try { - run(loadLocal(url)); - } catch(e) { - printError(e.stack); - fCb(); - } - } - -} - - -/** - * Loads and executes the JavaScript file with the given url in a - * jailed environment - * - * @param {String} url of the script to load - */ -var importScriptJailed = function(url) { - var sCb = function() { - process.send({type: 'importSuccess', url: url}); - } - - var fCb = function() { - process.send({type: 'importFailure', url: url}); - } - - var run = function(code) { - executeJailed(code, url, sCb, fCb); - } - - if (isRemote(url)) { - loadRemote(url, run, fCb); - } else { - try { - run(loadLocal(url)); - } catch (e) { - printError(e.stack); - fCb(); - } - - } - -} - - -/** - * Executes the given code in the jailed environment, sends the - * corresponding message to the application site when succeeded/failed - * - * @param {String} code to execute - */ -var execute = function(code) { - var sCb = function() { - process.send({type: 'executeSuccess'}); - } - - var fCb = function() { - process.send({type: 'executeFailure'}); - } - - executeJailed(code, 'DYNAMIC PLUGIN', sCb, fCb); -} - - -/** - * Executes the given code in the current environment / scope, runs - * the corresponding callback when done - * - * @param {String} code to execute - * @param {String} url of the script (for displaying the stack) - * @param {Function} sCb - * @param {Function} fCb - */ -var executeNormal = function(code, url, sCb, fCb) { - var err = null; - try { - require('vm').runInThisContext(code, url); - sCb(); - } catch (e) { - printError(e.stack); - fCb(); - } -} - - -/** - * Executes the given code in a jailed environment, runs the - * corresponding callback when done - * - * @param {String} code to execute - * @param {String} url of the script (for displaying the stack) - * @param {Function} sCb - * @param {Function} fCb - */ -var executeJailed = function(code, url, sCb, fCb) { - var vm = require('vm'); - var sandbox = {}; - var expose = [ - 'application', - 'setTimeout', - 'setInterval', - 'clearTimeout', - 'clearInterval' - ]; - - for (var i = 0; i < expose.length; i++) { - sandbox[expose[i]] = global[expose[i]]; - } - - code = '"use strict";\n'+code; - try { - vm.runInNewContext(code, vm.createContext(sandbox), url); - sCb(); - } catch (e) { - printError(e.stack); - fCb(); - } -} - - -/** - * Loads local file and - * - * @param {String} path of the file to read - * - * @returns {String} file contents - */ -var loadLocal = function(path) { - return require("fs").readFileSync(path).toString(); -} - - -/** - * Downloads the script by remote url and provides its content as a - * string to the callback - * - * @param {String} url of the remote module to load - * @param {Function} sCb success callback - * @param {Function} fCb failure callback - */ -var loadRemote = function(url, sCb, fCb) { - var receive = function(res) { - if (res.statusCode != 200) { - var msg = 'Failed to load ' + url + '\n' + - 'HTTP responce status code: ' + res.statusCode; - printError(msg); - fCb(); - } else { - var content = ''; - res.on('end', function(){ sCb(content); }); - res.on( - 'readable', - function() { - var chunk = res.read(); - content += chunk.toString(); - } - ); - } - } - - try { - require('http').get(url, receive).on('error', fCb); - } catch (e) { - printError(e.stack); - fCb(); - } -} - - -/** - * Connection object provided to the SandboxedSite constructor, plugin - * site implementation for the Node.js environment - */ -var conn = { - disconnect: function(){ process.exit(); }, - send: function(data) { - process.send({type: 'message', data: data}); - }, - onMessage: function(h){ conn._messageHandler = h; }, - _messageHandler: function(){}, - onDisconnect: function() {} -}; - -connection = conn; - diff --git a/public/js/lib/jailed/_pluginWeb.js b/public/js/lib/jailed/_pluginWeb.js deleted file mode 100644 index e3254155ec..0000000000 --- a/public/js/lib/jailed/_pluginWeb.js +++ /dev/null @@ -1,96 +0,0 @@ - -/** - * Contains the routines loaded by the plugin Worker under web-browser. - * - * Initializes the web environment version of the platform-dependent - * connection object for the plugin site - */ - -self.application = {}; -self.connection = {}; - - -(function(){ - - /** - * Event lisener for the plugin message - */ - self.addEventListener('message', function(e){ - var m = e.data.data; - switch (m.type) { - case 'import': - case 'importJailed': // already jailed in the Worker - importScript(m.url); - break; - case 'execute': - execute(m.code); - break; - case 'message': - conn._messageHandler(m.data); - break; - } - }); - - - /** - * Loads and executes the JavaScript file with the given url - * - * @param {String} url to load - */ - var importScript = function(url) { - var error = null; - try { - importScripts(url); - } catch (e) { - error = e; - } - - if (error) { - self.postMessage({type: 'importFailure', url: url}); - throw error; - } else { - self.postMessage({type: 'importSuccess', url: url}); - } - - } - - - /** - * Executes the given code in a jailed environment. For web - * implementation, we're already jailed in the worker, so simply - * eval() - * - * @param {String} code code to execute - */ - var execute = function(code) { - try { - eval(code); - } catch (e) { - self.postMessage({type: 'executeFailure'}); - throw e; - } - - self.postMessage({type: 'executeSuccess'}); - } - - - /** - * Connection object provided to the JailedSite constructor, - * plugin site implementation for the web-based environment. - * Global will be then cleared to prevent exposure into the - * Worker, so we put this local connection object into a closure - */ - var conn = { - disconnect: function(){ self.close(); }, - send: function(data) { - self.postMessage({type: 'message', data: data}); - }, - onMessage: function(h){ conn._messageHandler = h; }, - _messageHandler: function(){}, - onDisconnect: function() {} - }; - - connection = conn; - -})(); - diff --git a/public/js/lib/jailed/jailed.js b/public/js/lib/jailed/jailed.js deleted file mode 100644 index 4650b8cbe3..0000000000 --- a/public/js/lib/jailed/jailed.js +++ /dev/null @@ -1,780 +0,0 @@ -/** - * @fileoverview Jailed - safe yet flexible sandbox - * @version 0.2.0 - * - * @license MIT, see http://github.com/asvd/jailed - * Copyright (c) 2014 asvd - * - * Main library script, the only one to be loaded by a developer into - * the application. Other scrips shipped along will be loaded by the - * library either here (application site), or into the plugin site - * (Worker/child process): - * - * _JailedSite.js loaded into both applicaiton and plugin sites - * _frame.html sandboxed frame (web) - * _frame.js sandboxed frame code (web) - * _pluginWeb.js platform-dependent plugin routines (web) - * _pluginNode.js platform-dependent plugin routines (Node.js) - * _pluginCore.js common plugin site protocol implementation - */ - - -var __jailed__path__; -if (typeof window == 'undefined') { - // Node.js - __jailed__path__ = __dirname + '/'; -} else { - // web - var scripts = document.getElementsByTagName('script'); - __jailed__path__ = scripts[scripts.length-1].src - .split('?')[0] - .split('/') - .slice(0, -1) - .join('/')+'/'; -} - - -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.jailed = {})); - } -}(this, function (exports) { - var isNode = typeof window == 'undefined'; - - - /** - * A special kind of event: - * - which can only be emitted once; - * - executes a set of subscribed handlers upon emission; - * - if a handler is subscribed after the event was emitted, it - * will be invoked immideately. - * - * Used for the events which only happen once (or do not happen at - * all) during a single plugin lifecycle - connect, disconnect and - * connection failure - */ - var Whenable = function() { - this._emitted = false; - this._handlers = []; - } - - - /** - * Emits the Whenable event, calls all the handlers already - * subscribed, switches the object to the 'emitted' state (when - * all future subscibed listeners will be immideately issued - * instead of being stored) - */ - Whenable.prototype.emit = function(){ - if (!this._emitted) { - this._emitted = true; - - var handler; - while(handler = this._handlers.pop()) { - setTimeout(handler,0); - } - } - } - - - /** - * Saves the provided function as a handler for the Whenable - * event. This handler will then be called upon the event emission - * (if it has not been emitted yet), or will be scheduled for - * immediate issue (if the event has already been emmitted before) - * - * @param {Function} handler to subscribe for the event - */ - Whenable.prototype.whenEmitted = function(handler){ - handler = this._checkHandler(handler); - if (this._emitted) { - setTimeout(handler, 0); - } else { - this._handlers.push(handler); - } - } - - - /** - * Checks if the provided object is suitable for being subscribed - * to the event (= is a function), throws an exception if not - * - * @param {Object} obj to check for being subscribable - * - * @throws {Exception} if object is not suitable for subscription - * - * @returns {Object} the provided object if yes - */ - Whenable.prototype._checkHandler = function(handler){ - var type = typeof handler; - if (type != 'function') { - var msg = - 'A function may only be subsribed to the event, ' - + type - + ' was provided instead' - throw new Error(msg); - } - - return handler; - } - - - - /** - * Initializes the library site for Node.js environment (loads - * _JailedSite.js) - */ - var initNode = function() { - require('./_JailedSite.js'); - } - - - /** - * Initializes the library site for web environment (loads - * _JailedSite.js) - */ - var platformInit; - var initWeb = function() { - // loads additional script to the application environment - var load = function(path, cb) { - var script = document.createElement('script'); - script.src = path; - - var clear = function() { - script.onload = null; - script.onerror = null; - script.onreadystatechange = null; - script.parentNode.removeChild(script); - } - - var success = function() { - clear(); - cb(); - } - - script.onerror = clear; - script.onload = success; - script.onreadystatechange = function() { - var state = script.readyState; - if (state==='loaded' || state==='complete') { - success(); - } - } - - document.body.appendChild(script); - } - - platformInit = new Whenable; - var origOnload = window.onload || function(){}; - - window.onload = function(){ - origOnload(); - load( - __jailed__path__+'_JailedSite.js', - function(){ platformInit.emit(); } - ); - } - } - - - var BasicConnection; - - /** - * Creates the platform-dependent BasicConnection object in the - * Node.js environment - */ - var basicConnectionNode = function() { - var childProcess = require('child_process'); - - /** - * Platform-dependent implementation of the BasicConnection - * object, initializes the plugin site and provides the basic - * messaging-based connection with it - * - * For Node.js the plugin is created as a forked process - */ - BasicConnection = function() { - this._disconnected = false; - this._messageHandler = function(){}; - this._disconnectHandler = function(){}; - this._process = childProcess.fork( - __jailed__path__+'_pluginNode.js' - ); - - var me = this; - this._process.on('message', function(m){ - me._messageHandler(m); - }); - - this._process.on('exit', function(m){ - me._disconnected = true; - me._disconnectHandler(m); - }); - } - - - /** - * Sets-up the handler to be called upon the BasicConnection - * initialization is completed. - * - * For Node.js the connection is fully initialized within the - * constructor, so simply calls the provided handler. - * - * @param {Function} handler to be called upon connection init - */ - BasicConnection.prototype.whenInit = function(handler) { - handler(); - } - - - /** - * Sends a message to the plugin site - * - * @param {Object} data to send - */ - BasicConnection.prototype.send = function(data) { - if (!this._disconnected) { - this._process.send(data); - } - } - - - /** - * Adds a handler for a message received from the plugin site - * - * @param {Function} handler to call upon a message - */ - BasicConnection.prototype.onMessage = function(handler) { - this._messageHandler = function(data) { - // broken stack would break the IPC in Node.js - try { - handler(data); - } catch (e) { - console.error(); - console.error(e.stack); - } - } - } - - - /** - * Adds a handler for the event of plugin disconnection - * (= plugin process exit) - * - * @param {Function} handler to call upon a disconnect - */ - BasicConnection.prototype.onDisconnect = function(handler) { - this._disconnectHandler = handler; - } - - - /** - * Disconnects the plugin (= kills the forked process) - */ - BasicConnection.prototype.disconnect = function() { - this._process.kill('SIGKILL'); - this._disconnected = true; - } - - } - - - /** - * Creates the platform-dependent BasicConnection object in the - * web-browser environment - */ - var basicConnectionWeb = function() { - var perm = ['allow-scripts']; - - if (__jailed__path__.substr(0,7).toLowerCase() == 'file://') { - // local instance requires extra permission - perm.push('allow-same-origin'); - } - - // frame element to be cloned - var sample = document.createElement('iframe'); - sample.src = __jailed__path__ + '_frame.html'; - sample.sandbox = perm.join(' '); - sample.style.display = 'none'; - - - /** - * Platform-dependent implementation of the BasicConnection - * object, initializes the plugin site and provides the basic - * messaging-based connection with it - * - * For the web-browser environment, the plugin is created as a - * Worker in a sandbaxed frame - */ - BasicConnection = function() { - this._init = new Whenable; - this._disconnected = false; - - var me = this; - platformInit.whenEmitted(function() { - if (!me._disconnected) { - me._frame = sample.cloneNode(false); - document.body.appendChild(me._frame); - - window.addEventListener('message', function (e) { - if (e.origin === "null" && - e.source === me._frame.contentWindow) { - if (e.data.type == 'initialized') { - me._init.emit(); - } else { - me._messageHandler(e.data); - } - } - }); - } - }); - } - - - /** - * Sets-up the handler to be called upon the BasicConnection - * initialization is completed. - * - * For the web-browser environment, the handler is issued when - * the plugin worker successfully imported and executed the - * _pluginWeb.js, and replied to the application site with the - * initImprotSuccess message. - * - * @param {Function} handler to be called upon connection init - */ - BasicConnection.prototype.whenInit = function(handler) { - this._init.whenEmitted(handler); - } - - - /** - * Sends a message to the plugin site - * - * @param {Object} data to send - */ - BasicConnection.prototype.send = function(data) { - this._frame.contentWindow.postMessage( - {type: 'message', data: data}, '*' - ); - } - - - /** - * Adds a handler for a message received from the plugin site - * - * @param {Function} handler to call upon a message - */ - BasicConnection.prototype.onMessage = function(handler) { - this._messageHandler = handler; - } - - - /** - * Adds a handler for the event of plugin disconnection - * (not used in case of Worker) - * - * @param {Function} handler to call upon a disconnect - */ - BasicConnection.prototype.onDisconnect = function(){}; - - - /** - * Disconnects the plugin (= kills the frame) - */ - BasicConnection.prototype.disconnect = function() { - if (!this._disconnected) { - this._disconnected = true; - if (typeof this._frame != 'undefined') { - this._frame.parentNode.removeChild(this._frame); - } // otherwise farme is not yet created - } - } - - } - - - if (isNode) { - initNode(); - basicConnectionNode(); - } else { - initWeb(); - basicConnectionWeb(); - } - - - - /** - * Application-site Connection object constructon, reuses the - * platform-dependent BasicConnection declared above in order to - * communicate with the plugin environment, implements the - * application-site protocol of the interraction: provides some - * methods for loading scripts and executing the given code in the - * plugin - */ - var Connection = function(){ - this._platformConnection = new BasicConnection; - - this._importCallbacks = {}; - this._executeSCb = function(){}; - this._executeFCb = function(){}; - this._messageHandler = function(){}; - - var me = this; - this.whenInit = function(cb){ - me._platformConnection.whenInit(cb); - }; - - this._platformConnection.onMessage(function(m) { - switch(m.type) { - case 'message': - me._messageHandler(m.data); - break; - case 'importSuccess': - me._handleImportSuccess(m.url); - break; - case 'importFailure': - me._handleImportFailure(m.url); - break; - case 'executeSuccess': - me._executeSCb(); - break; - case 'executeFailure': - me._executeFCb(); - break; - } - }); - } - - - /** - * Tells the plugin to load a script with the given path, and to - * execute it. Callbacks executed upon the corresponding responce - * message from the plugin site - * - * @param {String} path of a script to load - * @param {Function} sCb to call upon success - * @param {Function} fCb to call upon failure - */ - Connection.prototype.importScript = function(path, sCb, fCb) { - var f = function(){}; - this._importCallbacks[path] = {sCb: sCb||f, fCb: fCb||f}; - this._platformConnection.send({type: 'import', url: path}); - } - - - /** - * Tells the plugin to load a script with the given path, and to - * execute it in the JAILED environment. Callbacks executed upon - * the corresponding responce message from the plugin site - * - * @param {String} path of a script to load - * @param {Function} sCb to call upon success - * @param {Function} fCb to call upon failure - */ - Connection.prototype.importJailedScript = function(path, sCb, fCb) { - var f = function(){}; - this._importCallbacks[path] = {sCb: sCb||f, fCb: fCb||f}; - this._platformConnection.send({type: 'importJailed', url: path}); - } - - - /** - * Sends the code to the plugin site in order to have it executed - * in the JAILED enviroment. Assuming the execution may only be - * requested once by the Plugin object, which means a single set - * of callbacks is enough (unlike importing additional scripts) - * - * @param {String} code code to execute - * @param {Function} sCb to call upon success - * @param {Function} fCb to call upon failure - */ - Connection.prototype.execute = function(code, sCb, fCb) { - this._executeSCb = sCb||function(){}; - this._executeFCb = fCb||function(){}; - this._platformConnection.send({type: 'execute', code: code}); - } - - - /** - * Adds a handler for a message received from the plugin site - * - * @param {Function} handler to call upon a message - */ - Connection.prototype.onMessage = function(handler) { - this._messageHandler = handler; - } - - - /** - * Adds a handler for a disconnect message received from the - * plugin site - * - * @param {Function} handler to call upon disconnect - */ - Connection.prototype.onDisconnect = function(handler) { - this._platformConnection.onDisconnect(handler); - } - - - /** - * Sends a message to the plugin - * - * @param {Object} data of the message to send - */ - Connection.prototype.send = function(data) { - this._platformConnection.send({ - type: 'message', - data: data - }); - } - - - /** - * Handles import succeeded message from the plugin - * - * @param {String} url of a script loaded by the plugin - */ - Connection.prototype._handleImportSuccess = function(url) { - var sCb = this._importCallbacks[url].sCb; - this._importCallbacks[url] = null; - delete this._importCallbacks[url]; - sCb(); - } - - - /** - * Handles import failure message from the plugin - * - * @param {String} url of a script loaded by the plugin - */ - Connection.prototype._handleImportFailure = function(url) { - var fCb = this._importCallbacks[url].fCb; - this._importCallbacks[url] = null; - delete this._importCallbacks[url]; - fCb(); - } - - - /** - * Disconnects the plugin when it is not needed anymore - */ - Connection.prototype.disconnect = function() { - this._platformConnection.disconnect(); - } - - - - - /** - * Plugin constructor, represents a plugin initialized by a script - * with the given path - * - * @param {String} url of a plugin source - * @param {Object} _interface to provide for the plugin - */ - var Plugin = function(url, _interface) { - this._path = url; - this._initialInterface = _interface||{}; - this._connect(); - } - - - /** - * DynamicPlugin constructor, represents a plugin initialized by a - * string containing the code to be executed - * - * @param {String} code of the plugin - * @param {Object} _interface to provide to the plugin - */ - var DynamicPlugin = function(code, _interface) { - this._code = code; - this._initialInterface = _interface||{}; - this._connect(); - } - - - /** - * Creates the connection to the plugin site - */ - DynamicPlugin.prototype._connect = - Plugin.prototype._connect = function() { - this.remote = null; - - this._connect = new Whenable; - this._fail = new Whenable; - this._disconnect = new Whenable; - - var me = this; - - // binded failure callback - this._fCb = function(){ - me._fail.emit(); - me.disconnect(); - } - - this._connection = new Connection; - this._connection.whenInit(function(){ - me._init(); - }); - } - - - /** - * Creates the Site object for the plugin, and then loads the - * common routines (_JailedSite.js) - */ - DynamicPlugin.prototype._init = - Plugin.prototype._init = function() { - this._site = new JailedSite(this._connection); - - var me = this; - this._site.onDisconnect(function() { - me._disconnect.emit(); - }); - - var sCb = function() { - me._loadCore(); - } - - this._connection.importScript( - __jailed__path__+'_JailedSite.js', sCb, this._fCb - ); - } - - - /** - * Loads the core scirpt into the plugin - */ - DynamicPlugin.prototype._loadCore = - Plugin.prototype._loadCore = function() { - var me = this; - var sCb = function() { - me._sendInterface(); - } - - this._connection.importScript( - __jailed__path__+'_pluginCore.js', sCb, this._fCb - ); - } - - - /** - * Sends to the remote site a signature of the interface provided - * upon the Plugin creation - */ - DynamicPlugin.prototype._sendInterface = - Plugin.prototype._sendInterface = function() { - var me = this; - this._site.onInterfaceSetAsRemote(function() { - if (!me._connected) { - me._loadPlugin(); - } - }); - - this._site.setInterface(this._initialInterface); - } - - - /** - * Loads the plugin body (loads the plugin url in case of the - * Plugin) - */ - Plugin.prototype._loadPlugin = function() { - var me = this; - var sCb = function() { - me._requestRemote(); - } - - this._connection.importJailedScript(this._path, sCb, this._fCb); - } - - - /** - * Loads the plugin body (executes the code in case of the - * DynamicPlugin) - */ - DynamicPlugin.prototype._loadPlugin = function() { - var me = this; - var sCb = function() { - me._requestRemote(); - } - - this._connection.execute(this._code, sCb, this._fCb); - } - - - /** - * Requests the remote interface from the plugin (which was - * probably set by the plugin during its initialization), emits - * the connect event when done, then the plugin is fully usable - * (meaning both the plugin and the application can use the - * interfaces provided to each other) - */ - DynamicPlugin.prototype._requestRemote = - Plugin.prototype._requestRemote = function() { - var me = this; - this._site.onRemoteUpdate(function(){ - me.remote = me._site.getRemote(); - me._connect.emit(); - }); - - this._site.requestRemote(); - } - - - /** - * Disconnects the plugin immideately - */ - DynamicPlugin.prototype.disconnect = - Plugin.prototype.disconnect = function() { - this._connection.disconnect(); - this._disconnect.emit(); - } - - - /** - * Saves the provided function as a handler for the connection - * failure Whenable event - * - * @param {Function} handler to be issued upon disconnect - */ - DynamicPlugin.prototype.whenFailed = - Plugin.prototype.whenFailed = function(handler) { - this._fail.whenEmitted(handler); - } - - - /** - * Saves the provided function as a handler for the connection - * success Whenable event - * - * @param {Function} handler to be issued upon connection - */ - DynamicPlugin.prototype.whenConnected = - Plugin.prototype.whenConnected = function(handler) { - this._connect.whenEmitted(handler); - } - - - /** - * Saves the provided function as a handler for the connection - * failure Whenable event - * - * @param {Function} handler to be issued upon connection failure - */ - DynamicPlugin.prototype.whenDisconnected = - Plugin.prototype.whenDisconnected = function(handler) { - this._disconnect.whenEmitted(handler); - } - - - - exports.Plugin = Plugin; - exports.DynamicPlugin = DynamicPlugin; - -})); - diff --git a/seed/challenges/00-getting-started/getting-started.json b/seed/challenges/00-getting-started/getting-started.json index 5e3e7d9b71..a9221ffe00 100644 --- a/seed/challenges/00-getting-started/getting-started.json +++ b/seed/challenges/00-getting-started/getting-started.json @@ -234,6 +234,81 @@ "Si completas todas las 2,080 horas de desafíos y proyectos, obtendrás un Certificado de Desarrollo de Pila Completa. Te ofreceremos gratuitamente una práctica en entrevistas para desarrolladores. Incluso ofrecemos un directorio de trabajos donde los empleadores contratan específicamente campistas que han recibido certificaciones de Free Code Camp.", "" ] + ], + "titleDe": "Lerne wie Free Code Camp funktioniert", + "descriptionDe": [ + [ + "//i.imgur.com/6ibIavQ.jpg", + "Ein Bild von den 4 Vorteilen von Free Code Camp: Vernetz Dich, Lerne Javascript, Bau ein Portfolio auf, Hilf Non-Profit-Organisationen", + "Willkommen bei Free Code Camp. Wir sind eine Open Source Gemeinschaft von motivierten Leuten, die programmieren lernen und Non-Profit-Organisationen helfen", + "" + ], + [ + "//i.imgur.com/Elb3dfj.jpg", + "Ein Screenshot von einigen unserer Camper beim gemeinsamen Programmieren in Toronto.", + "Programmieren zu lernen ist hart. Um erfolgreich zu sein brauchst du viel Übung und Unterstützung. Deswegen haben wir ein umfangreiches Curriculum und eine unterstützende Gemeinschaft geschaffen.", + "" + ], + [ + "//i.imgur.com/D7Y5luw.jpg", + "Ein Graph vom Verhältnis der Wachstumsrate von Jobs gegenüber der Abschlüsse von Informatik Studien. Es gibts 1,4 Millionen Jobs aber nur 400.000 Leute um diese zu füllen.", + "Es gibt tausende von unbesetzen Programmierjobs und die Nachfrage wächst jedes Jahr", + "" + ], + [ + "//i.imgur.com/WD3STY6.jpg", + "Foto von drei Campern die einen Job bekommen haben nachdem sie bei Free Code Camp programmieren gelernt haben", + "Free Code Camp ist ein sicherer Weg zu deinem ersten Programmierjob. Tatsächlich hat noch niemand unser komplettes Programm beendet, weil Campers bereits davor Jobs finden.", + "" + ], + [ + "//i.imgur.com/vLNso6h.jpg", + "Eine Illustration die zeigt dass du HTML5, CSS3, JavaScript, Datenbanken, Git, Node.js, React und D3 lernen wirst", + "Wir haben hunderte von optionalen Programmieraufgaben die dir die fundamentalen Webentwicklungstechnologien wie HTML5, Node.js und Datanbanken beibringen werden.", + "" + ], + [ + "//i.imgur.com/UVB9hxp.jpg", + "Ein Foto von einem Camper in einem Cafe der an Free Code Camp Projekten arbeitet.", + "Wir glauben dass Menschen am Besten beim Tun lernen. Deswegen wirst du die meiste Zeit damit beschäftigt sein an tatsächlichen Projekten zu arbeiten. Wir werden dir eine Liste an Anforderungen (agile User Stories) geben und du wirst dich damit auseinander setzen diese zu erfüllen.", + "" + ], + [ + "//i.imgur.com/pbW7K5S.jpg", + "Ein Bild auf dem man unsere Frontend-, Backend- und Daten Visualisierungzertifikate (je 400 Stunden), unsere Non-Profit-Projekte (800 Stunden) und Bewerbungsgesprächsvorbereitung (80 Stunden) sieht mit einer Summe von 2080 Stunden Programmiererfahrung.", + "Unser Curriculum ist in 4 Zertifikate aufgeteilt. Diese Zertifikate sind standardisiert und jederzeit von deinen Kunden oder zukünftigen Arbeitgeber überprüfbar. Wie alles andere auch bei Free Code Camp sind die Zertifikate gratis. Wir empfehlen sie in der vorgesehenen Reihenfolge zu machen, aber es steht dir offen frei zu wählen. Die ersten drei Zertifikate dauern jeweils 400 Stunden. Das letzte Zertifikat dauert 800 Stunden und beinhaltet die Umsetzung eines echten Projektes für eine Non-Profit-Organisation.", + "" + ], + [ + "//i.imgur.com/k8btNUB.jpg", + "Ein Screenshot von unserem Frontendzertifikat", + "Um sich unser geprüftes Frontend-Entwicklungszertifikat zu verdienen, wirst du 10 Projekte mit HTML, CSS, jQuery und Javascript umsetzen.", + "" + ], + [ + "//i.imgur.com/Et3iD74.jpg", + "Ein Screenshot von unserem Datenvisualisierungszertifikat", + "Für unser Datenvisualisierungszertifikat, wirst du 10 Projekte mit React, Sass und D3.js umsetzen.", + "" + ], + [ + "//i.imgur.com/8v3t84p.jpg", + "Ein Screenshot von unserem Backend-Entwicklungszertifikat", + "Um unser Backend-Entwicklungszertifikat zu erhalten, wirst du 10 Projekte mit Node.js, Express und MongoDB umsetzen. Du wirst Git und Heroku verwenden um sie in der Cloud zu veröffentlichen.", + "" + ], + [ + "//i.imgur.com/yXyxbDd.jpg", + "Ein Screenshot von unserem Non-Profit-Verzeichnis", + "Nachdem du alle drei von diesen Zertifikaten abgeschlossen hast, wirst du mit einem anderen Camper zusammen Methoden der agilen Softwareentwicklung verwenden und zwei echte Projekte für Non-Profit-Organisationen umsetzen. Außerdem wirst du zwei bereits existierende Non-Profit-Projekte um neue Funktionalität erweitern. Wenn du fertig bist, wirst du ein Portfolio mit zwei echten Apps besitzen, die täglich von Leuten genutzt werden.", + "" + ], + [ + "//i.imgur.com/PDGQ9ZM.jpg", + "Ein Foto von Campern die zusammen in einem Cafe in Seoul an einem Projekt arbeiten.", + "Wenn du alle 2080 Stunden an Aufgaben und Projekten absolviert hast, hast du dir unser Full Stack Development Zertifikat verdient. Wir bieten dir dann ein gratis Bewerbungstraining an. Außerdem haben wir eine Jobbörse, wo Arbeitsgeber Camper einstellen die Free Code Camp Zertifikate erhalten haben.", + "" + ] ] }, { @@ -242,18 +317,18 @@ [ "//i.imgur.com/EAR7Lvh.jpg", "Gitterチャットルームの一場面です。", - "コーディングを始める前に、Free Code Camp のチャットルームに参加してください。いつでも、雑談や質問ができたりペアプログラミングをするための仲間を見つけ流ことができます。最初に Github アカウントが必要です。", + "コーディングを始める前に、Free Code Camp のチャットルームに参加してください。いつでも、雑談や質問ができたりペアプログラミングをするための仲間を見つけ流ことができます。最初に GitHub アカウントが必要です。", "" ], [ "//i.imgur.com/n6GeSEm.gif", - "この gif は Github を開始するまでの流れを表しています。必要な欄に情報を入れて登録をしてください。そして Github からあなたのメールアドレス宛にメールが届きますのでアカウントを承認してください。", - "\"Open link in new tab\"をクリックして Github を開いてください。 必要な欄に情報を入力して GitHub アカウントを作ってください。実際に使われている email アドレスかを確認してください( GitHub にはこの情報が保存されます )。メールアドレス宛に GitHub からメールが来たことを確認してください。 メールにある\"verify email address\"をクリックして開いてください。
注意: もしすでに GitHub アカウントを持っていたら、あなたは \"Open link in new tab\" をクリックすることでこのステップを飛ばすことができます、新しく開かれたタブを閉じて \"go to my next step\" をクリックしてください。私たちはこの大事なステップが飛ばされてしまうのを防ぐために \"このステップを飛ばす\" ボタンは削除してあります。
", + "この gif は GitHub を開始するまでの流れを表しています。必要な欄に情報を入れて登録をしてください。そして GitHub からあなたのメールアドレス宛にメールが届きますのでアカウントを承認してください。", + "\"Open link in new tab\"をクリックして GitHub を開いてください。 必要な欄に情報を入力して GitHub アカウントを作ってください。実際に使われている email アドレスかを確認してください( GitHub にはこの情報が保存されます )。メールアドレス宛に GitHub からメールが来たことを確認してください。 メールにある\"verify email address\"をクリックして開いてください。
注意: もしすでに GitHub アカウントを持っていたら、あなたは \"Open link in new tab\" をクリックすることでこのステップを飛ばすことができます、新しく開かれたタブを閉じて \"go to my next step\" をクリックしてください。私たちはこの大事なステップが飛ばされてしまうのを防ぐために \"このステップを飛ばす\" ボタンは削除してあります。
", "https://github.com/join" ], [ "//i.imgur.com/hFqAEr8.gif", - "この gif は Github の右上にあるプロフィール画像をクリックする方法です。あなたの写真をアップロードするか、自動で生成されるピクセルアートを利用してください。そして、残りの欄に情報を入力し submit ボタンを押してください。", + "この gif は GitHub の右上にあるプロフィール画像をクリックする方法です。あなたの写真をアップロードするか、自動で生成されるピクセルアートを利用してください。そして、残りの欄に情報を入力し submit ボタンを押してください。", "GitHub の右上に表示されているピクセルアートをクリックしてください、そして settings を選んでください。あなたの画像をアップロードしてください。画像はあなたの顔が写っていると良いです。他のキャンパーズの仲間たちがチャットルームであなたを見かけるようになります。住んでいる場所や名前を登録することもできます", "https://github.com/settings/profile" ], @@ -266,7 +341,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "この git は私たちのチャットルームへのリンクをクリックして、\"sign in with GitHub\" ボタンをクリックしています。そして、テキストを入力してキャンパーズの仲間へメッセージを送る方法を表しています。", - "あなたは Github のアカウントを持っているので、私たちのチャットルームへ GitHub を利用してログインできます。\"Hellow world!\" と言って自己紹介をし、あなたがどうやって Free Code Camp を見つけたかや何故プログラミングを学びたいのかを私たちに話してください。", + "あなたは GitHub のアカウントを持っているので、私たちのチャットルームへ GitHub を利用してログインできます。\"Hellow world!\" と言って自己紹介をし、あなたがどうやって Free Code Camp を見つけたかや何故プログラミングを学びたいのかを私たちに話してください。", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -470,6 +545,63 @@ ] ], "titleJa": "Githubアカウントを作成し、チャットに参加しましょう", + "titleDe": "Erstelle einen GitHub Account und tritt unserem Chat bei", + "descriptionDe": [ + [ + "//i.imgur.com/EAR7Lvh.jpg", + "Ein Screenshot von einem userer Gitter Chats.", + "Bevor wir zu programmieren beginnen, lass uns den Free Code Camp Chats beitreten. Hier kannst du zu jeder Tageszeit kommen, Fragen stellen oder einen anderen Camper suchen um gemeinsam zu programmieren. Doch zuerst benötigst du einen GitHub Account.", + "" + ], + [ + "//i.imgur.com/n6GeSEm.gif", + "Ein GIF das zeigt wie der unten stehenden Link angeklickt wird um auf GitHub zu kommen. Füll die notwendigen Felder aus und bestätige. Dann schau in deine Mails nach einer Nachricht von GitHub um deinen Account zu verifizieren.", + "Klicke unten auf den \"Link in neuem Tab öffnen\" Button um GitHub zu öffnen. Erstelle einen GitHub Account indem du die Felder in dem Formular ausfüllst. Überprüfe ob du deine echte Emailadresse verwendest - GitHub wird sie nicht weitergeben. Dann suche in deinem Posteingang nach einer Nachricht von GitHub. Öffne sie und klicke den darin befindenden \"Emailadresse bestätigen\" Button.
Hinweis: Wenn du bereits einen GitHub Account besitzt, kannst du diesen Schritt überspringen, indem du \"Link in neuem Tab öffnen\" drückst, den neuen Tab schließt und dann auf \"Gehe zu nächstem Schritt\" klickst. Wir haben den \"Schritt überspringen\" Button entfernt weil viele Leute sich einfach durchgeklickt haben ohne diese wichtigen Schritte zu tun
", + "https://github.com/join" + ], + [ + "//i.imgur.com/hFqAEr8.gif", + "Ein GIF das dir zeigt wie man sein Profilebild im rechten oberen Eck von GitHub anklickt. Lade ein Foto von dir hoch oder verwende weiterhin das automatisch generierte Pixelbild. Dann fülle die übrigen Formularfelder aus und klicke auf Bestätigung.", + "Klicke auf das Pixel-Art Bild in der rechten oberen Ecke von GitHub, dann gehe auf Einstellungen (settings). Lade ein Bild von dir hoch. Ein Foto von deinem Gesicht bietet sich am Besten an. So sehen dich die anderen Camper im Chat, also mach dich schick. Du kannst deine Stadt und deinen Namen hinzufügen, falls du willst.", + "https://github.com/settings/profile" + ], + [ + "//i.imgur.com/pYk0wOk.gif", + "Ein GIF das dir zeigt wie man einem GitHub Repository einen Stern gibt", + "Öffne Free Code Camp's open-source Repository. Hier arbeitet das ehrenamtliche Team zusammen an Free Code Camp. Du kannst unserem Repositoy einen Stern geben. Das ist das GitHub Äquivalent für etwas \"liken\"", + "https://github.com/freecodecamp/freecodecamp" + ], + [ + "//i.imgur.com/OmRmLB4.gif", + "Ein GIF das dir zeigt wie der unten stehende Link geklickt, auf den Chat weitergeleitet und mit dem \"Melde dich mit GitHub an\" Button man angemeldet wird. Dann kannst du auf das Textfeld klicken und eine Nachricht an andere Camper schicken", + "Jetzt, da du einen GitHub Account besitzt, kannst du unserem Hauptchat beitreten indem du dich mit GitHub anmeldest. Stell dich vor indem du \"Hello World\" schreibst. Erzähl den anderen Campern wie du Free Code Camp gefunden hast. Außerdem könntest du uns erzählen warum du programmieren lernen willst.", + "https://gitter.im/FreeCodeCamp/FreeCodeCamp" + ], + [ + "//i.imgur.com/Ecs5XAd.gif", + "Ein Gif das dir zeigt wie man den Einstellungsbutton im oberen rechten Eck anklickt und die Benachrichtigungseinstellungen ändert.", + "Unsere Chats sind sehr aktiv. Du solltest die Einstellungen ändern, damit du nur benachrichtigt wirst falls dich jemand erwähnt", + "" + ], + [ + "//i.imgur.com/T0bGJPe.gif", + "Ein GIF das dir zeigt wie man ein Profilbild von einem anderen User anklickt um eine private Nachricht zu versenden.", + "Sei dir bitte bewusst, dass alle unsere Chats komplett öffentlich sind. Falls du also sensible Informationen, wie zum Beispiel Emailadressen oder Telefonnummern, austauschen willst, verwende Privatnachrichten.", + "" + ], + [ + "//i.imgur.com/vDTMJSh.gif", + "Ein GIF das dir zeigt, dass du mithilfe mehrerer Tabs zwischen Aufgaben und dem Chat hin und her wechseln kannst", + "Halte den Chat offen, während du an den Aufgaben arbeitest. So kannst du jederzeit nach Hilfe fragen falls du nicht weiterkommst. Außerdem kannst du dich mit anderen Campern unterhalten falls du eine Pause brauchst.", + "" + ], + [ + "//i.imgur.com/WvQvNGN.gif", + "Ein GIF das dir zeigt wie du den den untenstehenden Link klickst um die native Chatapp für deinen Computer herunterzuladen.", + "Du kannst dir auch die Chatapp für deinen Computer oder dein Smartphone herunterladen.", + "https://gitter.im/apps" + ] + ], "challengeType": 7 }, { @@ -495,6 +627,24 @@ "Dale un vistazo de tu portafolio de código. Pulsa en tu imagen en la esquina superior derecha. Para activar tu portafolio de código, necesitaras conectar tu cuenta de GitHub con Free Code Camp. Tu portafolio de código muestra tu progreso y cuantos Puntos Cafés tienes. Puedes obtener Puntos Cafés completando desafíos y ayudando a otros campistas en nuestras salas de chat. Si obtienes Puntos Cafés varios días consecutivos, obtendrás una racha.", "" ] + ], + "titleDe": "Erstelle dein Code Portfolio", + "descriptionDe": [ + [ + "//i.imgur.com/tP2ccTE.gif", + "Ein GIF das dir zeigt wie man sein Profilbild in der rechten oberen Ecke anklickt um zu deinem Code Portfolio zu gelangen und mit GitHub zu verbinden", + "Schau dir dein Code Portfolio an. Klick auf dein Profilbild in der rechten oberen Ecke. Um dein Portfolio zu aktivieren musst du deinen GitHub Account mit Free Code Camp verbinden. Dein Code Portfolio zeigt deinen Fortschritt und wieviele Brownie Punkte du hast. Du bekommst Brownie Punkte wenn du Aufgaben löst oder anderen Campern im Chat hilfst. Wenn du an mehreren Tagen in Folge Brownie Punkte erhälst bekommst du einen \"streak\"", + "" + ] + ], + "titleFr": "Configurer votre code portefeuille", + "descriptionFr": [ + [ + "//i.imgur.com/tP2ccTE.gif", + "Un gif montrant comment vous pouvez cliquez sur l'image de votre profil dans votre coin supérieur droit à votre code portefeuille et connectez GitHub.", + "Vérifiez votre code portefeuille. Cliquez sur votre photo dans votre coin supérieur droit. Pour activer votre code portefeuille, vous'll nécessité de lier votre compte avec code sans GitHub Camp. Votre code portefeuille affiche votre progression et combien de bons points vous avez. Vous pouvez obtenir de bons points par remplir les défis et en aidant d'autres campeurs dans nos salles de chat. Si vous obtenez Brownie Points sur plusieurs jours d'affilée, vous'll obtenez une rayure.", + "" + ] ] }, { @@ -518,15 +668,6 @@ "tests": [], "type": "Waypoint", "challengeType": 7, - "titleFr": "Configurer votre code portefeuille", - "descriptionFr": [ - [ - "//i.imgur.com/tP2ccTE.gif", - "Un gif montrant comment vous pouvez cliquez sur l'image de votre profil dans votre coin supérieur droit à votre code portefeuille et connectez GitHub.", - "Vérifiez votre code portefeuille. Cliquez sur votre photo dans votre coin supérieur droit. Pour activer votre code portefeuille, vous'll nécessité de lier votre compte avec code sans GitHub Camp. Votre code portefeuille affiche votre progression et combien de bons points vous avez. Vous pouvez obtenir de bons points par remplir les défis et en aidant d'autres campeurs dans nos salles de chat. Si vous obtenez Brownie Points sur plusieurs jours d'affilée, vous'll obtenez une rayure.", - "" - ] - ], "titleEs": "Únete a un Campamento en Tu Ciudad", "descriptionEs": [ [ @@ -541,6 +682,21 @@ "Encuentra tu ciudad en esta lista y haz clic en esta. Esto te llevara al grupo de Facebook del Campamento de tu ciudad. Da clic en el botón de \"Unirse al grupo\" para unirte a el grupo. Alguien del mismo campamento debería aprobarte en breve. Si tu ciudad no esta en esta lista, ve al final del articulo de la wiki para ver instrucciones de como crear un campamento para tu ciudad.", "https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites" ] + ], + "titleDe": "Tritt einem Campsite in deiner Stadt bei", + "descriptionDe": [ + [ + "//i.imgur.com/XugIMb4.jpg", + "Ein Foto von einigen Campern bei einem Treffen in einem lokalen Cafe.", + "Unsere Campsites sind Facebook Gruppen die dir helfen dich mit anderen Campern aus deiner Stadt zu treffen. Du kannst diese Gruppen verwenden um an \"Coffee-and-Code\" Treffen, wo du andere Camper in einem Cafe triffst um gemeinsam zu programmieren, teilzunehmen oder zu organisieren", + "" + ], + [ + "//i.imgur.com/fTFMjwf.gif", + "Ein GIF das zeigt wie du auf den untenstehenden Link klickst, deine Stadt aus der Liste aller Campsites suchst, auf den Facebook Link klickst und der Facebook Gruppe beitrittst.", + "Finde deine Stadt auf dieser Liste und klick sie an. Du wirst auf die Facebook Gruppe des Campsites deiner Stadt geleitet. Klick den \"Gruppe beitreten\" Button um eine Beitrittsanfrage zu stellen. Jemand aus der Gruppe sollte dich in kürzester Zeit annehmen. Falls deine Stadt nicht auf der Liste ist, scrolle zum Ende des Wiki Artikels für eine Anleitung wie du ein Campsite für deine Stadt erstellst.", + "https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites" + ] ] }, { @@ -701,7 +857,59 @@ "Ahora estas listo para empezar a programar. El botón de \"Mapa\" en tu esquina superior derecha te mostrará nuestro mapa de desafíos. Te recomendaos que completes los desafíos de arriba hacía abajo, a un ritmo sostenible. Nuestra comunidad de código abierto esta constantemente mejorando nuestros desafíos, así que no te sorprendas si cambian o se mueven alrededor. No te preocupes por volver hacia atrás - solo continúa avanzando. Siempre puedes ir a tu desafío más reciente pulsando el botón de \"Aprender\".", "" ] + ], + "titleDe": "Lerne was du tun kannst falls du nicht weiterkommst", + "descriptionDe": [ + [ + "//i.imgur.com/lzKvwU2.jpg", + "Der Text \"Coding is hard.\"", + "Programmieren ist hart. Du wirst zeitweise nicht weiterkommen. Sogar erfahrene Programmierer bleiben manchmal hängen. Der Schlüssel zum Erfolg ist zu wissen wie man in so einer Situation weitermacht", + "" + ], + [ + "//i.imgur.com/sfsidp6.jpg", + "Der Text \"It takes time to get good at coding.\"", + "Es dauert seine Zeit bis man gut programmieren kann. Du erwartest auch nicht einen Schachmeister nach 3 Monaten Übung zu schlagen. Erwarte also auch nicht das nächste Facebook nach 3 Monaten zu programmieren", + "" + ], + [ + "//i.imgur.com/EoTfOyC.jpg", + "Ein Foto von einigen Campern die gemeinsam in Montreal programmieren.", + "Übe programmieren jeden Tag und triff dich mit anderen Leuten die programmieren, dann wirst du bereit für einen Programmierjob.", + "" + ], + [ + "//i.imgur.com/EWWZBag.jpg", + "Ein Bild mit dem Text \"1. Read the error 2. Search Google 3. Ask for help.", + "Wann immer du nicht weiterkommst oder nicht weißt was du als nächstes tun sollst: Lesen-Suchen-Fragen", + "" + ], + [ + "//i.imgur.com/99BfAcK.jpg", + "Ein Bild von der jQuery Dokumentation", + "Ließ zuerst die Dokumentation oder Fehlermeldung. Eine Schlüsselfähigkeit von guten Programmierern ist die ist die Fähigkeit zu interpretieren und dann Anweisungen zu folgen", + "" + ], + [ + "//i.imgur.com/GxvrsFb.gif", + "Ein GIF das eine erweiterte Google Suche zeigt. Zuerst wird die Suchanfrage \"jquery doesn't run when my page loads\" eingegeben. Dann wird in den Suchoptionen die Auswahl \"Beliebige Zeit\" zu \"Letztes Jahr\" geändert. Dann wird auf ein Ergebnis geklickt, der Artikel gelesen und die Antwort gefunden", + "Wenn das nicht geholfen hat, durchsuche Google. Gute Google Abfragen brauchen einiges an Übung. Wenn du Google durchsuchst, wirst du normalerweise die Programmiersprache oder das Framework, das du verwendest, inkludieren. Außerdem solltest du die Ergebnisse auf einen aktuellen Zeitraum limitieren.", + "" + ], + [ + "//i.imgur.com/LZYU7p2.gif", + "Ein GIF das zeigt wie der untenstehende Link aufgerufen wird um in den \"Help Chat\" zu kommen um dort zu fragen: \"jquery doesn't run when my page loads\".", + "Falls das nicht geholfen hat, frag deine Freunde. Wenn du Probleme hast kannst du die anderen Camper in unserem Hilfe Chat fragen.", + "https://gitter.im/FreeCodeCamp/Help" + ], + [ + "//i.imgur.com/ZRgXraT.gif", + "Ein GIF das zeigt wie durch die Challenge Übersicht gescrollt wird", + "Jetzt bist du bereit mit Programmieren zu starten. Der \"Map\" Button in der rechten oberen Ecke zeigt dir deine Challenge Übersicht. Wir empfehlen dir diese von Oben nach Unten in einer angemessenen Geschwindikeit durchzuführen. Unsere Open-Source Gemeinschaft ist permanent am Verbessern der Challenges, wundere dich also nicht falls diese sich ändern oder verschieben. Hab keine Angst davor zurück zu gehen - schau nur dass du vorankommst. Du kommst immer zu deiner aktuellsten Aufgabe indem du den \"Learn\" Button drückst.", + "" + ] ] + } ] } diff --git a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json index 6d1c486184..5ce1ff1abc 100644 --- a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json +++ b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json @@ -311,10 +311,11 @@ "id": "a2f1d72d9b908d0bd72bb9f6", "title": "Make a Person", "description": [ - "Fill in the object constructor with the methods specified in the tests.", - "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).", - "All functions that take an argument have an arity of 1, and the argument will be a string.", - "These methods must be the only available means for interacting with the object.", + "Fill in the object constructor with the following methods below:", + "
getFirstName()\ngetLastName()\ngetFullName()\nsetFirstName(first)\nsetLastName(last)\nsetFullName(firstAndLast)
", + "Run the tests to see the expected output for each method.", + "The methods that take an argument must accept only one argument and it has to be a string.", + "These methods must be the only available means of interacting with the object.", "Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code." ], "challengeSeed": [ @@ -350,11 +351,12 @@ "challengeType": 5, "titleEs": "Crea una Persona", "descriptionEs": [ - "Completa el constructor de objetos con los métodos especificados en las pruebas.", - "Los métodos son: getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), y setFullName(firstAndLast). ", - "Todas las funciones que aceptan un argumento tienen una aridad de 1, y el argumento es una cadena de texto", - "Estos métodos deben ser el único medio para interactuar con el objeto", - "Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." + "Completa el constructor de objetos con los métodos especificados a continuación:", + "
getFirstName()\ngetLastName()\ngetFullName()\nsetFirstName(first)\nsetLastName(last)\nsetFullName(firstAndLast)
", + "Ejecuta las pruebas para ver el resultado esperado de cada método.", + "Las funciones que aceptan argumentos deben aceptar sólo uno, y este tiene que ser una cadena.", + "Estos métodos deben ser el único medio para interactuar con el objeto.", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." ] }, { diff --git a/seed/challenges/01-front-end-development-certification/basic-javascript.json b/seed/challenges/01-front-end-development-certification/basic-javascript.json index c50be7961e..e10ae3470f 100644 --- a/seed/challenges/01-front-end-development-certification/basic-javascript.json +++ b/seed/challenges/01-front-end-development-certification/basic-javascript.json @@ -46,9 +46,9 @@ "id": "bd7123c9c443eddfaeb5bdef", "title": "Declare JavaScript Variables", "description": [ - "In computer science, data is anything that is meaningful to the computer. JavaScript provides seven different data types which are undefined, null, Boolean, string, symbol, number, and object.", + "In computer science, data is anything that is meaningful to the computer. JavaScript provides seven different data types which are undefined, null, Boolean, string, symbol, number, and object.", "For example, computers distinguish between numbers, such as the number 12, and strings, such as \"12\", \"dog\", or \"123 cats\", which are collections of characters. Computers can perform mathematical operations on a number, but not on a string.", - "Variables allow computers to store data in a dynamic fashion, rather than updating a formula every time the data changes. Any of the seven different data types may be stored in a variable.", + "Variables allow computers to store and manipulate data in a dynamic fashion. They do this by using a \"label\" to point to the data rather than using the data itself. Any of the seven data types may be stored in a variable.", "Variables are similar to the x and y variables you use in mathematics, which means they're a simple name to represent the data we want to refer to. Computer variables differ from mathematical variables in that they can store different values at different times.", "We tell JavaScript to create or declare a variable by putting the keyword var in front of it, like so:", "
var ourName;
", @@ -443,6 +443,7 @@ ], "tests": [ "assert(myVar === 88, 'message: myVar should equal 88');", + "assert(/myVar\\s*\\=.*myVar/.test(code) === false, 'message: myVar = myVar should be changed');", "assert(/myVar\\s*[+]{2}/.test(code), 'message: Use the ++ operator');", "assert(/var myVar = 87;/.test(code), 'message: Do not change code above the line');" ], @@ -853,22 +854,19 @@ "id": "56533eb9ac21ba0edf2244b3", "title": "Convert Celsius to Fahrenheit", "description": [ - "To test your learning you will create a solution \"from scratch\". Place your code between the indicated lines and it will be tested against multiple test cases.", - "The algorithm to convert from Celsius to Fahrenheit is the temperature in Celsius times 9/5, plus 32.", - "You are given a variable celsius representing a temperature in Celsius. Create a variable fahrenheit and apply the algorithm to assign it the corresponding temperature in Fahrenheit." + "To test your learning, you will create a solution \"from scratch\". Place your code between the indicated lines and it will be tested against multiple test cases.", + "The algorithm to convert from Celsius to Fahrenheit is the temperature in Celsius times 9/5, plus 32.", + "You are given a variable celsius representing a temperature in Celsius. Create a variable fahrenheit and apply the algorithm to assign it the corresponding temperature in Fahrenheit.", + "Note
Don't worry too much about the function and return statements as they will be covered in future challenges. For now, only use operators that you have already learned." ], "releasedOn": "January 1, 2016", "challengeSeed": [ "function convert(celsius) {", " // Only change code below this line", " ", - "", + " ", " // Only change code above this line", - " if ( typeof fahrenheit !== 'undefined' ) {", - " return fahrenheit;", - " } else {", - " return 'fahrenheit not defined';", - " }", + " return fahrenheit;", "}", "", "// Change the inputs below to test your code", @@ -2264,23 +2262,24 @@ "
function myTest() {
var loc = \"foo\";
console.log(loc);
}
myTest(); // \"foo\"
console.log(loc); // \"undefined\"
", "loc is not defined outside of the function.", "

Instructions

", - "Declare a local variable myVar inside myFunction" + "Declare a local variable myVar inside myFunction. Run the tests and then follow the instructions commented out in the editor.", + "Hint
Refreshing the page may help if you get stuck." ], "releasedOn": "January 1, 2016", "head": [ "var logOutput = \"\";", "var originalConsole = console", "function capture() {", - " var nativeLog = console.log;", - " console.log = function (message) {", - " logOutput = message;", - " if(nativeLog.apply) {", - " nativeLog.apply(originalConsole, arguments);", - " } else {", - " var nativeMsg = Array.prototype.slice.apply(arguments).join(' ');", - " nativeLog(nativeMsg);", - " }", - " };", + " var nativeLog = console.log;", + " console.log = function (message) {", + " logOutput = message;", + " if(nativeLog.apply) {", + " nativeLog.apply(originalConsole, arguments);", + " } else {", + " var nativeMsg = Array.prototype.slice.apply(arguments).join(' ');", + " nativeLog(nativeMsg);", + " }", + " };", "}", "", "function uncapture() {", @@ -2297,11 +2296,11 @@ "}", "myFunction();", "", - "// run and check the console ", + "// Run and check the console", "// myVar is not defined outside of myFunction", "console.log(myVar);", "", - "// now remove the console log line to pass the test", + "// Now remove the console log line to pass the test", "" ], "tail": [ @@ -3345,7 +3344,7 @@ "tests": [ "assert(code.match(/else/g).length > 3, 'message: You should have at least four else statements');", "assert(code.match(/if/g).length > 3, 'message: You should have at least four if statements');", - "assert(code.match(/return/g).length >= 5, 'message: You should have at least five return statements');", + "assert(code.match(/return/g).length >= 1, 'message: You should have at least one return statement');", "assert(myTest(0) === \"Tiny\", 'message: myTest(0) should return \"Tiny\"');", "assert(myTest(4) === \"Tiny\", 'message: myTest(4) should return \"Tiny\"');", "assert(myTest(5) === \"Small\", 'message: myTest(5) should return \"Small\"');", @@ -3778,6 +3777,7 @@ "assert((function(){ count = 0; cc(10);cc('J');cc('Q');cc('K');var out = cc('A'); if(out === \"-5 Hold\") {return true;} return false; })(), 'message: Cards Sequence 10, J, Q, K, A should return \"-5 Hold\"');", "assert((function(){ count = 0; cc(3);cc(7);cc('Q');cc(8);var out = cc('A'); if(out === \"-1 Hold\") {return true;} return false; })(), 'message: Cards Sequence 3, 7, Q, 8, A should return \"-1 Hold\"');", "assert((function(){ count = 0; cc(2);cc('J');cc(9);cc(2);var out = cc(7); if(out === \"1 Bet\") {return true;} return false; })(), 'message: Cards Sequence 2, J, 9, 2, 7 should return \"1 Bet\"');", + "assert((function(){ count = 0; cc(2);cc(2);var out = cc(10); if(out === \"1 Bet\") {return true;} return false; })(), 'message: Cards Sequence 2, 2, 10 should return \"1 Bet\"');", "assert((function(){ count = 0; cc(3);cc(2);cc('A');cc(10);var out = cc('K'); if(out === \"-1 Hold\") {return true;} return false; })(), 'message: Cards Sequence 3, 2, A, 10, K should return \"-1 Hold\"');" ], "type": "checkpoint", diff --git a/seed/challenges/01-front-end-development-certification/bootstrap.json b/seed/challenges/01-front-end-development-certification/bootstrap.json index 3cf9d1bb58..06578ee939 100644 --- a/seed/challenges/01-front-end-development-certification/bootstrap.json +++ b/seed/challenges/01-front-end-development-certification/bootstrap.json @@ -104,102 +104,12 @@ "id": "bad87fee1348bd9acde08812", "title": "Make Images Mobile Responsive", "description": [ - "First, add a new image below the existing one. Set its src attribute to http://bit.ly/fcc-running-cats.", + "First, add a new image below the existing one. Set its src attribute to https://bit.ly/fcc-running-cats.", "It would be great if this image could be exactly the width of our phone's screen.", "Fortunately, with Bootstrap, all we need to do is add the img-responsive class to your image. Do this, and the image should perfectly fit the width of your page." ], "challengeSeed": [ - "", - "", - "", - "
", - "

CatPhotoApp

", - "", - "

Click here for cat photos.

", - "", - " ", - "", - "

Things cats love:

", - "
    ", - "
  • cat nip
  • ", - "
  • laser pointers
  • ", - "
  • lasagna
  • ", - "
", - "

Top 3 things cats hate:

", - "
    ", - "
  1. flea treatment
  2. ", - "
  3. thunder
  4. ", - "
  5. other cats
  6. ", - "
", - "
", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - "
", - "
" - ], - "tests": [ - "assert($(\"img\").length === 2, 'message: You should have a total of two images.');", - "assert($(\"img:eq(1)\").hasClass(\"img-responsive\"), 'message: Your new image should be below your old one and have the class img-responsive.');", - "assert(!$(\"img:eq(1)\").hasClass(\"smaller-image\"), 'message: Your new image should not have the class smaller-image.');", - "assert($(\"img:eq(1)\").attr(\"src\") === \"http://bit.ly/fcc-running-cats\", 'message: Your new image should have a src of http://bit.ly/fcc-running-cats.');", - "assert(code.match(//g).length === 2 && code.match(/img element has a closing angle bracket.');" - ], - "type": "waypoint", - "challengeType": 0, - "titleEs": "Haz que las imágenes sean adaptativas en dispositivos móviles", - "descriptionEs": [ - "Primero, agrega una nueva imagen debajo que la que ya existe. Haz que su atributo src sea http://bit.ly/fcc-running-cats.", - "Sería genial si esta imagen fuera exactamente del tamaño de la pantalla de nuestro teléfono.", - "Afortunadamente, con Bootstrap, todo lo que tenemos que hacer es agregar la clase img-responsive a tu imagen. Hazlo, y verás que la imagen se ajustará perfectamente al ancho de tu página." - ], - "nameFr": "Rendre des images adaptatives aux appareils mobiles", - "descriptionFr": [ - "It would be great if this image could be exactly the width of our phone's screen.", - "Fortunately, with Bootstrap, all we need to do is add the img-responsive class to your image. Do this, and the image should perfectly fit the width of your page.", - "D'abord, ajoutez une nouvelle image en dessous de celle qui eiste dejà. Changez l'attribut src en http://bit.ly/fcc-running-cats.", - "Ce serait absolument super si notre image pouvait être exactement de la largeur de l'écran du téléphone.", - "Heureusement, avec Bootstrap, il faut seulement ajouter la classe img-responsive à notre image. Faites le, et l'image devrait s'ajuster parfaitement à la largeur de la page." - ] - }, - { - "id": "bad87fee1348bd8acde08812", - "title": "Center Text with Bootstrap", - "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 text-center to our h2 element.", - "Remember that you can add several classes to the same element by separating each of them with a space, like this:", - "<h2 class=\"red-text text-center\">your text</h2>" - ], - "challengeSeed": [ - "", + "", "", + "", + "
", + "

CatPhotoApp

", + "", + "

Click here for cat photos.

", + "", + " ", + "", + " ", "

Things cats love:

", "
    ", "
  • cat nip
  • ", @@ -284,7 +284,7 @@ "Create a new button element below your large kitten photo. Give it the class btn and the text of \"Like\"." ], "challengeSeed": [ - "", + "", "