From 455451453246f0366fd31dbf662c11161597cf09 Mon Sep 17 00:00:00 2001 From: jmigual Date: Thu, 11 Dec 2014 12:59:08 +0100 Subject: [PATCH 01/18] Added some translations Added some translations and fixed spelling errors. --- app/locale/ca.coffee | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index d4c0a217a..64deb556c 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -4,7 +4,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr no_ie: "CodeCombat no funciona en Internet Explorer 8 o versions anteriors. Perdó!" # Warning that only shows up in IE8 and older no_mobile: "CodeCombat no ha estat dissenyat per dispositius mòbils i per tant no funcionarà!" # Warning that shows up on mobile devices play: "Jugar" # The big play button that just starts playing a level -# try_it: "Try It" # Alternate wording for Play button + try_it: "Prova'l" # Alternate wording for Play button old_browser: "Uh oh, el teu navegador és massa antic per fer funcionar CodeCombat. Perdó!" # Warning that shows up on really old Firefox/Chrome/Safari old_browser_suffix: "Pots probar-ho igualment, però el més segur és que no funcioni." # ipad_browser: "Bad news: CodeCombat doesn't run on iPad in the browser. Good news: our native iPad app is awaiting Apple approval." @@ -12,7 +12,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr for_beginners: "Per a principiants" multiplayer: "Multijugador" # Not currently shown on home page for_developers: "Per a Desenvolupadors" # Not currently shown on home page. -# or_ipad: "Or download for iPad" + or_ipad: "O descarrèga'l per iPad" nav: play: "Nivells" # The top nav bar entry where players choose which levels to play @@ -43,10 +43,10 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr diplomat_suggestion: title: "Ajuda a traduir CodeCombat!" # This shows up when a player switches to a non-English language using the language selector. sub_heading: "Neccesitem les teves habilitats lingüístiques." - pitch_body: "Hem desembolupat CodeCombat en Anglès, peró tenim jugadors per tot el món. Molts d'ells volen jugar en Català, però no parlen anglès, per tant si pots parlar ambdós llengües, siusplau considereu iniciar sesió per a ser Diplomàtic i ajudar a traduir la web de CodeCombat i tots els seus nivell en Català." + pitch_body: "Hem desenvolupat CodeCombat en Anglès, peró tenim jugadors per tot el món. Molts d'ells volen jugar en Català, però no parlen anglès, per tant si pots parlar ambdós llengües, siusplau considereu iniciar sesió per a ser Diplomàtic i ajudar a traduir la web de CodeCombat i tots els seus nivell en Català." missing_translations: "Fins que puguem traduir-ho tot en Català, veuràs en anglès quant sigui possible." - learn_more: "Apren més sobre seru un diplomàtic" - subscribe_as_diplomat: "Subscriute com a diplomàtic" + learn_more: "Aprèn més sobre seru un diplomàtic" + subscribe_as_diplomat: "Subscriu-te com a diplomàtic" play: play_as: "Jugar com" # Ladder page @@ -54,33 +54,33 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr players: "jugadors" # Hover over a level on /play hours_played: "hores de joc" # Hover over a level on /play items: "Objectes" # Tooltip on item shop button from /play -# unlock: "Unlock" # For purchasing items and heroes -# confirm: "Confirm" -# owned: "Owned" # For items you own -# locked: "Locked" -# purchasable: "Purchasable" # For a hero you unlocked but haven't purchased -# available: "Available" -# skills_granted: "Skills Granted" # Property documentation details + unlock: "Desbloquejar" # For purchasing items and heroes + confirm: "Confirmar" + owned: "Adquirit" # For items you own + locked: "Bloquejat" + purchasable: "Comprable" # For a hero you unlocked but haven't purchased + available: "Disponible" + skills_granted: "Habilitats Garantides" # Property documentation details heroes: "Herois" # Tooltip on hero shop button from /play achievements: "Triomfs" # Tooltip on achievement list button from /play - account: "Conta" # Tooltip on account button from /play + account: "Compte" # Tooltip on account button from /play settings: "Configuració" # Tooltip on settings button from /play next: "Següent" # Go from choose hero to choose inventory before playing a level change_hero: "Canviar heroi" # Go back from choose inventory to choose hero choose_inventory: "Equipar objectes" -# buy_gems: "Buy Gems" -# campaign_forest: "Forest Campaign" -# campaign_dungeon: "Dungeon Campaign" -# subscription_required: "Subscription Required" -# free: "Free" -# subscribed: "Subscribed" + buy_gems: "Comprar Gemes" + campaign_forest: "Campanya del Bosc" + campaign_dungeon: "Campanya de la Masmorra" + subscription_required: "Subscripció necessària" + free: "Gratuit" + subscribed: "Subscrit" older_campaigns: "Campanyes antigues" anonymous: "Jugador anònim" level_difficulty: "Dificultat: " campaign_beginner: "Campanya del principiant" -# awaiting_levels_adventurer_prefix: "We release five levels per week." -# awaiting_levels_adventurer: "Sign up as an Adventurer" -# awaiting_levels_adventurer_suffix: "to be the first to play new levels." + awaiting_levels_adventurer_prefix: "Fem cinc nivells per setmana" + awaiting_levels_adventurer: "Inicia sessió com aventurer" + awaiting_levels_adventurer_suffix: "sigues el primer en jugar els nous nivells" choose_your_level: "Escull el teu nivell" # The rest of this section is the old play view at /play-old and isn't very important. adventurer_prefix: "Pots saltar a qualsevols dels nivells de més abaix, o discutir els nivells de més amunt." adventurer_forum: "El fòrum de l'aventurer" @@ -101,14 +101,14 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr log_in: "Iniciar Sessió" logging_in: "Iniciant Sessió" log_out: "Tancar Sessió" -# forgot_password: "Forgot your password?" -# authenticate_gplus: "Authenticate G+" -# load_profile: "Load G+ Profile" + forgot_password: "Contrasenya oblidada?" + authenticate_gplus: "Inicia amb G+" + load_profile: "Carrega un perfil de G+" # load_email: "Load G+ Email" -# finishing: "Finishing" -# sign_in_with_facebook: "Sign in with Facebook" -# sign_in_with_gplus: "Sign in with G+" -# signup_switch: "Want to create an account?" + finishing: "Acabant" + sign_in_with_facebook: "Inicia amb Facebook" + sign_in_with_gplus: "Inicia amb G+" + signup_switch: "Vols crear-te un compte?" signup: email_announcements: "Rebre anuncis via email" @@ -117,7 +117,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr log_in: "Iniciar sessió amb la teva contrasenya" social_signup: "O, pots iniciar sesió desde Facebook o G+:" required: "Neccesites iniciar sesió abans ." -# login_switch: "Already have an account?" + login_switch: "Ja tens un compte?" recover: recover_account_title: "Recuperar Compte" @@ -125,8 +125,8 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr recovery_sent: "Correu de recuperació de contrasenya enviat." items: -# primary: "Primary" -# secondary: "Secondary" + primary: "Primari" + secondary: "Secundari" armor: "Armadura" accessories: "Accessoris" # misc: "Misc" From 375d388fe30c055b1cc8f5fb3715f834acfafb3d Mon Sep 17 00:00:00 2001 From: Adnan Zahid Date: Tue, 20 Jan 2015 00:06:29 +0500 Subject: [PATCH 02/18] Added 6 new tips for the loading screen Added the following tips: 1) play_level.tip_control_destiny 2) play_level.tip_no_code 3) play_level.tip_code_never_lies 4) play_level.tip_reusable_software 5) play_level.tip_optimization_operator 6) play_level.tip_lines_of_code --- app/templates/play/level/level_loading.jade | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/templates/play/level/level_loading.jade b/app/templates/play/level/level_loading.jade index 1515081d0..78ebd6154 100644 --- a/app/templates/play/level/level_loading.jade +++ b/app/templates/play/level/level_loading.jade @@ -57,3 +57,10 @@ strong.tip.rare span(data-i18n='play_level.tip_harry') Yer a Wizard, span= me.get('name', true) + + strong.tip.rare(data-i18n='play_level.tip_control_destiny') In real open source, you have the right to control your own destiny. - Linus Torvalds + strong.tip.rare(data-i18n='play_level.tip_no_code') No code is faster than no code. + strong.tip.rare(data-i18n='play_level.tip_code_never_lies') Code never lies, comments sometimes do. — Ron Jeffries + strong.tip.rare(data-i18n='play_level.tip_reusable_software') Before software can be reusable it first has to be usable. + strong.tip.rare(data-i18n='play_level.tip_optimization_operator') Every language has an optimization operator. In most languages that operator is ‘//’ + strong.tip.rare(data-i18n='play_level.tip_lines_of_code') Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates From f46160fff98ac396885f8b883f3396f2d46c8d86 Mon Sep 17 00:00:00 2001 From: Adnan Zahid Date: Tue, 20 Jan 2015 00:12:21 +0500 Subject: [PATCH 03/18] Added 6 new tips for the loading screen (Also written in level_loading.jade) Added the following tips: 1) play_level.tip_control_destiny 2) play_level.tip_no_code 3) play_level.tip_code_never_lies 4) play_level.tip_reusable_software 5) play_level.tip_optimization_operator 6) play_level.tip_lines_of_code --- app/locale/en.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 6415ecf09..991579ff7 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -317,6 +317,13 @@ tip_brute_force: "When in doubt, use brute force. - Ken Thompson" tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." tip_superpower: "Coding is the closest thing we have to a superpower." + + tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" + tip_no_code: "No code is faster than no code." + tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" + tip_reusable_software: "Before software can be reusable it first has to be usable." + tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" + tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventory" From 6b271799be7467ba6650ca5a8ee7f80bd2bd9172 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Wed, 21 Jan 2015 09:33:13 -0800 Subject: [PATCH 04/18] Update level loading view sub event data Sending level slug instead of name. --- app/views/play/level/LevelLoadingView.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/play/level/LevelLoadingView.coffee b/app/views/play/level/LevelLoadingView.coffee index 5e59cf816..ffd226793 100644 --- a/app/views/play/level/LevelLoadingView.coffee +++ b/app/views/play/level/LevelLoadingView.coffee @@ -110,7 +110,7 @@ module.exports = class LevelLoadingView extends CocoView onClickStartSubscription: (e) -> @openModalView new SubscribeModal() - window.tracker?.trackEvent 'Show subscription modal', category: 'Subscription', label: 'level loading', level: @options.level.get('name') ? 'unknown' + window.tracker?.trackEvent 'Show subscription modal', category: 'Subscription', label: 'level loading', level: @options.level.get('slug') onSubscribed: -> document.location.reload() From e49c74259b25bc44e4bf92a343bce527e99ede60 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Wed, 21 Jan 2015 13:41:34 -0800 Subject: [PATCH 05/18] Update campaign editor analytics Adding shown and purchased subscription counts. Locking down analytics to admin-only. --- .../campaign/campaign-analytics-modal.sass | 11 +- .../campaign/campaign-analytics-modal.jade | 69 +++--- .../editor/campaign/campaign-editor-view.jade | 7 +- .../campaign/CampaignAnalyticsModal.coffee | 50 ++++- .../mongodb/queries/insertPerDayAnalytics.js | 209 +++++++++++++----- .../analytics/analytics_perday_handler.coffee | 73 +++++- .../user_code_problem_handler.coffee | 4 + 7 files changed, 327 insertions(+), 96 deletions(-) diff --git a/app/styles/editor/campaign/campaign-analytics-modal.sass b/app/styles/editor/campaign/campaign-analytics-modal.sass index 40d19a78d..b3596890e 100644 --- a/app/styles/editor/campaign/campaign-analytics-modal.sass +++ b/app/styles/editor/campaign/campaign-analytics-modal.sass @@ -1,8 +1,16 @@ #campaign-analytics-modal + td + font-size: 9pt + max-width: 60px + td.completion-rate + max-width: 1000px + td.level + max-width: 1000px .modal-dialog - width: 75% + width: 85% .level-name-container position: relative + max-width: 1000px .level-name-background position: absolute height: 100% @@ -12,6 +20,7 @@ opacity: 0.25 .level-completion-container position: relative + max-width: 1000px .level-completion-background position: absolute height: 100% diff --git a/app/templates/editor/campaign/campaign-analytics-modal.jade b/app/templates/editor/campaign/campaign-analytics-modal.jade index 01b5e01b5..c2050199e 100644 --- a/app/templates/editor/campaign/campaign-analytics-modal.jade +++ b/app/templates/editor/campaign/campaign-analytics-modal.jade @@ -7,21 +7,32 @@ block modal-header-content input.form-control#input-startday(type='text', style='width:100px;', value=campaignCompletions.startDay) input.form-control#input-endday(type='text', style='width:100px;', value=campaignCompletions.endDay) button.btn.btn-default.btn-sm#reload-button(style='margin-left:10px;') Reload - div(style='font-size:10px') Double-click row to open level details. - + label(style='font-size:10px;font-weight:normal;') + span Double-click row to open level details. + span    + input#option-show-left-game(type='checkbox', checked=showLeftGame) + span Show Left Game + span    + input#option-show-subscriptions(type='checkbox', checked=showSubscriptions) + span Show Subscriptions + block modal-body-content if campaignCompletions && campaignCompletions.levels table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt') thead tr - td Level + td.level Level td Started td Finished - td Left Game - td LG % + td.completion-rate Completion % td Playtime (s) - td LG/s - td Completion % + if showLeftGame + td Left Game + td LG % + td LG/s + if showSubscriptions + td Sub Shown + td Sub Purchased tbody - for (var i = 0; i < campaignCompletions.levels.length; i++) tr.level(data-level-slug=campaignCompletions.levels[i].level) @@ -29,26 +40,6 @@ block modal-body-content span.level-name-background(style="width:#{campaignCompletions.levels[i].usersRemaining || 0}%;") td= campaignCompletions.levels[i].started td= campaignCompletions.levels[i].finished - td= campaignCompletions.levels[i].dropped - if campaignCompletions.levels[i].dropPercentage - if campaignCompletions.top3DropPercentage && campaignCompletions.top3DropPercentage.indexOf(campaignCompletions.levels[i].level) >= 0 - td(style='background-color:pink;')= campaignCompletions.levels[i].dropPercentage.toFixed(2) - else - td= campaignCompletions.levels[i].dropPercentage.toFixed(2) - else - td - if campaignCompletions.levels[i].averagePlaytime - td.level-playtime-container= campaignCompletions.levels[i].averagePlaytime.toFixed(2) - span.level-playtime-background(style="width:#{campaignCompletions.levels[i].playtimePercentage || 0}%;") - else - td - if campaignCompletions.levels[i].droppedPerSecond - if campaignCompletions.top3DropPerSecond && campaignCompletions.top3DropPerSecond.indexOf(campaignCompletions.levels[i].level) >= 0 - td(style='background-color:pink;')= campaignCompletions.levels[i].droppedPerSecond.toFixed(2) - else - td= campaignCompletions.levels[i].droppedPerSecond.toFixed(2) - else - td if campaignCompletions.levels[i].completionRate if campaignCompletions.top3 && campaignCompletions.top3.indexOf(campaignCompletions.levels[i].level) >= 0 td.level-completion-container(style='background-color:lightblue;')= campaignCompletions.levels[i].completionRate.toFixed(2) @@ -59,8 +50,32 @@ block modal-body-content else td.level-completion-container= campaignCompletions.levels[i].completionRate.toFixed(2) svg.level-completion-background(id="background#{campaignCompletions.levels[i].level}") + else + td.completion-rate + if campaignCompletions.levels[i].averagePlaytime + td.level-playtime-container= campaignCompletions.levels[i].averagePlaytime.toFixed(2) + span.level-playtime-background(style="width:#{campaignCompletions.levels[i].playtimePercentage || 0}%;") else td + if showLeftGame + td= campaignCompletions.levels[i].dropped + if campaignCompletions.levels[i].dropPercentage + if campaignCompletions.top3DropPercentage && campaignCompletions.top3DropPercentage.indexOf(campaignCompletions.levels[i].level) >= 0 + td(style='background-color:pink;')= campaignCompletions.levels[i].dropPercentage.toFixed(2) + else + td= campaignCompletions.levels[i].dropPercentage.toFixed(2) + else + td + if campaignCompletions.levels[i].droppedPerSecond + if campaignCompletions.top3DropPerSecond && campaignCompletions.top3DropPerSecond.indexOf(campaignCompletions.levels[i].level) >= 0 + td(style='background-color:pink;')= campaignCompletions.levels[i].droppedPerSecond.toFixed(2) + else + td= campaignCompletions.levels[i].droppedPerSecond.toFixed(2) + else + td + if showSubscriptions + td= campaignCompletions.levels[i].subsShown + td= campaignCompletions.levels[i].subsPurchased else div Loading... diff --git a/app/templates/editor/campaign/campaign-editor-view.jade b/app/templates/editor/campaign/campaign-editor-view.jade index b97154825..b503647b2 100644 --- a/app/templates/editor/campaign/campaign-editor-view.jade +++ b/app/templates/editor/campaign/campaign-editor-view.jade @@ -16,9 +16,10 @@ block header span.glyphicon-home.glyphicon ul.nav.navbar-nav.navbar-right - li#analytics-button - a - span.glyphicon-stats.glyphicon + if me.isAdmin() + li#analytics-button + a + span.glyphicon-stats.glyphicon if me.isAdmin() li#save-button a diff --git a/app/views/editor/campaign/CampaignAnalyticsModal.coffee b/app/views/editor/campaign/CampaignAnalyticsModal.coffee index d10b22f8d..5356b308d 100644 --- a/app/views/editor/campaign/CampaignAnalyticsModal.coffee +++ b/app/views/editor/campaign/CampaignAnalyticsModal.coffee @@ -14,14 +14,20 @@ module.exports = class CampaignAnalyticsModal extends ModalView events: 'click #reload-button': 'onClickReloadButton' 'dblclick .level': 'onDblClickLevel' + 'change #option-show-left-game': 'updateShowLeftGame' + 'change #option-show-subscriptions': 'updateShowSubscriptions' constructor: (options, @campaignHandle, @campaignCompletions) -> super options - @getCampaignAnalytics() unless @campaignCompletions?.levels? + @showLeftGame = true + @showSubscriptions = true + @getCampaignAnalytics() if me.isAdmin() getRenderData: -> c = super() c.campaignCompletions = @campaignCompletions + c.showLeftGame = @showLeftGame + c.showSubscriptions = @showSubscriptions c afterRender: -> @@ -30,6 +36,14 @@ module.exports = class CampaignAnalyticsModal extends ModalView $("#input-endday").datepicker dateFormat: "yy-mm-dd" @addCompletionLineGraphs() + updateShowLeftGame: -> + @showLeftGame = @$el.find('#option-show-left-game').prop('checked') + @render() + + updateShowSubscriptions: -> + @showSubscriptions = @$el.find('#option-show-subscriptions').prop('checked') + @render() + onClickReloadButton: () => startDay = $('#input-startday').val() endDay = $('#input-endday').val() @@ -45,6 +59,7 @@ module.exports = class CampaignAnalyticsModal extends ModalView @hide() addCompletionLineGraphs: -> + # TODO: no line graphs if some levels without completion rates? return unless @campaignCompletions.levels for level in @campaignCompletions.levels days = [] @@ -114,12 +129,14 @@ module.exports = class CampaignAnalyticsModal extends ModalView @render() @getCampaignAveragePlaytimes startDayDashed, endDayDashed, () => @render() + @getCampaignLevelSubscriptions startDay, endDay, () => + @render() getCampaignAveragePlaytimes: (startDay, endDay, doneCallback) => # Fetch level average playtimes # Needs date format yyyy-mm-dd success = (data) => - return if @destroyed + return doneCallback() if @destroyed # console.log 'getCampaignAveragePlaytimes success', data levelAverages = {} maxPlaytime = 0 @@ -161,7 +178,7 @@ module.exports = class CampaignAnalyticsModal extends ModalView getCampaignLevelCompletions: (startDay, endDay, doneCallback) => # Needs date format yyyymmdd success = (data) => - return if @destroyed + return doneCallback() if @destroyed # console.log 'getCampaignLevelCompletions success', data countCompletions = (item) -> item.started = _.reduce item.days, ((result, current) -> result + current.started), 0 @@ -217,7 +234,7 @@ module.exports = class CampaignAnalyticsModal extends ModalView @campaignCompletions.top3DropPercentage = _.pluck sortedLevels[0..2], 'level' doneCallback() - return unless @campaignCompletions?.levels? + return doneCallback() unless @campaignCompletions?.levels? levelSlugs = _.pluck @campaignCompletions.levels, 'level' request = @supermodel.addRequestResource 'level_drops', { @@ -227,3 +244,28 @@ module.exports = class CampaignAnalyticsModal extends ModalView success: success }, 0 request.load() + + getCampaignLevelSubscriptions: (startDay, endDay, doneCallback) => + # Fetch level subscriptions + # Needs date format yyyymmdd + success = (data) => + return doneCallback() if @destroyed + # console.log 'getCampaignLevelSubscriptions success', data + levelSubs = {} + for item in data + levelSubs[item.level] = shown: item.shown, purchased: item.purchased + for level in @campaignCompletions.levels + level.subsShown = levelSubs[level.level]?.shown + level.subsPurchased = levelSubs[level.level]?.purchased + doneCallback() + + return doneCallback() unless @campaignCompletions?.levels? + levelSlugs = _.pluck @campaignCompletions.levels, 'level' + + request = @supermodel.addRequestResource 'campaign_subscriptions', { + url: '/db/analytics_perday/-/level_subscriptions' + data: {startDay: startDay, endDay: endDay, slugs: levelSlugs} + method: 'POST' + success: success + }, 0 + request.load() diff --git a/scripts/analytics/mongodb/queries/insertPerDayAnalytics.js b/scripts/analytics/mongodb/queries/insertPerDayAnalytics.js index 20ab3c854..dcc26cd8a 100644 --- a/scripts/analytics/mongodb/queries/insertPerDayAnalytics.js +++ b/scripts/analytics/mongodb/queries/insertPerDayAnalytics.js @@ -16,10 +16,80 @@ // TODO: Are Mixpanel rates accounting for finishing steps likely to be completed in the future? // TODO: Use Mixpanel export API to investigate -// TODO: Output documents updated/inserted +try { + var scriptStartTime = new Date(); + var analyticsStringCache = {}; -var scriptStartTime = new Date(); -var analyticsStringCache = {}; + // Look at last 30 days, same as Mixpanel + var numDays = 30; + + var startDay = new Date(); + today = startDay.toISOString().substr(0, 10); + startDay.setUTCDate(startDay.getUTCDate() - numDays); + startDay = startDay.toISOString().substr(0, 10); + + var levelCompletionFunnel = ['Started Level', 'Saw Victory']; + var levelHelpEvents = ['Problem alert help clicked', 'Spell palette help clicked', 'Start help video']; + + log("Today is " + today); + log("Start day is " + startDay); + log("Funnel events are " + levelCompletionFunnel); + + log("Getting level completion data..."); + var levelCompletionData = getLevelFunnelData(startDay, levelCompletionFunnel); + log("Inserting aggregated level completion data..."); + for (level in levelCompletionData) { + for (day in levelCompletionData[level]) { + if (today === day) continue; // Never save data for today because it's incomplete + for (event in levelCompletionData[level][day]) { + insertEventCount(event, level, day, levelCompletionData[level][day][event]); + } + } + } + + log("Getting level drop counts..."); + var levelDropCounts = getLevelDropCounts(startDay, levelCompletionFunnel); + log("Inserting level drop counts..."); + for (level in levelDropCounts) { + for (day in levelDropCounts[level]) { + if (today === day) continue; // Never save data for today because it's incomplete + insertEventCount('User Dropped', level, day, levelDropCounts[level][day]); + } + } + + log("Getting level help counts..."); + var levelHelpCounts = getLevelHelpCounts(startDay, levelHelpEvents); + log("Inserting level help counts..."); + for (level in levelHelpCounts) { + for (day in levelHelpCounts[level]) { + if (today === day) continue; // Never save data for today because it's incomplete + for (event in levelHelpCounts[level][day]) { + insertEventCount(event, level, day, levelHelpCounts[level][day][event]); + } + } + } + + log("Getting level subscription counts..."); + var levelSubscriptionCounts = getLevelSubscriptionCounts(startDay); + log("Inserting level subscription counts..."); + for (level in levelSubscriptionCounts) { + for (day in levelSubscriptionCounts[level]) { + if (today === day) continue; // Never save data for today because it's incomplete + for (event in levelSubscriptionCounts[level][day]) { + insertEventCount(event, level, day, levelSubscriptionCounts[level][day][event]); + } + } + } + + log("Script runtime: " + (new Date() - scriptStartTime)); +} +catch(err) { + log("ERROR: " + err); + printjson(err); +} + + +// *** Helper functions *** function log(str) { print(new Date().toISOString() + " " + str); @@ -229,6 +299,82 @@ function getLevelHelpCounts(startDay, events) { return levelEventData; } +function getLevelSubscriptionCounts(startDay) { + // Counts subscriptions shown per day, only for events that have levels + // Subscription purchased event counts are attributed to last shown subscription modal event's day and level + if (!startDay) return {}; + + var startObj = objectIdWithTimestamp(ISODate(startDay + "T00:00:00.000Z")); + var queryParams = {$and: [ + {_id: {$gte: startObj}}, + {$or: [ + {$and: [{'event': 'Show subscription modal'}, {'properties.level': {$exists: true}}]}, + {'event': 'Finished subscription purchase'}] + } + ]}; + var cursor = db['analytics.log.events'].find(queryParams); + + // Map ordering: user, event, level, day + // Map ordering: user, event, day + var userDataMap = {}; + while (cursor.hasNext()) { + var doc = cursor.next(); + var created = doc._id.getTimestamp().toISOString(); + var day = created.substring(0, 10); + var event = doc.event; + var user = doc.user; + + if (!userDataMap[user]) userDataMap[user] = {}; + + if (event === 'Show subscription modal') { + var level = doc.properties.level; + + // TODO: This is for legacy data. + // TODO: Event tracking updated to use level slug for loading level view on ~1/21/15 + level = level.toLowerCase().replace(/ /g, '-'); + + if (!userDataMap[user][event]) userDataMap[user][event] = {}; + if (!userDataMap[user][event][level] || userDataMap[user][event][level].localeCompare(day) > 0) { + userDataMap[user][event][level] = day; + } + } + else if (event === 'Finished subscription purchase') { + if (!userDataMap[user][event] || userDataMap[user][event].localeCompare(day) > 0) { + userDataMap[user][event] = day; + } + } else { + continue; + } + } + + // Data: level, day, event + var levelFunnelData = {}; + for (user in userDataMap) { + if (userDataMap[user]['Show subscription modal']) { + var lastDay = null; + var lastLevel = null; + for (level in userDataMap[user]['Show subscription modal']) { + var day = userDataMap[user]['Show subscription modal'][level]; + if (!lastDay || lastDay.localeCompare(day) > 0) { + lastDay = day; + lastLevel = level; + } + if (!levelFunnelData[level]) levelFunnelData[level] = {}; + if (!levelFunnelData[level][day]) levelFunnelData[level][day] = {}; + if (!levelFunnelData[level][day][event]) levelFunnelData[level][day]['Show subscription modal'] = 0; + levelFunnelData[level][day]['Show subscription modal']++; + } + if (lastDay && userDataMap[user]['Finished subscription purchase']) { + if (!levelFunnelData[lastLevel][lastDay]['Finished subscription purchase']) { + levelFunnelData[lastLevel][lastDay]['Finished subscription purchase'] = 0; + } + levelFunnelData[lastLevel][lastDay]['Finished subscription purchase']++; + } + } + } + return levelFunnelData; +} + function insertEventCount(event, level, day, count) { // analytics.perdays schema in server/analytics/AnalyticsPeryDay.coffee day = day.replace(/-/g, ''); @@ -264,60 +410,3 @@ function insertEventCount(event, level, day, count) { // } } } - -try { - // Look at last 30 days, same as Mixpanel - var numDays = 30; - - var startDay = new Date(); - today = startDay.toISOString().substr(0, 10); - startDay.setUTCDate(startDay.getUTCDate() - numDays); - startDay = startDay.toISOString().substr(0, 10); - - var levelCompletionFunnel = ['Started Level', 'Saw Victory']; - var levelHelpEvents = ['Problem alert help clicked', 'Spell palette help clicked', 'Start help video']; - - log("Today is " + today); - log("Start day is " + startDay); - log("Funnel events are " + levelCompletionFunnel); - - log("Getting level completion data..."); - var levelCompletionData = getLevelFunnelData(startDay, levelCompletionFunnel); - log("Inserting aggregated level completion data..."); - for (level in levelCompletionData) { - for (day in levelCompletionData[level]) { - if (today === day) continue; // Never save data for today because it's incomplete - for (event in levelCompletionData[level][day]) { - insertEventCount(event, level, day, levelCompletionData[level][day][event]); - } - } - } - - log("Getting level drop counts..."); - var levelDropCounts = getLevelDropCounts(startDay, levelCompletionFunnel) - log("Inserting level drop counts..."); - for (level in levelDropCounts) { - for (day in levelDropCounts[level]) { - if (today === day) continue; // Never save data for today because it's incomplete - insertEventCount('User Dropped', level, day, levelDropCounts[level][day]); - } - } - - log("Getting level help counts..."); - var levelHelpCounts = getLevelHelpCounts(startDay, levelHelpEvents) - log("Inserting level help counts..."); - for (level in levelHelpCounts) { - for (day in levelHelpCounts[level]) { - if (today === day) continue; // Never save data for today because it's incomplete - for (event in levelHelpCounts[level][day]) { - insertEventCount(event, level, day, levelHelpCounts[level][day][event]); - } - } - } -} -catch(err) { - log("ERROR: " + err); - printjson(err); -} - -log("Script runtime: " + (new Date() - scriptStartTime)); \ No newline at end of file diff --git a/server/analytics/analytics_perday_handler.coffee b/server/analytics/analytics_perday_handler.coffee index e5e4a8e31..e64f6b7bf 100644 --- a/server/analytics/analytics_perday_handler.coffee +++ b/server/analytics/analytics_perday_handler.coffee @@ -10,13 +10,15 @@ class AnalyticsPerDayHandler extends Handler jsonSchema: require '../../app/schemas/models/analytics_perday' hasAccess: (req) -> - req.method in ['GET'] or req.user?.isAdmin() + req.user?.isAdmin() or false getByRelationship: (req, res, args...) -> + return @sendForbiddenError res unless @hasAccess req return @getCampaignCompletionsBySlug(req, res) if args[1] is 'campaign_completions' return @getLevelCompletionsBySlug(req, res) if args[1] is 'level_completions' return @getLevelDropsBySlugs(req, res) if args[1] is 'level_drops' return @getLevelHelpsBySlugs(req, res) if args[1] is 'level_helps' + return @getLevelSubscriptionsBySlugs(req, res) if args[1] is 'level_subscriptions' super(arguments...) getCampaignCompletionsBySlug: (req, res) -> @@ -334,4 +336,73 @@ class AnalyticsPerDayHandler extends Handler @levelHelpsCache[cacheKey] = helps @sendSuccess res, helps + + getLevelSubscriptionsBySlugs: (req, res) -> + # Send back an array of level subscriptions shown and purchased counts + # Parameters: + # slugs - level slugs + # startDay - Inclusive, optional, YYYYMMDD e.g. '20141214' + # endDay - Exclusive, optional, YYYYMMDD e.g. '20141216' + + levelSlugs = req.query.slugs or req.body.slugs + startDay = req.query.startDay or req.body.startDay + endDay = req.query.endDay or req.body.endDay + + # log.warn "level_subscriptions levelSlugs='#{levelSlugs}' startDay=#{startDay} endDay=#{endDay}" + + return @sendSuccess res, [] unless levelSlugs? + + # Cache results in app server memory for 1 day + @levelSubscriptionsCache ?= {} + @levelSubscriptionsCachedSince ?= new Date() + if (new Date()) - @levelSubscriptionsCachedSince > 86400 * 1000 + @levelSubscriptionsCache = {} + @levelSubscriptionsCachedSince = new Date() + cacheKey = levelSlugs.join '' + cacheKey += 's' + startDay if startDay? + cacheKey += 'e' + endDay if endDay? + return @sendSuccess res, subscriptions if subscriptions = @levelSubscriptionsCache[cacheKey] + + findQueryParams = {v: {$in: ['Show subscription modal', 'Finished subscription purchase', 'all'].concat(levelSlugs)}} + AnalyticsString.find(findQueryParams).exec (err, documents) => + if err? then return @sendDatabaseError res, err + + levelStringIDSlugMap = {} + for doc in documents + showSubEventID = doc._id if doc.v is 'Show subscription modal' + finishSubEventID = doc._id if doc.v is 'Finished subscription purchase' + filterEventID = doc._id if doc.v is 'all' + levelStringIDSlugMap[doc._id] = doc.v if doc.v in levelSlugs + + return @sendSuccess res, [] unless showSubEventID? and finishSubEventID? and filterEventID? + + queryParams = {$and: [ + {e: {$in: [showSubEventID, finishSubEventID]}}, + {f: filterEventID}, + {l: {$in: Object.keys(levelStringIDSlugMap)}} + ]} + queryParams["$and"].push {d: {$gte: startDay}} if startDay? + queryParams["$and"].push {d: {$lt: endDay}} if endDay? + AnalyticsPerDay.find(queryParams).exec (err, documents) => + if err? then return @sendDatabaseError res, err + + levelEventCounts = {} + for doc in documents + levelEventCounts[doc.l] ?= {} + levelEventCounts[doc.l][doc.e] ?= 0 + levelEventCounts[doc.l][doc.e] += doc.c + + subscriptions = [] + for levelID of levelEventCounts + for eventID of levelEventCounts[levelID] + subsShown = levelEventCounts[levelID][eventID] if parseInt(eventID) is showSubEventID + subsPurchased = levelEventCounts[levelID][eventID] if parseInt(eventID) is finishSubEventID + subscriptions.push + level: levelStringIDSlugMap[levelID] + shown: subsShown ? 0 + purchased: subsPurchased ? 0 + + @levelSubscriptionsCache[cacheKey] = subscriptions + @sendSuccess res, subscriptions + module.exports = new AnalyticsPerDayHandler() diff --git a/server/user_code_problems/user_code_problem_handler.coffee b/server/user_code_problems/user_code_problem_handler.coffee index 6c293f727..9ce2cbe7e 100644 --- a/server/user_code_problems/user_code_problem_handler.coffee +++ b/server/user_code_problems/user_code_problem_handler.coffee @@ -24,7 +24,11 @@ class UserCodeProblemHandler extends Handler ucp.set('creator', req.user._id) ucp + hasAccess: (req) -> + req.user?.isAdmin() or false + getByRelationship: (req, res, args...) -> + return @sendForbiddenError res unless @hasAccess req return @getCommonLevelProblemsBySlug(req, res) if args[1] is 'common_problems' super(arguments...) From 82bc526bd71d45d2270f1b22ebd323dee80bc3fa Mon Sep 17 00:00:00 2001 From: Maks Lyashuk Date: Thu, 22 Jan 2015 00:17:03 +0200 Subject: [PATCH 06/18] Update Ukrainian l18n Translated some new lines --- app/locale/uk.coffee | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index ab5e0e0ab..0db709506 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -81,7 +81,7 @@ module.exports = nativeDescription: "Українська", englishDescription: awaiting_levels_adventurer_prefix: "Ми випускаємо 5 рівнів на тиждень." awaiting_levels_adventurer: "Увійди як Шукач пригод" awaiting_levels_adventurer_suffix: "стань одним з перших, хто їх спробує." -# adjust_volume: "Adjust volume" + adjust_volume: "Підлаштувати гучність" choose_your_level: "Оберіть свій рівень" # The rest of this section is the old play view at /play-old and isn't very important. adventurer_prefix: "Ви можете грати у будь-який рівень з наведених нижче або обговорювати рівні на " adventurer_forum: "форумі Шукачів пригод" @@ -160,21 +160,21 @@ module.exports = nativeDescription: "Українська", englishDescription: date: "Дата" body: "Тіло" version: "Версія" -# pending: "Pending" -# accepted: "Accepted" -# rejected: "Rejected" + pending: "Очікування" + accepted: "Прийнято" + rejected: "Відхилено" # withdrawn: "Withdrawn" # submitter: "Submitter" -# submitted: "Submitted" + submitted: "Відправлено" commit_msg: "Доручити повідомлення" review: "Огляд" version_history: "Історія" version_history_for: "Історія версій для: " select_changes: "Оберіть дві зміни нижче, щоб побачити відмінності." -# undo_prefix: "Undo" -# undo_shortcut: "(Ctrl+Z)" -# redo_prefix: "Redo" -# redo_shortcut: "(Ctrl+Shift+Z)" + undo_prefix: "Відмінити" + undo_shortcut: "(Ctrl+Z)" + redo_prefix: "Повторити" + redo_shortcut: "(Ctrl+Shift+Z)" play_preview: "Попередній перегляд поточного рівня" result: "Результат" results: "Результати" @@ -198,9 +198,9 @@ module.exports = nativeDescription: "Українська", englishDescription: hard: "Важкий" player: "Гравець" player_level: "Рівень" # Like player level 5, not like level: Dungeons of Kithgard -# warrior: "Warrior" + warrior: "Воїн" # ranger: "Ranger" -# wizard: "Wizard" + wizard: "Чаклун" units: second: "Секунда" @@ -323,8 +323,8 @@ module.exports = nativeDescription: "Українська", englishDescription: save_load_tab: "Зберегти/Завантажити" options_tab: "Параметри" guide_tab: "Довідник" - guide_video_tutorial: "Відео Посібник" -# guide_tips: "Tips" + guide_video_tutorial: "Відео-посібник" + guide_tips: "Поради" multiplayer_tab: "Мультиплеєр" auth_tab: "Вийти" inventory_caption: "Екіпіруйте свого героя" @@ -338,7 +338,7 @@ module.exports = nativeDescription: "Українська", englishDescription: inventory: choose_inventory: "Екіпіруйте предмети" equipped_item: "Екіпіровано" -# required_purchase_title: "Required" + required_purchase_title: "Потребує" available_item: "Доступно" restricted_title: "Обмежено" should_equip: "(предмети одягаються подвійним кліком)" @@ -480,7 +480,7 @@ module.exports = nativeDescription: "Українська", englishDescription: versions: save_version_title: "Зберегти нову версію" new_major_version: "Зберегти основну версію" -# submitting_patch: "Submitting Patch..." + submitting_patch: "Відправка патчу..." cla_prefix: "Для збереження змін спочатку треба погодитись з нашим" cla_url: "CLA" cla_suffix: "." @@ -493,12 +493,12 @@ module.exports = nativeDescription: "Українська", englishDescription: forum_page: "наш форум" forum_suffix: "." # faq_prefix: "There's also a" -# faq: "FAQ" + faq: "ЧаПи" # subscribe_prefix: "If you need help figuring out a level, please" # subscribe: "buy a CodeCombat subscription" # subscribe_suffix: "and we'll be happy to help you with your code." # subscriber_support: "Since you're a CodeCombat subscriber, your email will get our priority support." -# screenshot_included: "Screenshot included." + screenshot_included: "Приєднано зняток." where_reply: "Куди ми повинні відповісти?" send: "Надіслати відгук" contact_candidate: "Сконтактуватися з кандидатом" # Deprecated @@ -583,7 +583,7 @@ module.exports = nativeDescription: "Українська", englishDescription: classes: archmage_title: "Архімаг" archmage_title_description: "(Програміст)" -# archmage_summary: "If you are a developer interested in coding educational games, become an archmage to help us build CodeCombat!" + archmage_summary: "Якщо ви зацікавлені в програмуванні навчальних ігор, станьте архімагом аби допомогти нам створювати CodeCombat!" artisan_title: "Ремісник" artisan_title_description: "(Створювач рівнів)" # artisan_summary: "Build and share levels for you and your friends to play. Become an Artisan to learn the art of teaching others to program." @@ -592,10 +592,10 @@ module.exports = nativeDescription: "Українська", englishDescription: # adventurer_summary: "Get our new levels (even our subscriber content) for free one week early and help us work out bugs before our public release." scribe_title: "Писар" scribe_title_description: "(Редактор статей)" -# scribe_summary: "Good code needs good documentation. Write, edit, and improve the docs read by millions of players across the globe." + scribe_summary: "Хороший код потребує хорошої документації. Пишіть, редагуйте, та покращуйте документацію, яку побачать мільйони гравців зі всього світу." diplomat_title: "Дипломат" diplomat_title_description: "(Перекладач)" -# diplomat_summary: "CodeCombat is localized in 45+ languages by our Diplomats. Help us out and contribute translations." + diplomat_summary: "За допомогою наших дипломатів CodeCombat локалізовано більш ніж 45 мовами. Ви також можете допомогти з перекладом." ambassador_title: "Посланець" ambassador_title_description: "(Підтримка)" # ambassador_summary: "Tame our forum users and provide direction for those with questions. Our ambassadors represent CodeCombat to the world." @@ -610,12 +610,12 @@ module.exports = nativeDescription: "Українська", englishDescription: revert: "Повернутись" revert_models: "Моделі повернення" pick_a_terrain: "Обрати лашдшафт" -# dungeon: "Dungeon" -# indoor: "Indoor" -# desert: "Desert" + dungeon: "Темниця" + indoor: "Кімната" + desert: "Пустеля" grassy: "Подвір'я" small: "Малий" -# large: "Large" + large: "Великий" fork_title: "Форк нової версії" fork_creating: "Створення форку..." generate_terrain: "Згенерувати ландшафт" @@ -636,12 +636,12 @@ module.exports = nativeDescription: "Українська", englishDescription: level_tab_thangs_all: "Усі" level_tab_thangs_conditions: "Початковий статус" level_tab_thangs_add: "Додати об'єкти" -# add_components: "Add Components" -# component_configs: "Component Configurations" + add_components: "Додати коментарі" + component_configs: "Налаштування компонента" # config_thang: "Double click to configure a thang" delete: "Видалити" - duplicate: "Дублікат" -# stop_duplicate: "Stop Duplicate" + duplicate: "Дублювати" + stop_duplicate: "Зупинити дублювання" rotate: "Повернути" level_settings_title: "Налаштування" level_component_tab_title: "Поточні компоненти" @@ -676,7 +676,7 @@ module.exports = nativeDescription: "Українська", englishDescription: achievement_query_goals: "Ключове досягнення випадає з цілей рівня" level_completion: "Рівень завершено" pop_i18n: "Додати I18N" -# tasks: "Tasks" + tasks: "Завдання" article: edit_btn_preview: "Перегляд" @@ -885,7 +885,7 @@ module.exports = nativeDescription: "Українська", englishDescription: leaderboard: "Таблиця лідерів" user_schema: "Схема користувача" user_profile: "Профайл користувача" -# patch: "Patch" + patch: "Патч" patches: "Патчі" patched_model: "Вихідний документ" model: "Модель" @@ -1069,7 +1069,7 @@ module.exports = nativeDescription: "Українська", englishDescription: # basics_looking_for_internship: "Internship" # basics_looking_for_help: "What kind of developer position do you want?" # name_header: "Fill in your name" -# name_anonymous: "Anonymous Developer" + name_anonymous: "Анонімний розробник" # name_help: "Name you want employers to see, like 'Nick Winter'." # short_description_header: "Write a short description of yourself" # short_description_blurb: "Add a tagline to help an employer quickly learn more about you." From 3f40364616d7a8ae1026364211d896d6361b89e2 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Wed, 21 Jan 2015 16:03:50 -0800 Subject: [PATCH 07/18] Update campaign editor analytics Add date range picker to level view. --- .../editor/campaign/campaign-level-view.jade | 92 ++++++------ .../campaign/CampaignAnalyticsModal.coffee | 10 +- .../editor/campaign/CampaignLevelView.coffee | 136 +++++++++++------- 3 files changed, 137 insertions(+), 101 deletions(-) diff --git a/app/templates/editor/campaign/campaign-level-view.jade b/app/templates/editor/campaign/campaign-level-view.jade index bf2f53a8a..9768d40cf 100644 --- a/app/templates/editor/campaign/campaign-level-view.jade +++ b/app/templates/editor/campaign/campaign-level-view.jade @@ -5,8 +5,15 @@ a(href="/editor/level/#{level.get('slug')}", target="_blank") (edit) p= level.get('description') + if analytics.startDay && analytics.endDay + .input-group.input-group-sm + input.form-control#input-startday(type='text', style='width:100px;', value=analytics.startDay) + input.form-control#input-endday(type='text', style='width:100px;', value=analytics.endDay) + button.btn.btn-default.btn-sm#reload-button(style='margin-left:10px;') Reload h4 Completion Rates - if levelCompletions + if analytics.levelCompletions.loading + div Loading... + else table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt') thead tr @@ -14,48 +21,43 @@ td Started td Finished td Completion % - if levelHelps && levelHelps.length === levelCompletions.length + if analytics.levelHelps.levels.length === analytics.levelCompletions.levels.length td Helps Clicked td Helps / Started td Help Videos td Videos / Started tbody - - for (var i = 0; i < levelCompletions.length; i++) + - for (var i = 0; i < analytics.levelCompletions.levels.length; i++) tr - td= levelCompletions[i].created - td= levelCompletions[i].started - td= levelCompletions[i].finished - td= levelCompletions[i].rate - if levelHelps && levelHelps.length === levelCompletions.length - td= levelHelps[i].alertHelps + levelHelps[i].paletteHelps - td= ((levelHelps[i].alertHelps + levelHelps[i].paletteHelps) / levelCompletions[i].started).toFixed(2) - td= levelHelps[i].videoStarts - td= (levelHelps[i].videoStarts / levelCompletions[i].started).toFixed(2) - else - div Loading... + td= analytics.levelCompletions.levels[i].created + td= analytics.levelCompletions.levels[i].started + td= analytics.levelCompletions.levels[i].finished + td= analytics.levelCompletions.levels[i].rate + if analytics.levelHelps.levels.length === analytics.levelCompletions.levels.length && analytics.levelCompletions.levels[i].created == analytics.levelHelps.levels[i].day + td= analytics.levelHelps.levels[i].alertHelps + analytics.levelHelps.levels[i].paletteHelps + td= ((analytics.levelHelps.levels[i].alertHelps + analytics.levelHelps.levels[i].paletteHelps) / analytics.levelCompletions.levels[i].started).toFixed(2) + td= analytics.levelHelps.levels[i].videoStarts + td= (analytics.levelHelps.levels[i].videoStarts / analytics.levelCompletions.levels[i].started).toFixed(2) h4 Average Playtimes - if levelPlaytimes + if analytics.levelPlaytimes.loading + div Loading... + else table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt') thead tr td Date td Average (s) tbody - - for (var i = 0; i < levelPlaytimes.length; i++) + - for (var i = 0; i < analytics.levelPlaytimes.levels.length; i++) tr - td= levelPlaytimes[i].created - td= levelPlaytimes[i].average.toFixed(2) - else - div Loading... + td= analytics.levelPlaytimes.levels[i].created + td= analytics.levelPlaytimes.levels[i].average.toFixed(2) h4 Common Problems - if commonProblems - if commonProblems.startDay - if commonProblems.endDay - div(style='font-size:10pt') #{commonProblems.startDay} to #{commonProblems.endDay} - else - div(style='font-size:10pt') #{commonProblems.startDay} to today + if analytics.commonProblems.loading + div Loading... + else table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt') thead tr @@ -64,18 +66,18 @@ td Error Hint td Count tbody - - for (var i = 0; i < commonProblems.length && i < 20; i++) + - for (var i = 0; i < analytics.commonProblems.levels.length && i < 20; i++) tr - td= commonProblems[i].language - td= commonProblems[i].message - td= commonProblems[i].hint - td= commonProblems[i].count - else - div Loading... + td= analytics.commonProblems.levels[i].language + td= analytics.commonProblems.levels[i].message + td= analytics.commonProblems.levels[i].hint + td= analytics.commonProblems.levels[i].count h4 Recent Sessions - if recentSessions - div(style='font-size:10pt') Latest #{recentSessions.length} sessions for this level + if analytics.recentSessions.loading + div Loading... + else + div(style='font-size:10pt') Latest #{analytics.recentSessions.levels.length} sessions for this level div(style='font-size:10pt') Double-click row to open player and session table.table.table-bordered.table-condensed.table-hover(style='font-size:10pt') thead @@ -87,19 +89,17 @@ td Complete td Changed tbody - - for (var i = 0; i < recentSessions.length; i++) - tr.recent-session(data-player-id=recentSessions[i].creator, data-session-id=recentSessions[i]._id) - td= recentSessions[i]._id - td= recentSessions[i].creatorName || recentSessions[i].creator - td= recentSessions[i].codeLanguage - td= recentSessions[i].playtime - if recentSessions[i].state && recentSessions[i].state.complete - td= recentSessions[i].state.complete + - for (var i = 0; i < analytics.recentSessions.levels.length; i++) + tr.recent-session(data-player-id=analytics.recentSessions.levels[i].creator, data-session-id=analytics.recentSessions.levels[i]._id) + td= analytics.recentSessions.levels[i]._id + td= analytics.recentSessions.levels[i].creatorName || analytics.recentSessions.levels[i].creator + td= analytics.recentSessions.levels[i].codeLanguage + td= analytics.recentSessions.levels[i].playtime + if analytics.recentSessions.levels[i].state && analytics.recentSessions.levels[i].state.complete + td= analytics.recentSessions.levels[i].state.complete else td false - td= recentSessions[i].changed - else - div Loading... + td= analytics.recentSessions.levels[i].changed if level.get('tasks') .tasks diff --git a/app/views/editor/campaign/CampaignAnalyticsModal.coffee b/app/views/editor/campaign/CampaignAnalyticsModal.coffee index 5356b308d..b4070ee00 100644 --- a/app/views/editor/campaign/CampaignAnalyticsModal.coffee +++ b/app/views/editor/campaign/CampaignAnalyticsModal.coffee @@ -25,9 +25,9 @@ module.exports = class CampaignAnalyticsModal extends ModalView getRenderData: -> c = super() - c.campaignCompletions = @campaignCompletions c.showLeftGame = @showLeftGame c.showSubscriptions = @showSubscriptions + c.campaignCompletions = @campaignCompletions c afterRender: -> @@ -124,13 +124,13 @@ module.exports = class CampaignAnalyticsModal extends ModalView # Chain these together so we can calculate relative metrics (e.g. left game per second) @getCampaignLevelCompletions startDay, endDay, () => - @render() + @render?() @getCompaignLevelDrops startDay, endDay, () => - @render() + @render?() @getCampaignAveragePlaytimes startDayDashed, endDayDashed, () => - @render() + @render?() @getCampaignLevelSubscriptions startDay, endDay, () => - @render() + @render?() getCampaignAveragePlaytimes: (startDay, endDay, doneCallback) => # Fetch level average playtimes diff --git a/app/views/editor/campaign/CampaignLevelView.coffee b/app/views/editor/campaign/CampaignLevelView.coffee index 9c384d82d..4efa73189 100644 --- a/app/views/editor/campaign/CampaignLevelView.coffee +++ b/app/views/editor/campaign/CampaignLevelView.coffee @@ -11,6 +11,7 @@ module.exports = class CampaignLevelView extends CocoView events: 'click .close': 'onClickClose' + 'click #reload-button': 'onClickReloadButton' 'dblclick .recent-session': 'onDblClickRecentSession' constructor: (options, @level) -> @@ -20,26 +21,28 @@ module.exports = class CampaignLevelView extends CocoView @listenToOnce @fullLevel, 'sync', => @render?() @levelSlug = @level.get('slug') - @getCommonLevelProblems() - @getLevelCompletions() - @getLevelHelps() - @getLevelPlaytimes() - @getRecentSessions() + @getAnalytics() getRenderData: -> c = super() c.level = if @fullLevel.loaded then @fullLevel else @level - c.commonProblems = @commonProblems - c.levelCompletions = @levelCompletions - c.levelHelps = @levelHelps - c.levelPlaytimes = @levelPlaytimes - c.recentSessions = @recentSessions + c.analytics = @analytics c + afterRender: -> + super() + $("#input-startday").datepicker dateFormat: "yy-mm-dd" + $("#input-endday").datepicker dateFormat: "yy-mm-dd" + onClickClose: -> @$el.addClass('hidden') @trigger 'hidden' + onClickReloadButton: () => + startDay = $('#input-startday').val() + endDay = $('#input-endday').val() + @getAnalytics startDay, endDay + onDblClickRecentSession: (e) -> # Admin view of players' code return unless me.isAdmin() @@ -48,91 +51,124 @@ module.exports = class CampaignLevelView extends CocoView session = new LevelSession _id: row.data 'session-id' @openModalView new ModelModal models: [session, player] - getCommonLevelProblems: -> - # Fetch last 30 days of common level problems - startDay = utils.getUTCDay -29 - startDay = "#{startDay[0..3]}-#{startDay[4..5]}-#{startDay[6..7]}" + getAnalytics: (startDay, endDay) => + if startDay? + startDayDashed = startDay + startDay = startDay.replace(/-/g, '') + else + startDay = utils.getUTCDay -14 + startDayDashed = "#{startDay[0..3]}-#{startDay[4..5]}-#{startDay[6..7]}" + if endDay? + endDayDashed = endDay + endDay = endDay.replace(/-/g, '') + else + endDay = utils.getUTCDay -1 + endDayDashed = "#{endDay[0..3]}-#{endDay[4..5]}-#{endDay[6..7]}" - success = (data) => - return if @destroyed - @commonProblems = data - @commonProblems.startDay = startDay + @analytics = + startDay: startDayDashed + endDay: endDayDashed + commonProblems: + levels: [] + loading: true + levelCompletions: + levels: [] + loading: true + levelHelps: + levels: [] + loading: true + levelPlaytimes: + levels: [] + loading: true + recentSessions: + levels: [] + loading: true + @render() + + @getCommonLevelProblems startDayDashed, endDayDashed, () => + @analytics.commonProblems.loading = false @render() + @getLevelCompletions startDay, endDay, () => + @analytics.levelCompletions.loading = false + @render() + @getLevelHelps startDay, endDay, () => + @analytics.levelHelps.loading = false + @render() + @getLevelPlaytimes startDayDashed, endDayDashed, () => + @analytics.levelPlaytimes.loading = false + @render() + @getRecentSessions () => + @analytics.recentSessions.loading = false + @render() + + getCommonLevelProblems: (startDay, endDay, doneCallback) -> + success = (data) => + return doneCallback() if @destroyed + @analytics.commonProblems.levels = data + doneCallback() # TODO: Why do we need this url dash? request = @supermodel.addRequestResource 'common_problems', { url: '/db/user_code_problem/-/common_problems' - data: {startDay: startDay, slug: @levelSlug} + data: {startDay: startDay, endDay: endDay, slug: @levelSlug} method: 'POST' success: success }, 0 request.load() - getLevelCompletions: -> - # Fetch last 14 days of level completion counts + getLevelCompletions: (startDay, endDay, doneCallback) -> success = (data) => - return if @destroyed + return doneCallback() if @destroyed data.sort (a, b) -> if a.created < b.created then 1 else -1 mapFn = (item) -> item.rate = (item.finished / item.started * 100).toFixed(2) item - @levelCompletions = _.map data, mapFn, @ - @render() + @analytics.levelCompletions.levels = _.map data, mapFn, @ + doneCallback() - startDay = utils.getUTCDay -14 - - # TODO: Why do we need this url dash? request = @supermodel.addRequestResource 'level_completions', { url: '/db/analytics_perday/-/level_completions' - data: {startDay: startDay, slug: @levelSlug} + data: {startDay: startDay, endDay: endDay, slug: @levelSlug} method: 'POST' success: success }, 0 request.load() - getLevelHelps: -> - # Fetch last 14 days of level completion counts + getLevelHelps: (startDay, endDay, doneCallback) -> success = (data) => - return if @destroyed - @levelHelps = data.sort (a, b) -> if a.created < b.created then 1 else -1 - @render() - - startDay = utils.getUTCDay -14 + return doneCallback() if @destroyed + @analytics.levelHelps.levels = data.sort (a, b) -> if a.day < b.day then 1 else -1 + doneCallback() request = @supermodel.addRequestResource 'level_helps', { url: '/db/analytics_perday/-/level_helps' - data: {startDay: startDay, slugs: [@levelSlug]} + data: {startDay: startDay, endDay: endDay, slugs: [@levelSlug]} method: 'POST' success: success }, 0 request.load() - getLevelPlaytimes: -> - # Fetch last 14 days of level average playtimes + getLevelPlaytimes: (startDay, endDay, doneCallback) -> success = (data) => - return if @destroyed - @levelPlaytimes = data.sort (a, b) -> if a.created < b.created then 1 else -1 - @render() + return doneCallback() if @destroyed + @analytics.levelPlaytimes.levels = data.sort (a, b) -> if a.created < b.created then 1 else -1 + doneCallback() - startDay = utils.getUTCDay -13 - startDay = "#{startDay[0..3]}-#{startDay[4..5]}-#{startDay[6..7]}" - - # TODO: Why do we need this url dash? request = @supermodel.addRequestResource 'playtime_averages', { url: '/db/level/-/playtime_averages' - data: {startDay: startDay, slugs: [@levelSlug]} + data: {startDay: startDay, endDay: endDay, slugs: [@levelSlug]} method: 'POST' success: success }, 0 request.load() - getRecentSessions: -> + getRecentSessions: (doneCallback) -> limit = 100 success = (data) => - return if @destroyed - @recentSessions = data - @render() + return doneCallback() if @destroyed + @analytics.recentSessions.levels = data + doneCallback() # TODO: Why do we need this url dash? request = @supermodel.addRequestResource 'level_sessions_recent', { From 1e5ef588d8912fc8936370b9ae89d775ddae6c1d Mon Sep 17 00:00:00 2001 From: z3t1 Date: Wed, 21 Jan 2015 20:56:13 -0500 Subject: [PATCH 08/18] Translation of several pharses --- app/locale/zh-HANS.coffee | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index ff34003ba..a46b4236c 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -853,9 +853,9 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese subscribed: "已订阅" unsubscribed: "取消订阅" # active_until: "Active Until" -# cost: "Cost" + cost: "花费" # next_payment: "Next Payment" -# card: "Card" + card: "银行卡" # status_unsubscribed_active: "You're not subscribed and won't be billed, but your account is still active for now." # status_unsubscribed: "Get access to new levels, heroes, items, and bonus gems with a CodeCombat subscription!" @@ -910,14 +910,14 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese # candidate_sessions: "Candidate Sessions" # user_remark: "User Remark" # user_remarks: "User Remarks" -# versions: "Versions" + versions: "版本" items: "物品" heroes: "英雄" achievement: "成就" # clas: "CLAs" # play_counts: "Play Counts" feedback: "反馈" -# payment_info: "Payment Info" + payment_info: "付款信息" delta: added: "被添加" @@ -1003,8 +1003,8 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese # blurb_3: "to the top human and ogre players." # blurb_4: "Two teams means double the prizes!" # blurb_5: "(There will be two first place winners, two second-place winners, etc.)" -# rank: "Rank" -# prizes: "Prizes" + rank: "排名" + prizes: "奖项" # total_value: "Total Value" # in_cash: "in cash" # custom_wizard: "Custom CodeCombat Wizard" @@ -1122,7 +1122,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese player_code: "玩家代码" employers: -# deprecation_warning_title: "Sorry, CodeCombat is not recruiting right now." + deprecation_warning_title: "抱歉,CodeCombat现不招募雇员。" # deprecation_warning: "We are focusing on beginner levels instead of finding expert developers for the time being." # hire_developers_not_credentials: "Hire developers, not credentials." # We are not actively recruiting right now, so there's no need to add new translations for the rest of this section. # get_started: "Get Started" @@ -1162,10 +1162,10 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese candidate_top_skills: "高级技能" candidate_years_experience: "多年工作经验" candidate_last_updated: "最后一次更新" -# candidate_who: "Who" -# featured_developers: "Featured Developers" -# other_developers: "Other Developers" -# inactive_developers: "Inactive Developers" + candidate_who: "谁?" + featured_developers: "主要开发者" + other_developers: "其他开发者" + inactive_developers: "不活跃的开发者" admin: # av_espionage: "Espionage" # Really not important to translate /admin controls. From 76906a15fcb5d8c4f3a71a17db3bb6dcccdee6a3 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Thu, 22 Jan 2015 16:28:27 +0000 Subject: [PATCH 09/18] Uncommented an header --- app/locale/zh-HANS.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index a46b4236c..f2d67915d 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -996,7 +996,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese nutshell_description: "我们在关卡编辑器里公开的任何资源,你都可以在制作关卡时随意使用,但我们保留限制在 codecombat.com 之上创建的关卡本身传播的权利,因为我们以后可能决定为它们收费。" canonical: "这篇说明的英文版本是权威版本。如果各个翻译版本之间有任何冲突,以英文版为准。" -# ladder_prizes: + ladder_prizes: # title: "Tournament Prizes" # This section was for an old tournament and doesn't need new translations now. # blurb_1: "These prizes will be awarded according to" # blurb_2: "the tournament rules" From 9e496fa9d0f3c2bf719c8638f0119ac854bc8c2e Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 22 Jan 2015 10:45:51 -0800 Subject: [PATCH 10/18] Propagated i18n. --- 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/el.coffee | 6 ++++++ app/locale/en-AU.coffee | 6 ++++++ app/locale/en-GB.coffee | 6 ++++++ app/locale/en-US.coffee | 6 ++++++ app/locale/en.coffee | 1 - app/locale/es-419.coffee | 6 ++++++ app/locale/es-ES.coffee | 6 ++++++ app/locale/fa.coffee | 6 ++++++ app/locale/fi.coffee | 6 ++++++ app/locale/fr.coffee | 6 ++++++ app/locale/gl.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/mk-MK.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/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/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/templates/play/level/level_loading.jade | 1 - 53 files changed, 306 insertions(+), 2 deletions(-) diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee index 2c19ce4ba..f68d84aa2 100644 --- a/app/locale/ar.coffee +++ b/app/locale/ar.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index 03ceb222f..174b50364 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "български език", englishDescri # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index ae976b599..dafa65cb3 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventari" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index c73feea71..0c2525177 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr tip_brute_force: "V případě pochybností, použijte brute force. - Ken Thompson" tip_extrapolation: "Jsou jenom dva druhy lidí: ti, kteří mohou extrapolovat z nekompletních dat..." tip_superpower: "Kódování by se téměř dalo srovnávat se superschopnostmi." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventář" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index 648af1103..8af523f98 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee index e88897078..e71c8cab8 100644 --- a/app/locale/de-AT.coffee +++ b/app/locale/de-AT.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription: tip_brute_force: "Im Zweifelsfall, verwende rohe Gewalt. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventar" diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee index cd75892d1..af3da25d4 100644 --- a/app/locale/de-CH.coffee +++ b/app/locale/de-CH.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee index 3b08aa1eb..2a132310e 100644 --- a/app/locale/de-DE.coffee +++ b/app/locale/de-DE.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription: tip_brute_force: "Verwende im Zweifelsfall rohe Gewalt. - Ken Thompson" tip_extrapolation: "Es gibt nur zwei Sorten Menschen, diejenigen die aus unvollständigen Informationen Schlüsse ziehen können, ..." tip_superpower: "Programmieren ist das näheste zu einer Superkraft was wir haben." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventar" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index 63137a46c..01ecbc9ba 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee index ab137afb0..2d9895185 100644 --- a/app/locale/en-AU.coffee +++ b/app/locale/en-AU.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee index d9c693e9f..f8d610ac6 100644 --- a/app/locale/en-GB.coffee +++ b/app/locale/en-GB.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee index f9529bf59..d46ad4830 100644 --- a/app/locale/en-US.coffee +++ b/app/locale/en-US.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 991579ff7..2d3e8b8bf 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -317,7 +317,6 @@ tip_brute_force: "When in doubt, use brute force. - Ken Thompson" tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." tip_superpower: "Coding is the closest thing we have to a superpower." - tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" tip_no_code: "No code is faster than no code." tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 3fb918551..b2685ad0e 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip tip_brute_force: "Cuando tengas duda, usa la fuerza bruta. - Ken Thompson" tip_extrapolation: "Solo hay dos tipos de personas: Esas que pueden extrapolar desde información incompleta..." tip_superpower: "Programar es lo más cercano que tenemos a superpoderes." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventario" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index a50fd54e4..97cec6451 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis tip_brute_force: "Cuando haya dudas, usa la fuerza bruta. - Ken Thompson" tip_extrapolation: "Existen solo dos clases de personas: aquellos que pueden extrapolar desde información incompleta..." tip_superpower: "Programar es lo más parecido que tenemos a un superpoder." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventario" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index f5bc6321f..1c8f2ec15 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee index 7b15bb491..53725ee44 100644 --- a/app/locale/fi.coffee +++ b/app/locale/fi.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index 3f19d87dd..aca640269 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "français", englishDescription: "French", t tip_brute_force: "En cas de doute, utiliser la force brute. - Ken Thompson" tip_extrapolation: "Il y a seulement deux types de personnes : celles qui peuvent extrapoler à partir de données incomplètes..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventaire" diff --git a/app/locale/gl.coffee b/app/locale/gl.coffee index 809da3752..ba3431b37 100644 --- a/app/locale/gl.coffee +++ b/app/locale/gl.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Galego", englishDescription: "Galician", tr tip_brute_force: "Cando haxa dúbidas, usa a forza bruta. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventario" diff --git a/app/locale/he.coffee b/app/locale/he.coffee index d1da7f4d1..528091743 100644 --- a/app/locale/he.coffee +++ b/app/locale/he.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee index 068ff62a2..d46f87b1c 100644 --- a/app/locale/hi.coffee +++ b/app/locale/hi.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 90462030e..571487c20 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t tip_brute_force: "Ha kérdésesa helyzet, használj nyers erőt. - Ken Thompson" tip_extrapolation: "Csak két fajta ember létezik. Az egyik, aki extrapolál hiányos adatokból..." tip_superpower: "A programozás képessége van legközelebb a szuperképességekhez." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Raktár" diff --git a/app/locale/id.coffee b/app/locale/id.coffee index dd47d7a6c..b1ce678b6 100644 --- a/app/locale/id.coffee +++ b/app/locale/id.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index e52f60d8b..3ca374748 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventario" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index b54f9b978..e9ec27d6a 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index 667d07259..3a008703f 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee index 99584311f..bfa2080f9 100644 --- a/app/locale/lt.coffee +++ b/app/locale/lt.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/mk-MK.coffee b/app/locale/mk-MK.coffee index 985ed75d6..9ba6f031f 100644 --- a/app/locale/mk-MK.coffee +++ b/app/locale/mk-MK.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Македонски", englishDescription: tip_brute_force: "Кога не си сигурен, користи 'brute force'. - Ken Thompson" tip_extrapolation: "Има само два вида на луѓе: оние кои можат да екстраполираат од некомплетни податоци..." tip_superpower: "Програмирањето е способност, најблиска до супермоќ, која ја имаме." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee index 407abffdf..9ea609566 100644 --- a/app/locale/ms.coffee +++ b/app/locale/ms.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index 410547ac2..ad7beb61b 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Utstyr" diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee index 37a35325e..364943354 100644 --- a/app/locale/nl-BE.coffee +++ b/app/locale/nl-BE.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription: tip_brute_force: "Als je twijfelt, gebruik brute kracht. - Ken Thompson" tip_extrapolation: "Er zijn maar 2 soorten van mensen: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventaris" diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee index ad1768462..65635198b 100644 --- a/app/locale/nl-NL.coffee +++ b/app/locale/nl-NL.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventaris" diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee index 8889adacf..abd524c7f 100644 --- a/app/locale/nn.coffee +++ b/app/locale/nn.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/no.coffee b/app/locale/no.coffee index fb1ccb98d..72c06c055 100644 --- a/app/locale/no.coffee +++ b/app/locale/no.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index b006b626f..d5f1e561d 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Ekwipunek" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 2e0a4e7d3..344b6fb29 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Português do Brasil", englishDescription: tip_brute_force: "Na dúvida, utilize força bruta. - Ken Thompson" tip_extrapolation: "Existem dois tipos de pessoa: aqueles que podem extrapolar apartir de dados incompletos..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventário" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 0a074fb9d..68321b293 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: tip_brute_force: "Quando em dúvida, usa a força bruta. - Ken Thompson" tip_extrapolation: "Há apenas dois tipos de pessoas: aquelas que conseguem tirar uma conclusão a partir de dados reduzidos..." tip_superpower: "A programação é a coisa mais próxima de um superpoder que temos." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Inventário" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index 0a68dc1db..e32acaa71 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 8eefec3d4..301b96016 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi tip_brute_force: "Когда сомневаешься используй грубую силу. - Кен Томпсон" tip_extrapolation: "Есть два типа людей: те, кто могут экстраполировать неполные данные..." tip_superpower: "Программирование делает нас ближе к обретению суперсилы." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Инвентарь" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 9e05f1cb5..ec2b802fa 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee index 033a62236..212f332fe 100644 --- a/app/locale/sl.coffee +++ b/app/locale/sl.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index 08b74d065..a0981e382 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index b19000637..b8cb962a3 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Utrustning" diff --git a/app/locale/th.coffee b/app/locale/th.coffee index 2d3bc0a9e..65d00e52f 100644 --- a/app/locale/th.coffee +++ b/app/locale/th.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index fd5674e03..74d380c75 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Envanter" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index 0db709506..4454a735b 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Українська", englishDescription: tip_brute_force: "Якщо Ви сумніваєтеся, використовуйте перебір - Кен Томсон" tip_extrapolation: "Існує 2 типи людей: які можуть екстраполюватись від неповних даних..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "Інвентар" diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee index c0beb3d95..535006934 100644 --- a/app/locale/ur.coffee +++ b/app/locale/ur.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu", # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 18ab57c14..51704b410 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index f2d67915d..b769ca7cb 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese tip_brute_force: "拿不准时就用穷举法。 - Ken Thompson" tip_extrapolation: "世界上只有两类人:一类人能够根据不完整的数据进行推断……" tip_superpower: "编程是我们拥有的最接近超能力的技能" +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "道具箱" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index dca4b4c75..c0cd308cd 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: inventory_tab: "倉庫" diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee index 4ddd75140..beea36af1 100644 --- a/app/locale/zh-WUU-HANS.coffee +++ b/app/locale/zh-WUU-HANS.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # game_menu: # inventory_tab: "Inventory" diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee index 9c1baa0af..c0e2deb40 100644 --- a/app/locale/zh-WUU-HANT.coffee +++ b/app/locale/zh-WUU-HANT.coffee @@ -317,6 +317,12 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio # tip_brute_force: "When in doubt, use brute force. - Ken Thompson" # tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..." # tip_superpower: "Coding is the closest thing we have to a superpower." +# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" +# tip_no_code: "No code is faster than no code." +# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" +# tip_reusable_software: "Before software can be reusable it first has to be usable." +# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" +# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" game_menu: # inventory_tab: "Inventory" diff --git a/app/templates/play/level/level_loading.jade b/app/templates/play/level/level_loading.jade index 78ebd6154..40fb053e1 100644 --- a/app/templates/play/level/level_loading.jade +++ b/app/templates/play/level/level_loading.jade @@ -57,7 +57,6 @@ strong.tip.rare span(data-i18n='play_level.tip_harry') Yer a Wizard, span= me.get('name', true) - strong.tip.rare(data-i18n='play_level.tip_control_destiny') In real open source, you have the right to control your own destiny. - Linus Torvalds strong.tip.rare(data-i18n='play_level.tip_no_code') No code is faster than no code. strong.tip.rare(data-i18n='play_level.tip_code_never_lies') Code never lies, comments sometimes do. — Ron Jeffries From e49a70a62e7ff0806641e749d705a8414d5372ed Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 22 Jan 2015 10:48:41 -0800 Subject: [PATCH 11/18] Fixed mountain map background ratio. --- app/views/play/CampaignView.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/play/CampaignView.coffee b/app/views/play/CampaignView.coffee index add5f3ff1..039436c52 100644 --- a/app/views/play/CampaignView.coffee +++ b/app/views/play/CampaignView.coffee @@ -340,7 +340,7 @@ module.exports = class CampaignView extends RootView onWindowResize: (e) => mapHeight = iPadHeight = 1536 - mapWidth = {dungeon: 2350, forest: 2500, desert: 2350}[@terrain] or 2350 + mapWidth = {dungeon: 2350, forest: 2500, auditions: 2500, desert: 2350, mountain: 2422}[@terrain] or 2350 aspectRatio = mapWidth / mapHeight pageWidth = @$el.width() pageHeight = @$el.height() From bb0a820638b498b3ce86f24c1baaea1ceefa86a9 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Thu, 22 Jan 2015 19:04:41 +0000 Subject: [PATCH 12/18] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 68321b293..573b1cbdc 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -317,12 +317,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: tip_brute_force: "Quando em dúvida, usa a força bruta. - Ken Thompson" tip_extrapolation: "Há apenas dois tipos de pessoas: aquelas que conseguem tirar uma conclusão a partir de dados reduzidos..." tip_superpower: "A programação é a coisa mais próxima de um superpoder que temos." -# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" -# tip_no_code: "No code is faster than no code." -# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" -# tip_reusable_software: "Before software can be reusable it first has to be usable." -# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" -# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" + tip_control_destiny: "Em open source a sério, tens o direito de controlares o teu próprio destino. - Linus Torvalds" + tip_no_code: "Nenhum código é mais rápido que código não existente." + tip_code_never_lies: "O código nunca mente, mas os comentários às vezes sim. — Ron Jeffries" + tip_reusable_software: "Antes de um software poder ser reutilizável, primeiro tem de ser utilizável." + tip_optimization_operator: "Todas as linguagens têm um operador de otimização. Na maior parte delas esse operador é ‘//’." + tip_lines_of_code: "Medir o progresso em programação pelo número de linhas de código é como medir o progresso da construção de um avião pelo peso. — Bill Gates" game_menu: inventory_tab: "Inventário" @@ -727,7 +727,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the " # scribe_introduction_url_mozilla: "Mozilla Developer Network" # scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you." -# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others." + scribe_attribute_1: "Habilidade com palavras é basicamente do que precisas. Não apenas gramática e ortografia, mas seres capaz de explicar ideias complicadas a outros." contact_us_url: "Contacta-nos" scribe_join_description: "fala-nos um bocado de ti, a tua experiência com a programação e o tipo de coisas sobre o qual gostavas de escrever. Começamos a partir daí!" scribe_subscribe_desc: "Receber e-mails sobre anúncios relativos à escrita de artigos." @@ -745,7 +745,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # ambassador_introduction: "This is a community we're building, and you are the connections. We've got forums, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you." # ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!" # ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!" -# ambassador_join_note_strong: "Note" + ambassador_join_note_strong: "Nota" # ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!" ambassador_subscribe_desc: "Receber e-mails relativos a novidades do suporte e desenvolvimentos do modo multijogador." changes_auto_save: "As alterações são guardadas automaticamente quando clicas nas caixas." @@ -1108,8 +1108,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # education_degree: "Degree" # education_degree_help: "What was your degree and field of study?" # education_duration: "Dates" -# education_duration_help: "When?" -# education_description: "Description" + education_duration_help: "Quando?" + education_description: "Descrição" # education_description_help: "Highlight anything about this educational experience. (140 chars; optional)" # our_notes: "CodeCombat's Notes" # remarks: "Remarks" @@ -1124,7 +1124,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: project_picture: "Imagem" # project_picture_help: "Upload a 230x115px or larger image showing off the project." project_link: "Ligação" -# project_link_help: "Link to the project." + project_link_help: "Ligação para o projeto." player_code: "Código do Jogador" employers: From 44c97428e37c7d84d22adc7aad7e989a02ce8bc5 Mon Sep 17 00:00:00 2001 From: nixel2007 Date: Thu, 22 Jan 2015 22:14:56 +0300 Subject: [PATCH 13/18] Update ru.coffee --- app/locale/ru.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 301b96016..f919b6b5d 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -317,12 +317,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi tip_brute_force: "Когда сомневаешься используй грубую силу. - Кен Томпсон" tip_extrapolation: "Есть два типа людей: те, кто могут экстраполировать неполные данные..." tip_superpower: "Программирование делает нас ближе к обретению суперсилы." -# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" -# tip_no_code: "No code is faster than no code." -# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" -# tip_reusable_software: "Before software can be reusable it first has to be usable." -# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’" -# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" + tip_control_destiny: "В настоящей среде открытого кода у вас есть право контроллировать свою собственную судьбу. - Linus Torvalds" + tip_code_never_lies: "Код никогда не врет. Комментарии - иногда. — Ron Jeffries" + tip_no_code: "Нет кода быстрее, чем его отсутствие." + tip_reusable_software: "Прежде, чем программное обеспечение станет повторно используемым, оно должно стать в принципе используемым." + tip_optimization_operator: "В каждом языке есть оператор оптимизации. В большинстве языков это оператор ‘//’" + tip_lines_of_code: "Измерение прогресса программирования в строках кода - это как измерять прогресс построения самолета по его весу. — Bill Gates" game_menu: inventory_tab: "Инвентарь" From 6b5c69f8890a6c0242664d0267f243e0bb142d85 Mon Sep 17 00:00:00 2001 From: nixel2007 Date: Thu, 22 Jan 2015 22:16:37 +0300 Subject: [PATCH 14/18] ru.coffee - small fix --- app/locale/ru.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index f919b6b5d..999c79fbe 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -317,7 +317,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi tip_brute_force: "Когда сомневаешься используй грубую силу. - Кен Томпсон" tip_extrapolation: "Есть два типа людей: те, кто могут экстраполировать неполные данные..." tip_superpower: "Программирование делает нас ближе к обретению суперсилы." - tip_control_destiny: "В настоящей среде открытого кода у вас есть право контроллировать свою собственную судьбу. - Linus Torvalds" + tip_control_destiny: "В настоящей среде открытого кода у вас есть право контролировать свою судьбу. - Linus Torvalds" tip_code_never_lies: "Код никогда не врет. Комментарии - иногда. — Ron Jeffries" tip_no_code: "Нет кода быстрее, чем его отсутствие." tip_reusable_software: "Прежде, чем программное обеспечение станет повторно используемым, оно должно стать в принципе используемым." From 64008276c24bab8128f281259b49c7dfbc68fac0 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 22 Jan 2015 11:22:35 -0800 Subject: [PATCH 15/18] Finally translating level names and descriptions in the campaign view. --- app/schemas/models/campaign.schema.coffee | 1 + app/templates/play/campaign-view.jade | 9 +++++---- app/views/play/CampaignView.coffee | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/schemas/models/campaign.schema.coffee b/app/schemas/models/campaign.schema.coffee index d99e19684..a08df6a3e 100644 --- a/app/schemas/models/campaign.schema.coffee +++ b/app/schemas/models/campaign.schema.coffee @@ -52,6 +52,7 @@ _.extend CampaignSchema.properties, { #- denormalized from Level name: { type: 'string', format: 'hidden' } description: { type: 'string', format: 'hidden' } + i18n: { type: 'object', format: 'hidden' } requiresSubscription: { type: 'boolean' } type: {'enum': ['campaign', 'ladder', 'ladder-tutorial', 'hero', 'hero-ladder', 'hero-coop']} slug: { type: 'string', format: 'hidden' } diff --git a/app/templates/play/campaign-view.jade b/app/templates/play/campaign-view.jade index 7cd02593b..14c8ee1e0 100644 --- a/app/templates/play/campaign-view.jade +++ b/app/templates/play/campaign-view.jade @@ -7,7 +7,7 @@ each level in levels if !level.hidden - div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, data-level-original=level.original, title=level.name + (level.disabled ? ' (Coming Soon to Adventurers)' : '')) + div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, data-level-original=level.original, title=i18n(level, 'name') + (level.disabled ? ' (Coming Soon to Adventurers)' : '')) if level.unlocksHero && !level.unlockedHero img.hero-portrait(src=level.unlocksHero.img) a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.slug}", disabled=level.disabled, data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name) @@ -20,8 +20,9 @@ div(style="left: #{level.position.x}%; bottom: #{level.position.y}%", class="level-shadow" + (level.next ? " next" : "") + " " + levelStatusMap[level.slug] || "") .level-info-container(data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name) div(class="level-info " + (levelStatusMap[level.slug] || "")) - h3= level.name + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : "")) - .level-description= level.description + h3= i18n(level, 'name') + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : "")) + - var description = i18n(level, 'description') || level.description || "" + .level-description!= marked(description) if level.disabled p span.spr(data-i18n="play.awaiting_levels_adventurer_prefix") We release five levels per week. @@ -36,7 +37,7 @@ span(data-i18n="play.players") players span.spr , #{Math.round(playCount.playtime / 3600)} span(data-i18n="play.hours_played") hours played - .campaign-label= campaign.get('name') + .campaign-label= i18n(campaign.attributes, 'name') if isIPadApp && !level.disabled && !level.locked button.btn.btn-success.btn-lg.start-level(data-i18n="common.play") Play diff --git a/app/views/play/CampaignView.coffee b/app/views/play/CampaignView.coffee index 039436c52..619e12799 100644 --- a/app/views/play/CampaignView.coffee +++ b/app/views/play/CampaignView.coffee @@ -170,6 +170,8 @@ module.exports = class CampaignView extends RootView styles.push "top: #{ac.position.y}%" ac.style = styles.join('; ') return true + context.marked = marked + context.i18n = utils.i18n context afterRender: -> From 0d00917ca05397c533939f0497dbbfd3a840d828 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Thu, 22 Jan 2015 19:28:17 +0000 Subject: [PATCH 16/18] Fixed order --- app/locale/ru.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 999c79fbe..faa650fdf 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -318,8 +318,8 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi tip_extrapolation: "Есть два типа людей: те, кто могут экстраполировать неполные данные..." tip_superpower: "Программирование делает нас ближе к обретению суперсилы." tip_control_destiny: "В настоящей среде открытого кода у вас есть право контролировать свою судьбу. - Linus Torvalds" - tip_code_never_lies: "Код никогда не врет. Комментарии - иногда. — Ron Jeffries" tip_no_code: "Нет кода быстрее, чем его отсутствие." + tip_code_never_lies: "Код никогда не врет. Комментарии - иногда. — Ron Jeffries" tip_reusable_software: "Прежде, чем программное обеспечение станет повторно используемым, оно должно стать в принципе используемым." tip_optimization_operator: "В каждом языке есть оператор оптимизации. В большинстве языков это оператор ‘//’" tip_lines_of_code: "Измерение прогресса программирования в строках кода - это как измерять прогресс построения самолета по его весу. — Bill Gates" From e75e0791d07a1ceffaf7debb945ff44a71890c81 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 22 Jan 2015 11:30:22 -0800 Subject: [PATCH 17/18] Fixed problem POSTing UserCodeProblems for non-admins. --- server/user_code_problems/user_code_problem_handler.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/user_code_problems/user_code_problem_handler.coffee b/server/user_code_problems/user_code_problem_handler.coffee index 9ce2cbe7e..968e2d2c2 100644 --- a/server/user_code_problems/user_code_problem_handler.coffee +++ b/server/user_code_problems/user_code_problem_handler.coffee @@ -25,7 +25,9 @@ class UserCodeProblemHandler extends Handler ucp hasAccess: (req) -> - req.user?.isAdmin() or false + return true if req.user?.isAdmin() + return true if req.method.toLowerCase() is 'post' + false getByRelationship: (req, res, args...) -> return @sendForbiddenError res unless @hasAccess req From e3bf8f74ab4bb0f43ddd035babcec93cc4b56596 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 22 Jan 2015 12:26:37 -0800 Subject: [PATCH 18/18] Trying to stagger LevelSessions saves on wins on replayable levels to see if that might help #2108 at all. --- app/models/LevelSession.coffee | 4 ++-- app/views/play/level/PlayLevelView.coffee | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/models/LevelSession.coffee b/app/models/LevelSession.coffee index bf40073ea..3e2732eb2 100644 --- a/app/models/LevelSession.coffee +++ b/app/models/LevelSession.coffee @@ -54,13 +54,13 @@ module.exports = class LevelSession extends CocoModel return if @shouldAvoidCorruptData attrs super attrs, options - increaseDifficulty: -> + increaseDifficulty: (callback) -> state = @get('state') ? {} state.difficulty = (state.difficulty ? 0) + 1 delete state.lastUnsuccessfulSubmissionTime @set 'state', state - @save() @trigger 'change-difficulty' + @save null, success: callback timeUntilResubmit: -> state = @get('state') ? {} diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index fd16c3caf..dcb21d8e5 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -523,8 +523,11 @@ module.exports = class PlayLevelView extends RootView return if @destroyed # TODO: Show a victory dialog specific to hero-ladder level if @goalManager.checkOverallStatus() is 'success' and not @options.realTimeMultiplayerSessionID? - @session.increaseDifficulty() if @level.get 'replayable' - Backbone.Mediator.publish 'level:show-victory', showModal: true + showModalFn = -> Backbone.Mediator.publish 'level:show-victory', showModal: true + if @level.get 'replayable' + @session.increaseDifficulty showModalFn + else + showModalFn() destroy: -> @levelLoader?.destroy()