From 2d7b6eb1452f30f03b48298f52249baff61eb6ff Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 20:12:59 -0700 Subject: [PATCH 01/14] Updated code language logos. Added code language blurb i18n tags. --- .../images/common/code_languages/c_icon.png | Bin 0 -> 3108 bytes .../common/code_languages/clojure_icon.png | Bin 0 -> 3094 bytes .../code_languages/clojure_small.png} | Bin .../code_languages/coffeescript_icon.png | Bin 0 -> 3018 bytes .../code_languages/coffeescript_small.png} | Bin .../images/common/code_languages/cpp_icon.png | Bin 0 -> 3093 bytes .../common/code_languages/csharp_icon.png | Bin 0 -> 3077 bytes .../images/common/code_languages/go_icon.png | Bin 0 -> 2983 bytes .../images/common/code_languages/io_icon.png | Bin 0 -> 4113 bytes .../code_languages/io_small.png} | Bin .../common/code_languages/java_icon.png | Bin 0 -> 3105 bytes .../common/code_languages/javascript_icon.png | Bin 0 -> 3976 bytes .../code_languages/javascript_small.png} | Bin .../images/common/code_languages/lua_icon.png | Bin 0 -> 2917 bytes .../code_languages/lua_small.png} | Bin .../images/common/code_languages/php_icon.png | Bin 0 -> 3020 bytes .../common/code_languages/python_icon.png | Bin 0 -> 3008 bytes .../code_languages/python_small.png} | Bin .../common/code_languages/ruby_icon.png | Bin 0 -> 3073 bytes .../common/code_languages/swift_icon.png | Bin 0 -> 2961 bytes app/locale/en.coffee | 6 ++++ app/styles/home.sass | 17 ++++++++--- app/styles/play/ladder/ladder_tab.sass | 5 ++-- app/styles/play/ladder/my_matches_tab.sass | 5 ++-- app/styles/play/ladder/play_modal.sass | 10 +++---- app/styles/play/level/tome/spell_palette.sass | 28 +++++++++++------- app/templates/home.jade | 12 ++++---- app/templates/play/ladder/ladder_tab.jade | 4 +-- app/templates/play/ladder/my_matches_tab.jade | 2 +- app/templates/play/ladder/play_modal.jade | 8 ++--- app/views/home_view.coffee | 2 +- 31 files changed, 59 insertions(+), 40 deletions(-) create mode 100755 app/assets/images/common/code_languages/c_icon.png create mode 100755 app/assets/images/common/code_languages/clojure_icon.png rename app/assets/images/{pages/home/language_logo_clojure.png => common/code_languages/clojure_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/coffeescript_icon.png rename app/assets/images/{pages/home/language_logo_coffeescript.png => common/code_languages/coffeescript_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/cpp_icon.png create mode 100755 app/assets/images/common/code_languages/csharp_icon.png create mode 100755 app/assets/images/common/code_languages/go_icon.png create mode 100644 app/assets/images/common/code_languages/io_icon.png rename app/assets/images/{pages/home/language_logo_io.png => common/code_languages/io_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/java_icon.png create mode 100644 app/assets/images/common/code_languages/javascript_icon.png rename app/assets/images/{pages/home/language_logo_javascript.png => common/code_languages/javascript_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/lua_icon.png rename app/assets/images/{pages/home/language_logo_lua.png => common/code_languages/lua_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/php_icon.png create mode 100755 app/assets/images/common/code_languages/python_icon.png rename app/assets/images/{pages/home/language_logo_python.png => common/code_languages/python_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/ruby_icon.png create mode 100755 app/assets/images/common/code_languages/swift_icon.png diff --git a/app/assets/images/common/code_languages/c_icon.png b/app/assets/images/common/code_languages/c_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..99cd55241df4b94612ea0f61f6984561304c52cf GIT binary patch literal 3108 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/clojure_icon.png b/app/assets/images/common/code_languages/clojure_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..7152f84c0ca9f772194cf8da1a4ae67426686d9a GIT binary patch literal 3094 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_clojure.png b/app/assets/images/common/code_languages/clojure_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_clojure.png rename to app/assets/images/common/code_languages/clojure_small.png diff --git a/app/assets/images/common/code_languages/coffeescript_icon.png b/app/assets/images/common/code_languages/coffeescript_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..502db9b06bc3af2ad3060afe03588aba55619110 GIT binary patch literal 3018 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 M07*qoM6N<$f)%@!EC2ui literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_coffeescript.png b/app/assets/images/common/code_languages/coffeescript_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_coffeescript.png rename to app/assets/images/common/code_languages/coffeescript_small.png diff --git a/app/assets/images/common/code_languages/cpp_icon.png b/app/assets/images/common/code_languages/cpp_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..c3067378cca155e9e81de53c6adf38e294f1c2cb GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/csharp_icon.png b/app/assets/images/common/code_languages/csharp_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..d3eff9260c6f09acaddc205ec7c31d94fc67128e GIT binary patch literal 3077 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 Tlxi+a00000NkvXXu0mjfW<0v? literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/go_icon.png b/app/assets/images/common/code_languages/go_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..ecbfb0d6ab769009983d760404a64aa92b6363d5 GIT binary patch literal 2983 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/io_icon.png b/app/assets/images/common/code_languages/io_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6c58fe4eafcd179cb0df77a7fe4123a42c8903 GIT binary patch literal 4113 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_io.png b/app/assets/images/common/code_languages/io_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_io.png rename to app/assets/images/common/code_languages/io_small.png diff --git a/app/assets/images/common/code_languages/java_icon.png b/app/assets/images/common/code_languages/java_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e39879caeb661b8ae5d8f969991c3f49ee21ccaa GIT binary patch literal 3105 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/javascript_icon.png b/app/assets/images/common/code_languages/javascript_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4580f350b4b9412f0dbd539340325962c5bbba0e GIT binary patch literal 3976 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 F{{(R7Ih+6h literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_javascript.png b/app/assets/images/common/code_languages/javascript_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_javascript.png rename to app/assets/images/common/code_languages/javascript_small.png diff --git a/app/assets/images/common/code_languages/lua_icon.png b/app/assets/images/common/code_languages/lua_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e97873a331f62e51f94b8fa374a596233ebf6510 GIT binary patch literal 2917 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 P00000NkvXXu0mjfDMxEp literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_lua.png b/app/assets/images/common/code_languages/lua_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_lua.png rename to app/assets/images/common/code_languages/lua_small.png diff --git a/app/assets/images/common/code_languages/php_icon.png b/app/assets/images/common/code_languages/php_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..35757de0b61b2f778df0e3ef459938f74ef5f350 GIT binary patch literal 3020 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 O0000<MNUMnLSTYoi=V{+ literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/python_icon.png b/app/assets/images/common/code_languages/python_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..b8575c4f842679491f5c631b62a76d18062200c6 GIT binary patch literal 3008 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 CK##fr literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_python.png b/app/assets/images/common/code_languages/python_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_python.png rename to app/assets/images/common/code_languages/python_small.png diff --git a/app/assets/images/common/code_languages/ruby_icon.png b/app/assets/images/common/code_languages/ruby_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..7e1192d7abf52cba6f1f82b272051b79c867ed81 GIT binary patch literal 3073 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 P00000NkvXXu0mjfD=f2y literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/swift_icon.png b/app/assets/images/common/code_languages/swift_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e789c15168232d60bb83864e1699406a9b6fbe0c GIT binary patch literal 2961 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 Hu0mjfcJg_# literal 0 HcmV?d00001 diff --git a/app/locale/en.coffee b/app/locale/en.coffee index a3cf8152b..2b8549b5e 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -100,6 +100,12 @@ for_beginners: "For Beginners" multiplayer: "Multiplayer" for_developers: "For Developers" + javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." + python_blurb: "Simple yet powerful, Python is a great general purpose programming language." + coffeescript_blurb: "Nicer JavaScript syntax." + clojure_blurb: "A modern Lisp." + lua_blurb: "Game scripting language." + io_blurb: "Simple but obscure." play: choose_your_level: "Choose Your Level" diff --git a/app/styles/home.sass b/app/styles/home.sass index c58133fb8..f5abd9c0f 100644 --- a/app/styles/home.sass +++ b/app/styles/home.sass @@ -167,6 +167,10 @@ h2 margin: 15px 0 5px + p + overflow: hidden + height: 40px + .secondary-code-languages margin-left: -10px @@ -201,17 +205,22 @@ margin: 0 padding: 0 + p + white-space: nowrap + text-overflow: ellipsis + overflow: hidden + #coffeescript .code-language-logo - background: transparent url(/images/pages/home/language_logo_coffeescript.png) no-repeat center + background: transparent url(/images/common/code_languages/coffeescript_small.png) no-repeat center #clojure .code-language-logo - background: transparent url(/images/pages/home/language_logo_clojure.png) no-repeat center + background: transparent url(/images/common/code_languages/clojure_small.png) no-repeat center #lua .code-language-logo - background: transparent url(/images/pages/home/language_logo_lua.png) no-repeat center + background: transparent url(/images/common/code_languages/lua_small.png) no-repeat center #io .code-language-logo - background: transparent url(/images/pages/home/language_logo_io.png) no-repeat center + background: transparent url(/images/common/code_languages/io_small.png) no-repeat center #multiplayer-launch-modal diff --git a/app/styles/play/ladder/ladder_tab.sass b/app/styles/play/ladder/ladder_tab.sass index c92726c9c..2529f6280 100644 --- a/app/styles/play/ladder/ladder_tab.sass +++ b/app/styles/play/ladder/ladder_tab.sass @@ -53,6 +53,5 @@ .code-language-cell padding: 0 10px - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center - background-size: contain - height: 19px + background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center + height: 16px diff --git a/app/styles/play/ladder/my_matches_tab.sass b/app/styles/play/ladder/my_matches_tab.sass index 741a3a534..13aca340d 100644 --- a/app/styles/play/ladder/my_matches_tab.sass +++ b/app/styles/play/ladder/my_matches_tab.sass @@ -40,6 +40,5 @@ .code-language-cell padding: 0 10px - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center - background-size: contain - height: 19px + background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center + height: 16px diff --git a/app/styles/play/ladder/play_modal.sass b/app/styles/play/ladder/play_modal.sass index 3587c557f..6050df159 100644 --- a/app/styles/play/ladder/play_modal.sass +++ b/app/styles/play/ladder/play_modal.sass @@ -98,12 +98,12 @@ .code-language position: absolute - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center + background: transparent url(/images/common/code_languages/javascript_small.png) no-repeat center center background-size: contain - width: 40px - height: 40px - right: -5px - top: -15px + width: 50px + height: 50px + right: -0px + top: -30px display: block .my-name diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass index 3e2f78794..6c5a12f32 100644 --- a/app/styles/play/level/tome/spell_palette.sass +++ b/app/styles/play/level/tome/spell_palette.sass @@ -70,10 +70,10 @@ .code-language-logo position: absolute - width: 20px - height: 20px - left: 12px - top: 34px + width: 16px + height: 16px + left: 16px + top: 36px z-index: 10 background-color: transparent background-repeat: no-repeat @@ -81,21 +81,27 @@ cursor: pointer &.javascript - background-image: url(/images/pages/home/language_logo_javascript.png) + background-image: url(/images/common/code_languages/javascript_icon.png) &.python - background-image: url(/images/pages/home/language_logo_python.png) + background-image: url(/images/common/code_languages/python_icon.png) &.coffeescript - background-image: url(/images/pages/home/language_logo_coffeescript.png) + background-image: url(/images/common/code_languages/coffeescript_icon.png) &.clojure - background-image: url(/images/pages/home/language_logo_clojure.png) + background-image: url(/images/common/code_languages/clojure_icon.png) &.lua - background-image: url(/images/pages/home/language_logo_lua.png) + background-image: url(/images/common/code_languages/lua_icon.png) &.io - background-image: url(/images/pages/home/language_logo_io.png) + background-image: url(/images/common/code_languages/io_icon.png) + + &:hover + outline: 1px outset #ccc + + &:active + outline: 1px inset #ccc html.no-borderimage #spell-palette-view span.code-palette-background display: none img.code-palette-background - display: block \ No newline at end of file + display: block diff --git a/app/templates/home.jade b/app/templates/home.jade index 02775696a..6d9d939df 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -10,14 +10,14 @@ block content .code-language#javascript(data-code-language='javascript') .code-wizard h2 JavaScript - p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. + p(data-i18n="home.javascript_blurb") The language of the web. Great for writing websites, web apps, HTML5 games, and servers. .col-md-6 .code-language.beta#python(data-code-language='python') .code-wizard .code-language-beta h2 Python - p Simple yet powerful, Python is a great general purpose programming language. + p(data-i18n="home.python_blurb") Simple yet powerful, Python is a great general purpose programming language. .secondary-code-languages.row .col-md-3 @@ -26,7 +26,7 @@ block content .code-wizard .code-language-beta h3 CoffeeScript - p Nicer JavaScript syntax + p(data-i18n="home.coffeescript_blurb") Nicer JavaScript syntax. .col-md-3 .code-language.beta#clojure(data-code-language='clojure') @@ -34,7 +34,7 @@ block content .code-wizard .code-language-beta h3 Clojure - p A modern Lisp + p(data-i18n="home.clojure_blurb") A modern Lisp. .col-md-3 .code-language.beta#lua(data-code-language='lua') @@ -42,7 +42,7 @@ block content .code-wizard .code-language-beta h3 Lua - p Game scripting language + p(data-i18n="home.lua_blurb") Game scripting language. .col-md-3 .code-language.beta#io(data-code-language='io', title="Careful: Io is still quite buggy") @@ -50,7 +50,7 @@ block content .code-wizard .code-language-beta h3 Io - p Simple but obscure + p(data-i18n="home.io_blurb") Simple but obscure. .alert.alert-danger.lt-ie10 strong(data-i18n="home.no_ie") CodeCombat does not run in Internet Explorer 9 or older. Sorry! diff --git a/app/templates/play/ladder/ladder_tab.jade b/app/templates/play/ladder/ladder_tab.jade index 4d682243a..515397e1f 100644 --- a/app/templates/play/ladder/ladder_tab.jade +++ b/app/templates/play/ladder/ladder_tab.jade @@ -21,7 +21,7 @@ div#columns.row for session, rank in topSessions - var myRow = session.get('creator') == me.id tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id) - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)") td.rank-cell= rank + 1 td.score-cell= Math.round(session.get('totalScore') * 100) td.name-col-cell= session.get('creatorName') || "Anonymous" @@ -35,7 +35,7 @@ div#columns.row for session in team.leaderboard.nearbySessions() - var myRow = session.get('creator') == me.id tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id) - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)") td.rank-cell= session.rank td.score-cell= Math.round(session.get('totalScore') * 100) td.name-col-cell= session.get('creatorName') || "Anonymous" diff --git a/app/templates/play/ladder/my_matches_tab.jade b/app/templates/play/ladder/my_matches_tab.jade index a08f6651b..bf4d9e856 100644 --- a/app/templates/play/ladder/my_matches_tab.jade +++ b/app/templates/play/ladder/my_matches_tab.jade @@ -39,7 +39,7 @@ div#columns.row span(data-i18n="general.loss").loss Loss if match.state === 'tie' span(data-i18n="general.tie").tie Tie - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + match.codeLanguage + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + match.codeLanguage + "_icon.png)") td.name-cell= match.opponentName || "Anonymous" td.time-cell= match.when td.battle-cell diff --git a/app/templates/play/ladder/play_modal.jade b/app/templates/play/ladder/play_modal.jade index 841203b2f..c25c3a1f5 100644 --- a/app/templates/play/ladder/play_modal.jade +++ b/app/templates/play/ladder/play_modal.jade @@ -33,7 +33,7 @@ block modal-body-content span= myName div.opponent-name.name-label span(data-i18n="ladder.simple_ai") Simple AI - //span.code-language(style="background-image: url(/images/pages/home/language_logo_javascript.png)") + //span.code-language(style="background-image: url(/images/common/code_languages/javascript_small.png)") div.difficulty span(data-i18n="ladder.warmup") Warmup div(data-i18n="ladder.vs").vs VS @@ -50,7 +50,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.easy.opponentName if challengers.easy.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.easy.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.easy.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.easy") Easy div(data-i18n="ladder.vs").vs VS @@ -67,7 +67,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.medium.opponentName if challengers.medium.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.medium.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.medium.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.medium") Medium div(data-i18n="ladder.vs").vs VS @@ -84,7 +84,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.hard.opponentName if challengers.hard.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.hard.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.hard.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.hard") Hard div(data-i18n="ladder.vs").vs VS diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index 40eb72e88..ff3b287c2 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -52,7 +52,7 @@ module.exports = class HomeView extends View @updateLanguageLogos codeLanguage updateLanguageLogos: (codeLanguage) -> - @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/pages/home/language_logo_#{codeLanguage}.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) + @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) onCodeLanguageSelected: (e) -> target = $(e.target).closest('.code-language') From 207f0adf11e8b7b8d963b4ba816786b60c40f443 Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 20:13:30 -0700 Subject: [PATCH 02/14] Propagated i18n tags for code language blurbs. --- app/locale/ar.coffee | 6 ++++++ app/locale/bg.coffee | 6 ++++++ app/locale/ca.coffee | 6 ++++++ app/locale/cs.coffee | 6 ++++++ app/locale/da.coffee | 6 ++++++ app/locale/de-AT.coffee | 6 ++++++ app/locale/de-CH.coffee | 6 ++++++ app/locale/de-DE.coffee | 6 ++++++ app/locale/de.coffee | 6 ++++++ app/locale/el.coffee | 6 ++++++ app/locale/en-AU.coffee | 6 ++++++ app/locale/en-GB.coffee | 6 ++++++ app/locale/en-US.coffee | 6 ++++++ app/locale/es-419.coffee | 6 ++++++ app/locale/es-ES.coffee | 6 ++++++ app/locale/es.coffee | 6 ++++++ app/locale/fa.coffee | 6 ++++++ app/locale/fi.coffee | 6 ++++++ app/locale/fr.coffee | 6 ++++++ app/locale/he.coffee | 6 ++++++ app/locale/hi.coffee | 6 ++++++ app/locale/hu.coffee | 6 ++++++ app/locale/id.coffee | 6 ++++++ app/locale/it.coffee | 6 ++++++ app/locale/ja.coffee | 6 ++++++ app/locale/ko.coffee | 6 ++++++ app/locale/lt.coffee | 6 ++++++ app/locale/ms.coffee | 6 ++++++ app/locale/nb.coffee | 6 ++++++ app/locale/nl-BE.coffee | 6 ++++++ app/locale/nl-NL.coffee | 6 ++++++ app/locale/nl.coffee | 6 ++++++ app/locale/nn.coffee | 6 ++++++ app/locale/no.coffee | 6 ++++++ app/locale/pl.coffee | 6 ++++++ app/locale/pt-BR.coffee | 6 ++++++ app/locale/pt-PT.coffee | 6 ++++++ app/locale/pt.coffee | 6 ++++++ app/locale/ro.coffee | 6 ++++++ app/locale/ru.coffee | 6 ++++++ app/locale/sk.coffee | 6 ++++++ app/locale/sl.coffee | 6 ++++++ app/locale/sr.coffee | 6 ++++++ app/locale/sv.coffee | 6 ++++++ app/locale/th.coffee | 6 ++++++ app/locale/tr.coffee | 6 ++++++ app/locale/uk.coffee | 6 ++++++ app/locale/ur.coffee | 6 ++++++ app/locale/vi.coffee | 6 ++++++ app/locale/zh-HANS.coffee | 6 ++++++ app/locale/zh-HANT.coffee | 6 ++++++ app/locale/zh-WUU-HANS.coffee | 6 ++++++ app/locale/zh-WUU-HANT.coffee | 6 ++++++ app/locale/zh.coffee | 6 ++++++ 54 files changed, 324 insertions(+) diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee index 0d95ef171..40f349b61 100644 --- a/app/locale/ar.coffee +++ b/app/locale/ar.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index 5620a6b60..0609ffaf8 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "български език", englishDescri # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Избери своето ниво" diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index 3a1a35800..0ab50115a 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr for_beginners: "Per a principiants" multiplayer: "Multijugador" for_developers: "Per a Desenvolupadors" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escull el teu nivell" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index 5836d1889..cd470a43b 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Zvolte si úroveň" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index 470764cd8..1ffef227c 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans for_beginners: "For Begyndere" multiplayer: "Multiplayer" for_developers: "For Udviklere" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Vælg Dit Level" diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee index 1242212fd..9c4c0c144 100644 --- a/app/locale/de-AT.coffee +++ b/app/locale/de-AT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription: # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee index b8b40dbac..d83d4959a 100644 --- a/app/locale/de-CH.coffee +++ b/app/locale/de-CH.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge for_beginners: "Für Afänger" multiplayer: "Multiplayer" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähl dis Level us" diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee index 69570107d..d94fbbbfd 100644 --- a/app/locale/de-DE.coffee +++ b/app/locale/de-DE.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription: for_beginners: "Für Anfänger" multiplayer: "Mehrspieler" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähle dein Level" diff --git a/app/locale/de.coffee b/app/locale/de.coffee index 4f83a118e..aa72ab375 100644 --- a/app/locale/de.coffee +++ b/app/locale/de.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra for_beginners: "Für Anfänger" multiplayer: "Mehrspieler" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähle dein Level" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index 41d735d5d..0405a50f3 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre for_beginners: "Για αρχάριους" # multiplayer: "Multiplayer" for_developers: "Για προγραμματιστές" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Διάλεξε την πίστα σου" diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee index 29d87cbe7..772111136 100644 --- a/app/locale/en-AU.coffee +++ b/app/locale/en-AU.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee index 0ba3466cc..e6fadc26e 100644 --- a/app/locale/en-GB.coffee +++ b/app/locale/en-GB.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee index ebecb2bd2..61513d098 100644 --- a/app/locale/en-US.coffee +++ b/app/locale/en-US.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 84d5ddd86..6d4b7892c 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip for_beginners: "Para Principiantes" multiplayer: "Multijugador" for_developers: "Para Desarrolladores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index 565025b19..956682ba2 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis for_beginners: "Para principiantes" multiplayer: "Multijugador" for_developers: "Para programadores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/es.coffee b/app/locale/es.coffee index dcc2e7ff1..3382d263f 100644 --- a/app/locale/es.coffee +++ b/app/locale/es.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t for_beginners: "Para principiantes" multiplayer: "Multijugador" for_developers: "Para desarrolladores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index e043269ae..5643e4646 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "مرحله خود را انتخاب کنید" diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee index cd1da3699..d045279e8 100644 --- a/app/locale/fi.coffee +++ b/app/locale/fi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index 94a3dd46d..1d717c739 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "français", englishDescription: "French", t for_beginners: "Pour débutants" multiplayer: "Multijoueurs" for_developers: "Pour développeurs" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Choisissez votre niveau" diff --git a/app/locale/he.coffee b/app/locale/he.coffee index 7dda67ac8..4621f2dce 100644 --- a/app/locale/he.coffee +++ b/app/locale/he.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", for_beginners: "למתחילים" multiplayer: "רב-משתתפים" for_developers: "למומחים" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "בחר את השלב" diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee index 85ccf7dac..ca51ba569 100644 --- a/app/locale/hi.coffee +++ b/app/locale/hi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 2aef84d38..390e20a98 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t for_beginners: "Kezdőknek" # multiplayer: "Multiplayer" for_developers: "Fejlesztőknek" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Válaszd ki a pályát!" diff --git a/app/locale/id.coffee b/app/locale/id.coffee index ae972660d..fe9958166 100644 --- a/app/locale/id.coffee +++ b/app/locale/id.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index e1535c040..a1ed0fbaf 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t for_beginners: "Per Principianti" # multiplayer: "Multiplayer" for_developers: "Per Sviluppatori" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Scegli il tuo livello" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index fce997c9a..acdc9ffb6 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", for_beginners: "初心者向け" multiplayer: "マルチプレイヤー" for_developers: "開発者向け" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "レベル選択" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index 791630d0e..fdc645eb4 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t for_beginners: "초보자용" multiplayer: "멀티플레이어" for_developers: "개발자용" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "레벨을 선택하세요." diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee index dd8420fff..c34b07ae6 100644 --- a/app/locale/lt.coffee +++ b/app/locale/lt.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee index 7149e3b19..62d60bdb5 100644 --- a/app/locale/ms.coffee +++ b/app/locale/ms.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index 855b05b2b..cfcf2cd07 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Velg Ditt Nivå" diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee index 42221b38d..20eef3d90 100644 --- a/app/locale/nl-BE.coffee +++ b/app/locale/nl-BE.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription: for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee index f54d02efd..5db7557ee 100644 --- a/app/locale/nl-NL.coffee +++ b/app/locale/nl-NL.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee index 74b8c35b4..0fccad1af 100644 --- a/app/locale/nl.coffee +++ b/app/locale/nl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee index c7e58789f..180420e6a 100644 --- a/app/locale/nn.coffee +++ b/app/locale/nn.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/no.coffee b/app/locale/no.coffee index 4085d5128..d319665ee 100644 --- a/app/locale/no.coffee +++ b/app/locale/no.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Velg Ditt Nivå" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index 6cbdc2007..a047b1f31 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish for_beginners: "Dla początkujących" # multiplayer: "Multiplayer" for_developers: "Dla developerów" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wybierz poziom" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index f7758b9be..21ef4fcf3 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Desenvolvedores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha seu estágio" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index ec504f6db..9e51664d6 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha o Seu Nível" diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee index ea24890d3..e69e86463 100644 --- a/app/locale/pt.coffee +++ b/app/locale/pt.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha seu estágio" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index baefa15fb..145382ca0 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman for_beginners: "Pentru Începători" multiplayer: "Multiplayer" for_developers: "Pentru dezvoltatori" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Alege nivelul" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 9ac956a4d..cb96b0e6e 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi for_beginners: "Новичкам" multiplayer: "Мультиплеер" for_developers: "Разработчикам" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Выберите ваш уровень" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 20be15ee8..135b8acf0 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", for_beginners: "Pre začiatočníkov" # multiplayer: "Multiplayer" for_developers: "Pre vývojárov" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Vyber si úroveň" diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee index 73c8947f7..6517ac37d 100644 --- a/app/locale/sl.coffee +++ b/app/locale/sl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index 4b748189c..ae0508b0f 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Изабери ниво" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index ac9d04d87..1e6356c4f 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr for_beginners: "För nybörjare" multiplayer: "Flera spelare" for_developers: "För utvecklare" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Välj din nivå" diff --git a/app/locale/th.coffee b/app/locale/th.coffee index debe63e0f..0ffadebae 100644 --- a/app/locale/th.coffee +++ b/app/locale/th.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index 83596230d..6c52344fa 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t for_beginners: "Yeni Başlayanlar için" multiplayer: "Çoklu-oyuncu Modu" for_developers: "Geliştiriciler için" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Seviye Seçimi" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index beb7659ec..65c15f9c3 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "українська мова", englishDesc for_beginners: "Для новачків" multiplayer: "Командна гра" for_developers: "Для розробників" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Оберіть свій рівень" diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee index a0ca20473..9672ccdbd 100644 --- a/app/locale/ur.coffee +++ b/app/locale/ur.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu", # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 55bf539c7..f58f20fb4 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Chọn Trình của bạn" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index 665af4c82..7523c69af 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese for_beginners: "适合初学者" multiplayer: "多人游戏" for_developers: "适合开发者" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "选择关卡" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index 96a11fc42..b4a96e647 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "選取關卡" diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee index 5d5a8c757..ea129d982 100644 --- a/app/locale/zh-WUU-HANS.coffee +++ b/app/locale/zh-WUU-HANS.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee index 6fdb7dd26..361a86c11 100644 --- a/app/locale/zh-WUU-HANT.coffee +++ b/app/locale/zh-WUU-HANT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio for_beginners: "適合學起頭個人" multiplayer: "聚隊打遊戲" for_developers: "適合開發個人" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "揀關數" diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee index 7a2b8c97e..811f7a5ca 100644 --- a/app/locale/zh.coffee +++ b/app/locale/zh.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "选取难度" From 051fd9ecbc014143e919cfee40ed51a2710783ab Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Fri, 18 Jul 2014 13:40:05 +0100 Subject: [PATCH 03/14] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 9e51664d6..215d1aad0 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" -# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." -# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." -# coffeescript_blurb: "Nicer JavaScript syntax." -# clojure_blurb: "A modern Lisp." -# lua_blurb: "Game scripting language." -# io_blurb: "Simple but obscure." + javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." + python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." + coffeescript_blurb: "Sintaxe do Javascript mais agradável." + clojure_blurb: "Um Lisp moderno" + lua_blurb: "Linguagem para scripts de jogos" + io_blurb: "Simples mas obscuro" play: choose_your_level: "Escolha o Seu Nível" From 3ac1d6c77cae0b493cf1b23b9b89396e9e764ae3 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Fri, 18 Jul 2014 15:48:36 +0100 Subject: [PATCH 04/14] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 215d1aad0..47879bfe7 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" - javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." - python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." - coffeescript_blurb: "Sintaxe do Javascript mais agradável." - clojure_blurb: "Um Lisp moderno" - lua_blurb: "Linguagem para scripts de jogos" - io_blurb: "Simples mas obscuro" +# javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." +# python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." +# coffeescript_blurb: "Sintaxe do Javascript mais agradável." +# clojure_blurb: "Um Lisp moderno" +# lua_blurb: "Linguagem para scripts de jogos" +# io_blurb: "Simples mas obscuro" play: choose_your_level: "Escolha o Seu Nível" From a6ab97703410aeadc73e864374e2a0151b44cdb5 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 11:05:37 -0700 Subject: [PATCH 05/14] Add candidate finish reminder email --- server/routes/mail.coffee | 104 +++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 26a5e8ed0..e7deb6707 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,5 +1,6 @@ mail = require '../commons/mail' MailSent = require '../mail/sent/MailSent' +UserRemark = require '../users/remarks/UserRemark' User = require '../users/User' async = require 'async' errors = require '../commons/errors' @@ -28,6 +29,9 @@ setupScheduledEmails = -> , taskFunction: employerNewCandidatesAvailableTask frequencyMs: 10 * 60 * 1000 #10 minutes + , + taskFunction: unapprovedCandidateFinishProfileTask + frequencyMs: 10 * 60 * 1000 ] for mailTask in mailTasks @@ -35,7 +39,7 @@ setupScheduledEmails = -> testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" -### Candidate Update Reminder Task ### +### Approved Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" @@ -132,7 +136,103 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> sendwithus.api.send context, (err, result) -> log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err sendEmailCallback null -### End Candidate Update Reminder Task ### +### End Approved Candidate Update Reminder Task ### + +### Unapproved Candidate Finish Reminder Task ### +unapprovedCandidateFinishProfileTask = -> + mailTaskName = "unapprovedCandidateFinishProfileTask" + lockDurationMs = 2 * 60 * 1000 + currentDate = new Date() + timeRanges = [] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']] + timeRanges.push + start: generateWeekOffset currentDate, weekPair[0] + end: generateWeekOffset currentDate, weekPair[1] + name: weekPair[2] + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" + async.each timeRanges, emailUnapprovedCandidateTimeRange.bind({mailTaskName: mailTaskName}), (err) -> + if err + log.error "There was an error sending the candidate profile update reminder emails: #{err}" + else + log.info "Completed mail task #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) -> + waterfallContext = + "timeRange": timeRange + "mailTaskName": @mailTaskName + async.waterfall [ + findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext) + (unfilteredCandidates, cb) -> + async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null) + (unfilteredPotentialCandidates, cb) -> + async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null) + (filteredCandidates, cb) -> + async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb + ], emailTimeRangeCallback + +findAllUnapprovedCandidatesWithinTimeRange = (cb) -> + findParameters = + "jobProfile": + $exists: true + "jobProfile.updated": + $gt: @timeRange.start + $lte: @timeRange.end + "jobProfileApproved": false + selection = "_id email jobProfile.name jobProfile.updated emails" + User.find(findParameters).select(selection).lean().exec cb + +ignoredCandidateFilter = (candidate, cb) -> + findParameters = + "user": candidate._id + "contactName": "Ignore" + UserRemark.count findParameters, (err, results) -> + if err? then return true + return cb Boolean(results.length) + +unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) -> + if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false + return sentEmailFilterCallback true + findParameters = + "user": candidate._id + "mailTask": @mailTaskName + "metadata.timeRangeName": @timeRange.name + "metadata.updated": candidate.jobProfile.updated + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" + sentEmailFilterCallback true + else + sentEmailFilterCallback Boolean(sentMail.length) + +sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) -> + if err? + log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}" + return sendEmailCallback err + context = + email_id: "tem_RXyjzmc7S2HJH287pfoSPN" + recipient: + address: candidate.email + name: candidate.jobProfile.name + email_data: + user_profile: "http://codecombat.com/account/profile/#{candidate._id}" + recipient_address: encodeURIComponent(candidate.email) + log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})" + newSentMail = + mailTask: @mailTaskName + user: candidate._id + metadata: + timeRangeName: @timeRange.name + updated: candidate.jobProfile.updated + MailSent.create newSentMail, (err) -> + if err? then return sendEmailCallback err + sendwithus.api.send context, (err, result) -> + log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err + sendEmailCallback null +### End Unapproved Candidate Finish Reminder Task ### + ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" From 321bce121c8772b38be3f837bff2f6ff21d1f88e Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 14:50:31 -0700 Subject: [PATCH 06/14] Edited task schema --- app/schemas/models/user_remark.coffee | 18 +++++++++++++++++- server/routes/mail.coffee | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/schemas/models/user_remark.coffee b/app/schemas/models/user_remark.coffee index 839ce1380..260164a3b 100644 --- a/app/schemas/models/user_remark.coffee +++ b/app/schemas/models/user_remark.coffee @@ -12,7 +12,23 @@ _.extend UserRemarkSchema.properties, history: c.array {title: 'History', description: 'Records of our interactions with the user.'}, c.object {title: 'Record'}, {date: c.date(title: 'Date'), content: {title: 'Content', type: 'string', format: 'markdown'}} tasks: c.array {title: 'Tasks', description: 'Task entries: when to email the contact about something.'}, - c.object {title: 'Task'}, {date: c.date(title: 'Date'), action: {title: 'Action', type: 'string'}} + c.object {title: 'Task'}, + date: c.date + title: 'Date' + action: + title: 'Action' + type: 'string' + status: + title: 'Status' + description: 'The current status of the task' + type: 'string' + enum: ['Not started', 'In progress', 'Completed'] + notes: + title: 'Notes' + description: 'Notes about the task in progress' + type: 'string' + format: 'markdown' + # denormalization userName: {title: 'Player Name', type: 'string'} diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index e0ef70220..0786a5f62 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -403,6 +403,10 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> cb null ### End Employer New Candidates Available Email ### + +### Task Emails ### +userRemarkTaskEmailTask = -> + ### New Recruit Leaderboard Email ### ### From 18631ec5b152468d0889713f9d4e9bd1c1a36aa8 Mon Sep 17 00:00:00 2001 From: George Saines <gsaines@gmail.com> Date: Fri, 18 Jul 2014 15:42:53 -0700 Subject: [PATCH 07/14] upgrading our level icons --- app/assets/images/pages/home/language_js.png | Bin 9586 -> 9268 bytes .../images/pages/home/language_python.png | Bin 7633 -> 8282 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/assets/images/pages/home/language_js.png b/app/assets/images/pages/home/language_js.png index 75db0f254b6ce29a7e5b869ec1d8ed2e98ee2c80..9da73cf33c8c7ee7d6e29f82ccb850e866574279 100644 GIT binary patch delta 8701 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 Q65TFsbpy59XLgbQ3wXY0g#Z8m delta 9001 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 OpQ$Lkl`oUE2>CzL&<<Sy diff --git a/app/assets/images/pages/home/language_python.png b/app/assets/images/pages/home/language_python.png index 80e09da9eddaaf746a569d80f1671a5e4b1e5f1d..71f23d4ad89a4618e74065bd1edbd01e3b13886d 100644 GIT binary patch delta 7530 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 delta 6876 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 Wl{nr3RxTa@0000<MNUMnLSTYWXr)X5 From 90a4a1b635db04f91564537ad8a3e4afeaa6ea47 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:22:06 -0700 Subject: [PATCH 08/14] Added setProjection so CocoModels can more easily get subsets of data. --- app/models/CocoModel.coffee | 15 +++++++++++---- test/app/models/CocoModel.spec.coffee | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 045843306..5da19cab3 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -13,8 +13,10 @@ class CocoModel extends Backbone.Model getMe: -> @me or @me = require('lib/auth').me - initialize: -> - super() + initialize: (attributes, options) -> + super(arguments...) + options ?= {} + @setProjection options.project if not @constructor.className console.error("#{@} needs a className set.") @addSchemaDefaults() @@ -22,6 +24,8 @@ class CocoModel extends Backbone.Model @on 'error', @onError, @ @on 'add', @onLoaded, @ @saveBackup = _.debounce(@saveBackup, 500) + + setProjection: (@project) -> type: -> @constructor.className @@ -116,8 +120,11 @@ class CocoModel extends Backbone.Model console.debug 'Patching', @get('name') or @, keys @save(attrs, options) - fetch: -> - @jqxhr = super(arguments...) + fetch: (options) -> + options ?= {} + options.data ?= {} + options.data.project = @project.join(',') if @project + @jqxhr = super(options) @loading = true @jqxhr diff --git a/test/app/models/CocoModel.spec.coffee b/test/app/models/CocoModel.spec.coffee index 67e019c9a..7f2529466 100644 --- a/test/app/models/CocoModel.spec.coffee +++ b/test/app/models/CocoModel.spec.coffee @@ -14,6 +14,14 @@ class BlandClass extends CocoModel urlRoot: '/db/bland' describe 'CocoModel', -> + describe 'setProjection', -> + it 'takes an array of properties to project and adds them as a query parameter', -> + b = new BlandClass({}) + b.setProjection ['number', 'object'] + b.fetch() + request = jasmine.Ajax.requests.mostRecent() + expect(decodeURIComponent(request.url).indexOf('project=number,object')).toBeGreaterThan(-1) + describe 'save', -> it 'saves to db/<urlRoot>', -> From 52447f9e227d7da4e9a1a1d31313d8403a1e70f8 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:12 -0700 Subject: [PATCH 09/14] Fixed the avatar endpoint handling when the user object DNE. --- server/users/user_handler.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 020d30f20..275807ad7 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -219,6 +219,7 @@ UserHandler = class UserHandler extends Handler avatar: (req, res, id) -> @modelClass.findById(id).exec (err, document) => return @sendDatabaseError(res, err) if err + return @sendNotFoundError(res) unless document photoURL = document?.get('photoURL') if photoURL photoURL = "/file/#{photoURL}" From 4658c3000f34d0655adbca47a861d3ec68635cd5 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:28:52 -0700 Subject: [PATCH 10/14] Extended getLatestVersion for Handler to also be able to accept project parameters. --- server/commons/Handler.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index a796b705e..9dfca705b 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -232,7 +232,11 @@ module.exports = class Handler query['version.minor'] = minorVersion unless _.isNaN(minorVersion) sort = { 'version.major': -1, 'version.minor': -1 } args = [query] - args.push PROJECT if req.query.project + if req.query.project + projection = {} + fields = if req.query.project is 'true' then _.keys(PROJECT) else req.query.project.split(',') + projection[field] = 1 for field in fields + args.push projection @modelClass.findOne(args...).sort(sort).exec (err, doc) => return @sendNotFoundError(res) unless doc? return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc) From 74425103d18e8122865fb0c17aa0c124f9e5e1c2 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:29:26 -0700 Subject: [PATCH 11/14] Fixed some DemoView issues, mainly clicking links from one demo to another. --- app/views/DemoView.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/DemoView.coffee b/app/views/DemoView.coffee index a3b65c781..d18190162 100644 --- a/app/views/DemoView.coffee +++ b/app/views/DemoView.coffee @@ -35,6 +35,7 @@ module.exports = DemoView = class DemoView extends CocoView @loadDemoingLibs() unless DemoView.loaded loadDemoingLibs: -> + DemoView.loaded = true @queue = new createjs.LoadQueue() @queue.on('complete', @scriptsLoaded, @) window.jasmine = {} # so that mock-ajax properly loads. It expects jasmine to be loaded @@ -81,8 +82,14 @@ module.exports = DemoView = class DemoView extends CocoView view = demoFunc() return unless view @$el.find('#demo-area').empty().append(view.$el) + view.afterInsert() # TODO, maybe handle root views differently than modal views differently than everything else? getAllDemoFiles: -> allFiles = window.require.list() (f for f in allFiles when f.indexOf('.demo') > -1) + + destroy: -> + # hack to get jasmine tests to properly run again on clicking links, and make sure if you + # leave this page (say, back to the main site) that test stuff doesn't follow you. + document.location.reload() From 9ad166048d37daaef40a6d961c871c003a13d3e8 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:21 -0700 Subject: [PATCH 12/14] Some work the job profile page. Added a demo view, mainly added a modal view for viewing raw player code. --- app/schemas/models/level.coffee | 2 + app/schemas/models/level_session.coffee | 2 +- app/styles/account/profile.sass | 3 +- app/styles/base.sass | 13 +- .../common/level_session_code_view.sass | 25 + .../account/job_profile_code_modal.jade | 12 + app/templates/account/profile.jade | 7 +- app/templates/base.jade | 2 +- app/templates/common/level_session_code.jade | 13 + app/views/account/JobProfileCodeModal.coffee | 25 + app/views/account/profile_view.coffee | 14 +- app/views/common/LevelSessionCodeView.coffee | 50 ++ .../editor/level/settings_tab_view.coffee | 2 +- app/views/kinds/RootView.coffee | 7 + server/levels/level_handler.coffee | 2 + server/users/user_handler.coffee | 2 +- .../common/LevelSessionCodeView.demo.coffee | 13 + .../views/user/JobProfileView.demo.coffee | 576 ++++++++++++++++++ 18 files changed, 754 insertions(+), 16 deletions(-) create mode 100644 app/styles/common/level_session_code_view.sass create mode 100644 app/templates/account/job_profile_code_modal.jade create mode 100644 app/templates/common/level_session_code.jade create mode 100644 app/views/account/JobProfileCodeModal.coffee create mode 100644 app/views/common/LevelSessionCodeView.coffee create mode 100644 test/demo/views/common/LevelSessionCodeView.demo.coffee create mode 100644 test/demo/views/user/JobProfileView.demo.coffee diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee index eba42f599..262c02d18 100644 --- a/app/schemas/models/level.coffee +++ b/app/schemas/models/level.coffee @@ -230,12 +230,14 @@ _.extend LevelSchema.properties, title: 'Next Level', description: 'Reference to the next level players will play after beating this one.' } + employerDescription: { type:'string', format: 'markdown', title: 'Employer Description' } scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema # TODO: uniqueness should be based on 'original', not whole thing victory: c.object {title: 'Victory Screen', default: {}, properties: {'body': {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'}, i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}}} i18n: {type: 'object', format: 'i18n', props: ['name', 'description'], description: 'Help translate this level'} icon: {type: 'string', format: 'image-file', title: 'Icon'} + banner: {type: 'string', format: 'image-file', title: 'Banner'} goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial']) showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always']) diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee index f4f629914..92ff0f5ba 100644 --- a/app/schemas/models/level_session.coffee +++ b/app/schemas/models/level_session.coffee @@ -13,7 +13,7 @@ LevelSessionPlayerSchema = c.object changes: type: 'Number' -LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion']}, +LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion'], links: [{rel: 'db', href: '/db/level/{(original)}/version/{(majorVersion)}'}]}, original: c.objectId({}) majorVersion: type: 'integer' diff --git a/app/styles/account/profile.sass b/app/styles/account/profile.sass index 05a06f6ee..a661ea611 100644 --- a/app/styles/account/profile.sass +++ b/app/styles/account/profile.sass @@ -127,13 +127,14 @@ text-align: center ul.links + text-align: center li.has-icon display: inline-block img margin: 0 0 10px 0 li.has-icon:not(:nth-child(5)) img - margin: 0 10px 10px 0 + margin: 0 5px 10px 5px #contact-candidate margin-top: 20px diff --git a/app/styles/base.sass b/app/styles/base.sass index eae0d473b..c873d3d0f 100644 --- a/app/styles/base.sass +++ b/app/styles/base.sass @@ -24,13 +24,16 @@ h1 h2 h3 h4 @include box-sizing(border-box) #outer-content-wrapper + background: #B4B4B4 + +#outer-content-wrapper.show-background background: #8cc63f url(/images/pages/base/repeat-tile.png) top center -#intermediate-content-wrapper - background: url(/images/pages/base/sky_repeater.png) repeat-x + #intermediate-content-wrapper + background: url(/images/pages/base/sky_repeater.png) repeat-x -#inner-content-wrapper - background: url(/images/pages/base/background_texture.png) top center no-repeat + #inner-content-wrapper + background: url(/images/pages/base/background_texture.png) top center no-repeat #front-summary-points-left width: 250px @@ -70,7 +73,7 @@ h1 h2 h3 h4 &:hover color: $white -a[data-toggle="modal"] +a cursor: pointer .share-buttons, .partner-badges diff --git a/app/styles/common/level_session_code_view.sass b/app/styles/common/level_session_code_view.sass new file mode 100644 index 000000000..270d9a0d3 --- /dev/null +++ b/app/styles/common/level_session_code_view.sass @@ -0,0 +1,25 @@ +.level-session-code-view + #level-icon + max-width: 60% + max-height: 150px + margin-right: 10px + display: inline-block + float: right + margin-bottom: 20px + + #level-meta-data + width: 35% + button + float: right + + #session-code + clear: both + margin-top: 20px + + h3 + font-family: Arial + margin: 0 + + .code + height: 600px + border: 2px solid black \ No newline at end of file diff --git a/app/templates/account/job_profile_code_modal.jade b/app/templates/account/job_profile_code_modal.jade new file mode 100644 index 000000000..6f5703ef6 --- /dev/null +++ b/app/templates/account/job_profile_code_modal.jade @@ -0,0 +1,12 @@ +extends /templates/modal/modal_base + +block modal-header-content + h3 Applicant Code for + span.spl= session.get('levelName') + +block modal-body-content + .level-session-code-view + +block modal-footer + .modal-footer + button(data-dismiss="modal", data-i18n="modal.close").btn Close diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade index 11c0d6956..2699a3ac1 100644 --- a/app/templates/account/profile.jade +++ b/app/templates/account/profile.jade @@ -181,13 +181,12 @@ block content ul.sessions each session in sessions li - - var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id); - a(href=sessionLink) + a.session-link(data-session-id=session._id) span= session.levelName if session.team - span #{session.team} + span.spl - #{session.team} if session.codeLanguage != 'javascript' - span - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} + span.spl - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} .middle-column.full-height-column .sub-column diff --git a/app/templates/base.jade b/app/templates/base.jade index 01a67687c..6c18d420c 100644 --- a/app/templates/base.jade +++ b/app/templates/base.jade @@ -49,7 +49,7 @@ body a.header-font(href='/community', data-i18n="nav.community") Community block outer_content - #outer-content-wrapper + #outer-content-wrapper(class=showBackground ? 'show-background' : '') #intermediate-content-wrapper #inner-content-wrapper .main-content-area diff --git a/app/templates/common/level_session_code.jade b/app/templates/common/level_session_code.jade new file mode 100644 index 000000000..ad998e89d --- /dev/null +++ b/app/templates/common/level_session_code.jade @@ -0,0 +1,13 @@ +div#session-info + img(src='/file/'+levelIcon alt='levelIcon')#level-icon + div#level-meta-data + a.btn.btn-primary(href=sessionLink, target=_blank) Spectate + p!= levelDescription + +div#session-code + for spell in levelSpells + .panel.panel-success + .panel-heading + h3= spell.name + .panel-body + .code(data-height=spell.height)= spell.code \ No newline at end of file diff --git a/app/views/account/JobProfileCodeModal.coffee b/app/views/account/JobProfileCodeModal.coffee new file mode 100644 index 000000000..397de97cf --- /dev/null +++ b/app/views/account/JobProfileCodeModal.coffee @@ -0,0 +1,25 @@ +ModalView = require 'views/kinds/ModalView' +template = require 'templates/account/job_profile_code_modal' +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +console.log 'template', template + +module.exports = class JobProfileCodeModal extends ModalView + id: 'job_profile_code_modal' + template: template + modalWidthPercent: 90 + plain: true + + constructor: (options) -> + super(arguments...) + @session = options.session + + getRenderData: -> + c = super() + c.session = @session + c + + afterRender: -> + super() + codeView = new LevelSessionCodeView({session:@session}) + @insertSubView(codeView, @$el.find('.level-session-code-view')) + \ No newline at end of file diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee index 213b89a97..ca33ba8e8 100644 --- a/app/views/account/profile_view.coffee +++ b/app/views/account/profile_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/account/profile' User = require 'models/User' LevelSession = require 'models/LevelSession' @@ -9,6 +9,7 @@ JobProfileView = require 'views/account/job_profile_view' UserRemark = require 'models/UserRemark' forms = require 'lib/forms' ModelModal = require 'views/modal/model_modal' +JobProfileCodeModal = require './JobProfileCodeModal' class LevelSessionsCollection extends CocoCollection url: -> "/db/user/#{@userID}/level.sessions/employer" @@ -25,9 +26,11 @@ adminContacts = [ {id: '52a57252a89409700d0000d9', name: 'Ignore'} ] -module.exports = class ProfileView extends View +module.exports = class ProfileView extends RootView id: 'profile-view' template: template + showBackground: false + subscriptions: 'linkedin-loaded': 'onLinkedInLoaded' @@ -49,6 +52,7 @@ module.exports = class ProfileView extends View 'keyup .editable-profile .editable-array input': 'onEditArray' 'click .editable-profile a': 'onClickLinkWhileEditing' 'change #admin-contact': 'onAdminContactChanged' + 'click .session-link': 'onSessionLinkPressed' constructor: (options, @userID) -> @userID ?= me.id @@ -584,3 +588,9 @@ module.exports = class ProfileView extends View {name: t('account_profile.next_photo'), weight: 2, container: '#profile-photo-container', fn: modified 'photoURL'} {name: t('account_profile.next_active'), weight: 1, fn: modified 'active'} ] + + onSessionLinkPressed: (e) -> + sessionID = $(e.target).closest('.session-link').data('session-id') + session = _.find @sessions.models, (session) -> session.id is sessionID + modal = new JobProfileCodeModal({session:session}) + @openModalView modal \ No newline at end of file diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee new file mode 100644 index 000000000..768793115 --- /dev/null +++ b/app/views/common/LevelSessionCodeView.coffee @@ -0,0 +1,50 @@ +CocoView = require 'views/kinds/CocoView' +template = require 'templates/common/level_session_code' + +Level = require 'models/Level' +LevelSession = require 'models/LevelSession' + +module.exports = class LevelSessionCodeView extends CocoView + className: 'level-session-code-view' + template: template + + constructor: (options) -> + super(options) + @session = options.session + @level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level) + @level.setProjection ['employerDescription', 'name', 'icon', 'banner', 'slug'] + @supermodel.loadModel @level, 'level' + + getRenderData: -> + c = super() + c.levelIcon = @level.get('banner') or @level.get('icon') + c.levelName = @level.get('name') + c.levelDescription = marked(@level.get('employerDescription') or '') + c.levelSpells = @organizeCode() + c.sessionLink = "/play/level/" + (@level.get('slug') or @level.id) + "?team=" + (@session.get('team') || 'humans') + "&session=" + @session.id + c + + afterRender: -> + super() + @$el.find('.code').each (index, codeEl) -> + height = parseInt($(codeEl).data('height')) + $(codeEl).height(height) + editor = ace.edit codeEl + editor.setReadOnly true + aceSession = editor.getSession() + aceSession.setMode 'ace/mode/javascript' + + organizeCode: -> + team = @session.get('team') or 'humans' + teamSpells = @session.get('teamSpells')[team] or [] + filteredSpells = [] + for spell in teamSpells + code = @session.getSourceFor(spell) + lines = code.split('\n').length + height = lines * 16 + 20 + filteredSpells.push { + code: code + name: spell + height: height + } + filteredSpells \ No newline at end of file diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee index b3f99150c..21504830a 100644 --- a/app/views/editor/level/settings_tab_view.coffee +++ b/app/views/editor/level/settings_tab_view.coffee @@ -13,7 +13,7 @@ module.exports = class SettingsTabView extends View # not thangs or scripts or the backend stuff editableSettings: [ 'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals', - 'type', 'showsGuide' + 'type', 'showsGuide', 'banner', 'employerDescription' ] subscriptions: diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee index aac5dc64f..858c9fb48 100644 --- a/app/views/kinds/RootView.coffee +++ b/app/views/kinds/RootView.coffee @@ -17,6 +17,8 @@ filterKeyboardEvents = (allowedEvents, func) -> return func(splat...) module.exports = class RootView extends CocoView + showBackground: true + events: 'click #logout-button': 'logoutAccount' 'change .language-dropdown': 'onLanguageChanged' @@ -112,6 +114,11 @@ module.exports = class RootView extends CocoView @renderScrollbar() #@$('.antiscroll-wrap').antiscroll() # not yet, buggy + getRenderData: -> + c = super() + c.showBackground = @showBackground + c + afterRender: -> super(arguments...) @chooseTab(location.hash.replace('#', '')) if location.hash diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee index bcda60e1c..76d0ed8ac 100644 --- a/server/levels/level_handler.coffee +++ b/server/levels/level_handler.coffee @@ -25,6 +25,8 @@ LevelHandler = class LevelHandler extends Handler 'goals' 'type' 'showsGuide' + 'banner' + 'employerDescription' ] postEditableProperties: ['name'] diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 275807ad7..fbd13ec19 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -233,7 +233,7 @@ UserHandler = class UserHandler extends Handler getLevelSessionsForEmployer: (req, res, userID) -> return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions')) query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']} - projection = 'levelName levelID team playtime codeLanguage submitted code totalScore' + projection = 'levelName levelID team playtime codeLanguage submitted code totalScore teamSpells level' LevelSession.find(query).select(projection).exec (err, documents) => return @sendDatabaseError(res, err) if err documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents) diff --git a/test/demo/views/common/LevelSessionCodeView.demo.coffee b/test/demo/views/common/LevelSessionCodeView.demo.coffee new file mode 100644 index 000000000..a7aa3810e --- /dev/null +++ b/test/demo/views/common/LevelSessionCodeView.demo.coffee @@ -0,0 +1,13 @@ +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +LevelSession = require 'models/LevelSession' + +levelSessionData = {"_id":"5317ad4909098828ed071f4d","level":{"original":"53173f76c269d400000543c2","majorVersion":0},"team":"humans","levelID":"dungeon-arena","levelName":"Dungeon Arena","submitted":true,"totalScore":38.4584087145667,"code":{"programmable-librarian":{"chooseAction":"// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nif (this.canCast('slow', enemy)) {\n // Slow the enemy, or chase if out of range (30m).\n this.castSlow(enemy);\n if (this.distance(enemy) <= 50)\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}\nvar base = this.getFriends()[0];\nvar d = base.distance(enemy);\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n"},"human-base":{"chooseAction":"// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\nhero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"},"hushbaum":{"chooseAction":"var enemy = this.getNearestEnemy();\nif (enemy) {\n if (!enemy.hasEffect('slow')) {\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 70, y: 30});\n}\n"},"tharin":{"chooseAction":"var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n"},"tharin-1":{"chooseAction":"var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n _aether.logCallStart(this._aetherUserInfo); var enemies, enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;\n tmp2 = 'use strict';\n tmp3 = __interceptThis(this, __global);\n tmp4 = 'getEnemies';\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}]); enemies = tmp3[tmp4](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}], \"var enemies = this.getEnemies();\", this._aetherUserInfo);\n tmp5 = __interceptThis(this, __global);\n tmp6 = 'getNearest';\n tmp7 = enemies;\n _aether.logStatementStart([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}]); enemy = tmp5[tmp6](tmp7); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}], \"var enemy = this.getNearest(enemies);\", this._aetherUserInfo);\n tmp10 = __interceptThis(this, __global);\n tmp11 = 'getCooldown';\n _aether.logStatementStart([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}]); tmp12 = 'warcry'; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}], \"'warcry'\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}]); tmp9 = tmp10[tmp11](tmp12); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}], \"this.getCooldown('warcry')\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}]); tmp8 = !tmp9; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}], \"!this.getCooldown('warcry')\", this._aetherUserInfo);\n if (tmp8) {\n tmp13 = __interceptThis(this, __global);\n tmp14 = 'warcry';\n _aether.logStatementStart([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}]); tmp15 = tmp13[tmp14](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}], \"this.warcry()\", this._aetherUserInfo);\n } else {\n tmp16 = enemy;\n if (tmp16) {\n tmp17 = __interceptThis(this, __global);\n tmp18 = 'attack';\n tmp19 = enemy;\n _aether.logStatementStart([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}]); tmp20 = tmp17[tmp18](tmp19); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}], \"this.attack(enemy)\", this._aetherUserInfo);\n } else {\n tmp21 = __interceptThis(this, __global);\n tmp22 = 'move';\n _aether.logStatementStart([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}]); tmp24 = 10; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}], \"10\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}]); tmp25 = 30; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}], \"30\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}]); tmp23 = {\n x: tmp24,\n y: tmp25\n }; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}], \"{x: 10, y: 30}\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}]); tmp26 = tmp21[tmp22](tmp23); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}], \"this.move({x: 10, y: 30})\", this._aetherUserInfo);\n }\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));"},"programmable-tharin":{"chooseAction":"/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n If they fully base race us, we actually do want to produce archers since they DPS faster\n The effective DPS on soldiers is better if they attack us\n but worse if they straight race us\n\n //not sure if this is good but...\n if they're attacking our base with a small number of units\n we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n} \nif (!this.getCooldown('warcry') && friends.length > 5) {\n this.warcry();\n} \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n this.shield();\n}\nelse {\n this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/"}},"teamSpells":{"ogres":["programmable-brawler/chooseAction","programmable-shaman/chooseAction","ogre-base/chooseAction"],"humans":["programmable-librarian/chooseAction","programmable-tharin/chooseAction","human-base/chooseAction"]},"submittedCodeLanguage":"javascript","playtime":9753,"codeLanguage":"javascript"} +levelData = {"_id":"53c997066567c600002a43d0","name":"Dungeon Arena","icon":"db/level/53173f76c269d400000543c2/11_dungeon.png","banner":"db/level/53173f76c269d400000543c2/dungeon_arena.png","employerDescription":"Players:\n* Attempt to destroy the enemy base.\n* Choose and control heroes to attack with.\n* Choose which types of lesser units to build and have limited control over them.\n* Try to write strategies that counter other enemy strategies.\n* Play on a small map.","systems":[],"thangs":[],"scripts":[],"documentation":{"generalArticles":[],"specificArticles":[]},"description":"This level is indescribably flarmy!","version":{"minor":0,"major":0,"isLatestMajor":true,"isLatestMinor":true}}; + +module.exports = -> + session = new LevelSession(levelSessionData) + v = new LevelSessionCodeView({session:session}) + request = jasmine.Ajax.requests.mostRecent() + request.response({status: 200, responseText: JSON.stringify(levelData)}) + console.log 'okay should be fine' + v diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee new file mode 100644 index 000000000..17ac8767b --- /dev/null +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -0,0 +1,576 @@ +ProfileView = require 'views/account/profile_view' + +responses = + '/db/user/joe/nameToID':'512ef4805a67a8c507000001' + + '/db/user/512ef4805a67a8c507000001': { + "_id": "512ef4805a67a8c507000001", + "__v": 47, + "email": "livelily@gmail.com", + "emailSubscriptions": [ + "announcement", + "notification", + "developer", + "level_creator", + "tester", + "article_editor", + "translator", + "support" + ], + "facebookID": "4301215", + "firstName": "Nick", + "gender": "male", + "lastName": "Winter", + "name": "Nick!", + "photoURL": "db/user/512ef4805a67a8c507000001/nick_wizard.png", + "volume": 0, + "wizardColor1": 0.4, + "testGroupNumber": 217, + "mailChimp": { + "leid": "70264209", + "euid": "c4418e2abd", + "email": "livelily@gmail.com" + }, + "hourOfCode": true, + "hourOfCodeComplete": true, + "signedCLA": "Fri Jan 03 2014 14:40:18 GMT-0800 (PST)", + "wizard": { + "colorConfig": { + "boots": { + "lightness": 0.1647058823529412, + "saturation": 0.023809523809523805, + "hue": 0 + }, + "spell": { + "hue": 0.7490196078431373, + "saturation": 0.4106280193236715, + "lightness": 0.5941176470588235 + }, + "cloud": { + "lightness": 0.14, + "saturation": 1, + "hue": 0 + }, + "clothes": { + "lightness": 0.1411764705882353, + "saturation": 0, + "hue": 0 + }, + "trim": { + "hue": 0.5, + "saturation": 0.009900990099009936, + "lightness": 0.19803921568627453 + } + } + }, + "aceConfig": { + "liveCompletion": true, + "indentGuides": true, + "invisibles": true, + "keyBindings": "emacs", + "behaviors": true, + "language": "javascript" + }, + "lastLevel": "drink-me", + "gplusID": "110703832132860599877", + "jobProfile": { + "photoURL": "db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg", + "links": [ +# { +# "name": "Twitter", +# "link": "https://twitter.com/nwinter" +# }, +# { +# "name": "Facebook", +# "link": "https://www.facebook.com/nwinter" +# }, + { + "name": "LinkedIn", + "link": "https://www.linkedin.com/in/nwinter" + }, + { + "name": "Blog", + "link": "http://blog.nickwinter.net/" + }, + { + "name": "Personal Site", + "link": "http://www.nickwinter.net/" + }, + { + "name": "GitHub", + "link": "https://github.com/nwinter" + }, + { + "name": "G+", + "link": "https://plus.google.com/u/0/+NickWinter" + } + ], + "projects": [ + { + "name": "The Motivation Hacker", + "description": "I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.", + "picture": "db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg", + "link": "http://www.nickwinter.net/motivation-hacker" + }, + { + "name": "Quantified Mind", + "description": "Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.", + "picture": "db/user/512ef4805a67a8c507000001/screenshot.png", + "link": "http://www.quantified-mind.com/" + }, + { + "link": "https://github.com/nwinter/telepath-logger", + "name": "Telepath", + "description": "A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).", + "picture": "db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067" + } + ], + "education": [ + { + "school": "Oberlin College", + "degree": "BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS", + "duration": "Aug 2004 - May 2008", + "description": "Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it." + } + ], + "work": [ + { + "employer": "CodeCombat", + "role": "Cofounder", + "duration": "Jan 2013 - present", + "description": "Programming a programming game for learning programming to be a programming programmer of programmatic programs." + }, + { + "employer": "Skritter", + "role": "Cofounder", + "duration": "May 2008 - present", + "description": "I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email." + } + ], + "visa": "Authorized to work in the US", + "longDescription": "I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.", + "shortDescription": "Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.", + "experience": 6, + "skills": [ + "python", + "coffeescript", + "node", + "ios", + "objective-c", + "javascript", + "app-engine", + "mongodb", + "web dev", + "django", + "backbone", + "chinese", + "qs", + "writing" + ], + "country": "USA", + "city": "San Francisco", + "active": false, + "lookingFor": "Full-time", + "name": "Nick Winter", + "updated": "2014-07-12T01:48:42.980Z", + "jobTitle": "Mutant Code Gorilla" + }, + "jobProfileApproved": false, + "emails": { + "anyNotes": { + "enabled": true + }, + "generalNews": { + "enabled": true + }, + "archmageNews": { + "enabled": true + }, + "artisanNews": { + "enabled": true + }, + "adventurerNews": { + "enabled": true + }, + "scribeNews": { + "enabled": true + }, + "diplomatNews": { + "enabled": true + }, + "ambassadorNews": { + "enabled": true + } + }, + "activity": { + "viewed_by_employer": { + "last": "2014-06-19T20:21:43.747Z", + "count": 6, + "first": "2014-06-12T01:37:38.278Z" + }, + "view_candidate": { + "first": "2014-06-10T19:59:30.773Z", + "count": 661, + "last": "2014-07-11T02:14:40.131Z" + }, + "login": { + "first": "2014-06-10T21:55:08.968Z", + "count": 22, + "last": "2014-07-16T16:32:31.661Z" + }, + "contacted_by_employer": { + "first": "2014-06-19T20:24:51.870Z", + "count": 1, + "last": "2014-06-19T20:24:51.870Z" + } + }, + "slug": "nick", + "jobProfileNotes": "Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.", + "simulatedFor": 2363, + "simulatedBy": 103674, + "preferredLanguage": "en-US", + "anonymous": false, + "permissions": [ + "admin" + ], + "autocastDelay": 90019001, + "music": false, + "dateCreated": "2013-02-28T06:09:04.743Z" + }, + + '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ + { + "_id": "53179b49b483edfcdb7ef13e", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "code": { + }, + "submitted": false, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submittedCodeLanguage": "javascript", + "playtime": 33, + "codeLanguage": "javascript" + }, + { + "_id": "53336ee91506ed33756f73e5", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "code": { + }, + "teamSpells": { + "humans": [ + "programmable-coin/chooseAction", + "tharin/chooseAction", + "wizard-purple/chooseAction" + ] + }, + "levelID": "gold-rush", + "levelName": "Resource gathering multiplayer", + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "52ae32cbef42c52f1300000d", + "level": { + "original": "52ae2460ef42c52f13000008", + "majorVersion": 0 + }, + "levelID": "gridmancer", + "levelName": "Gridmancer", + "code": { + }, + "teamSpells": { + "humans": [ + "thoktar" + ] + }, + "submitted": false, + "submittedCodeLanguage": "javascript", + "playtime": 302, + "codeLanguage": "javascript" + }, + { + "_id": "5334901f0a0f9b286f57382c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "team": "humans", + "code": { + }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "levelID": "gold-rush", + "levelName": "Gold Rush", + "totalScore": 39.23691444835561, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1158, + "codeLanguage": "javascript" + }, + { + "_id": "52dea9b77e486eeb97000001", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, + "levelID": "brawlwood", + "levelName": "Brawlwood", + "code": { + }, + "totalScore": 24.138610165979667, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, + "team": "humans", + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "535701331bfa9bba14b5e03d", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "greed", + "levelName": "Greed", + "code": { + }, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 36.77589873873074, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 12893, + "codeLanguage": "javascript" + }, + { + "_id": "5356fc2e1bfa9bba14b5e039", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, + "team": "humans", + "levelID": "greed", + "levelName": "Greed", + "code": { + }, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 31.538998178536794, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 15648, + "codeLanguage": "javascript" + }, + { + "_id": "52fd5bf7e3c53130231726e1", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": true, + "totalScore": 53.73511062513137, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, + "code": { + }, + "submittedCodeLanguage": "javascript", + "playtime": 178, + "codeLanguage": "javascript" + }, + { + "_id": "5317ad4909098828ed071f4d", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "team": "humans", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 38.19039674380126, + "code": { + }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "submittedCodeLanguage": "javascript", + "playtime": 9753, + "codeLanguage": "javascript" + }, + { + "_id": "53361c80948ad7a777a10d9c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "gold-rush", + "levelName": "Gold Rush", + "code": { + }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "totalScore": 40.73558595296533, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1014, + "codeLanguage": "javascript" + }, + { + "_id": "531920069f44be00001a7aef", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 26.50666470188054, + "code": { + }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "submittedCodeLanguage": "javascript", + "playtime": 1786, + "codeLanguage": "javascript" + } + ] + +module.exports = -> + me.isAdmin = -> false + me.set('permissions', ['employer']) + v = new ProfileView({}, 'joe') + for url, responseBody of responses + requests = jasmine.Ajax.requests.filter(url) + if not requests.length + console.error "could not find response for <#{url}>", responses + continue + request = requests[0] + request.response({status: 200, responseText: JSON.stringify(responseBody)}) + # v.$el = v.$el.find('.main-content-area') + v From cd0d81438dc75dc829afdbdf9b9a028e358e7222 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 16:26:53 -0700 Subject: [PATCH 13/14] Add recruitment task reminder emails --- server/routes/mail.coffee | 94 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 0786a5f62..ed239f9be 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -32,6 +32,9 @@ setupScheduledEmails = -> , taskFunction: unapprovedCandidateFinishProfileTask frequencyMs: 10 * 60 * 1000 + , + taskFunction: emailUserRemarkTaskRemindersTask + frequencyMs: 10 * 60 * 1000 ] for mailTask in mailTasks @@ -405,8 +408,97 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> ### End Employer New Candidates Available Email ### ### Task Emails ### -userRemarkTaskEmailTask = -> +emailUserRemarkTaskRemindersTask = -> + mailTaskName = "emailUserRemarkTaskRemindersTask" + lockDurationMs = 2 * 60 * 1000 + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" + emailUserRemarkTaskReminders.call {"mailTaskName":mailTaskName}, (err) -> + if err + log.error "There was an error completing the #{mailTaskName}: #{err}" + else + log.info "Completed the #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailUserRemarkTaskReminders = (cb) -> + currentTime = new Date() + asyncContext = + "currentTime": currentTime + "mailTaskName": @mailTaskName + async.waterfall [ + findAllIncompleteUserRemarkTasksDue.bind(asyncContext) + processRemarksIntoTasks.bind(asyncContext) + (allTasks, cb) -> + async.reject allTasks, taskReminderAlreadySentThisWeekFilter.bind(asyncContext), cb.bind(null,null) + (tasksToRemind, cb) -> + async.each tasksToRemind, sendUserRemarkTaskEmail.bind(asyncContext), cb + ], cb + +findAllIncompleteUserRemarkTasksDue = (cb) -> + findParameters = + tasks: + $exists: true + $elemMatch: + date: + $lte: @currentTime.toISOString() + status: + $ne: 'Completed' + selection = "contact user tasks" + UserRemark.find(findParameters).select(selection).lean().exec cb + +processRemarksIntoTasks = (remarks, cb) -> + tasks = [] + for remark in remarks + for task in remark.tasks + taskObject = + date: task.date + action: task.action + contact: remark.contact + user: remark.user + remarkID: remark._id + tasks.push taskObject + cb null, tasks + +taskReminderAlreadySentThisWeekFilter = (task, cb) -> + findParameters = + "user": task.contact + "mailTask": @mailTaskName + "sent": + $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) + "metadata": + remarkID: task.remarkID + taskAction: task.action + date: task.date + MailSent.count findParameters, (err, count) -> + if err? then return cb true + return cb Boolean(count) + +sendUserRemarkTaskEmail = (task, cb) -> + mailTaskName = @mailTaskName + User.findOne("_id":task.contact).select("email").lean().exec (err, contact) -> + if err? then return cb err + context = + email_id: "tem_aryDjyw6JmEmbKtCMTSwAM" + recipient: + address: contact.email + email_data: + candidate_link: "http://codecombat.com/account/profile/#{task.user}" + due_date: task.date + log.info "Sending recruitment task reminder to #{contact.email}" + newSentMail = + mailTask: mailTaskName + user: task.contact + "metadata": + remarkID: task.remarkID + taskAction: task.action + date: task.date + MailSent.create newSentMail, (err) -> + if err? then return cb err + sendwithus.api.send context, (err, result) -> + log.error "Error sending #{mailTaskName} to #{contact.email}: #{err} with result #{result}" if err + cb null ### New Recruit Leaderboard Email ### ### From 00c11fd70e1915f070de72d52978258d997fc427 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Fri, 18 Jul 2014 16:45:35 -0700 Subject: [PATCH 14/14] Minor defensive bug handling for the LevelSessionCodeView for when teamSpells has invalid, old data. --- app/views/common/LevelSessionCodeView.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee index 768793115..277eb2e3e 100644 --- a/app/views/common/LevelSessionCodeView.coffee +++ b/app/views/common/LevelSessionCodeView.coffee @@ -39,7 +39,7 @@ module.exports = class LevelSessionCodeView extends CocoView teamSpells = @session.get('teamSpells')[team] or [] filteredSpells = [] for spell in teamSpells - code = @session.getSourceFor(spell) + code = @session.getSourceFor(spell) ? '' lines = code.split('\n').length height = lines * 16 + 20 filteredSpells.push {