Merge branch 'master' into production

This commit is contained in:
Nick Winter 2014-12-06 20:31:34 -08:00
commit 7eaef4fd81
38 changed files with 613 additions and 271 deletions

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View file

@ -56,24 +56,8 @@
<div id="modal-wrapper" class="modal-content"></div>
<div class="modal fade" id="module-loading-list">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">LOADING</h4>
<div class="progress" id="module-load-progress">
<div class="progress-bar"></div>
</div>
<div class="modal-body">
<ul class="list-group"></ul>
</div>
</div>
</div>
</div>
<!--<div class="panel panel-primary" id="module-loading-list">-->
<!--<div class="panel-heading">-->
<!--<div class="panel-title">LOADING</div>-->
<!--</div>-->
<!--<ul class="list-group"></ul>-->
<!--</div>-->
</body>
</html>

View file

@ -24,10 +24,12 @@ module.exports = ModuleLoader = class ModuleLoader extends CocoClass
return func(name, loaderPath)
_.extend wrapped, window.require # for functions like 'list'
window.require = wrapped
@updateProgress = _.throttle _.bind(@updateProgress, @), 700
@lastShownProgress = 0
load: (path, first=true) ->
$('#module-load-progress').css('opacity', 1)
if first
$('#module-loading-list ul').empty()
@recentPaths = []
@recentLoadedBytes = 0
@ -35,14 +37,8 @@ module.exports = ModuleLoader = class ModuleLoader extends CocoClass
wad = _.find ModuleLoader.WADS, (wad) -> _.string.startsWith(path, wad)
path = wad if wad
return false if @loaded[path]
$('#module-loading-list').modal('show') if first
@loaded[path] = true
@recentPaths.push(path)
li = $("<li class='list-group-item loading' data-path='#{path}'>#{path}</li>")
.prepend($("<span class='glyphicon glyphicon-minus'></span>"))
.prepend($("<span class='glyphicon glyphicon-ok'></span>"))
ul = $('#module-loading-list ul')
ul.append(li).scrollTop(ul[0].scrollHeight)
console.debug 'Loading js file:', "/javascripts/app/#{path}.js" if LOG
@queue.loadFile({
id: path
@ -59,8 +55,6 @@ module.exports = ModuleLoader = class ModuleLoader extends CocoClass
return @load("locale/#{firstBit}", false) or loading
onFileLoad: (e) =>
$("#module-loading-list li[data-path='#{e.item.id}']").removeClass('loading').addClass('success')
# load dependencies if it's not a vendor library
if not _.string.startsWith(e.item.id, 'vendor')
have = window.require.list()
@ -80,13 +74,11 @@ module.exports = ModuleLoader = class ModuleLoader extends CocoClass
# get treema set up only when the library loads, if it loads
if e.item.id is 'vendor/treema'
console.log 'setting up treema-ext'
treemaExt = require 'core/treema-ext'
treemaExt.setup()
# a module and its dependencies have loaded!
if @queue.progress is 1
$('#module-loading-list').modal('hide')
@recentPaths.sort()
console.debug @recentPaths.join('\n')
console.debug 'loaded', @recentPaths.length, 'files,', parseInt(@recentLoadedBytes/1024), 'KB'
@ -94,6 +86,14 @@ module.exports = ModuleLoader = class ModuleLoader extends CocoClass
@trigger 'loaded', e.item
@updateProgress()
updateProgress: ->
return if @queue.progress < @lastShownProgress
$('#module-load-progress .progress-bar').css('width', (100*@queue.progress)+'%')
if @queue.progress is 1
$('#module-load-progress').css('opacity', 0)
parseDependencies: (raw) ->
bits = raw.match(/(require\(['"](.+?)['"])|(register\(['"].+?['"])/g) or []
rootFolder = null

View file

@ -76,6 +76,14 @@ class AudioPlayer extends CocoClass
return sound if sound = say[message]
if _.string.startsWith message, 'attack'
return sound if sound = say.attack
if message.indexOf("i-dont-see-anyone") isnt -1
return sound if sound = say['i-dont-see-anyone']
if message.indexOf("i-see-you") isnt -1
return sound if sound = say['i-see-you']
if message.indexOf("repeating-loop") isnt -1
return sound if sound = say['repeating-loop']
if /move(up|down|left|right)/.test message
return sound if sound = say["move-#{message[4...]}"]
defaults = say.defaultSimlish
if say.swearingSimlish?.length and _.find(swears, (s) -> message.search(s) isnt -1)
defaults = say.swearingSimlish

View file

@ -691,10 +691,10 @@ module.exports = Lank = class Lank extends CocoClass
Backbone.Mediator.publish 'surface:gold-changed', {team: @thang.team, gold: gold, goldEarned: Math.floor(@thang.goldEarned ? 0)}
shouldMuteMessage: (m) ->
return true if m in ['moveRight', 'moveUp', 'moveDown', 'moveLeft']
return true if /^attack /.test m
return true if /^Repeating loop/.test m
return true if /^findNearestEnemy/.test m
return false if m in ['moveRight', 'moveUp', 'moveDown', 'moveLeft']
#return true if /^attack /.test m
#return true if /^Repeating loop/.test m
#return true if /^findNearestEnemy/.test m
@previouslySaidMessages ?= {}
t0 = @previouslySaidMessages[m] ? 0
t1 = new Date()

View file

@ -101,23 +101,25 @@
log_in: "Log In"
logging_in: "Logging In"
log_out: "Log Out"
recover: "recover account"
forgot_password: "Forgot your password?"
authenticate_gplus: "Authenticate G+"
load_profile: "Load G+ Profile"
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?"
signup:
create_account_title: "Create Account to Save Progress"
description: "It's free. Just need a couple things and you'll be good to go:"
email_announcements: "Receive announcements by email"
coppa: "13+ or non-USA "
coppa_why: "(Why?)"
creating: "Creating Account..."
sign_up: "Sign Up"
log_in: "log in with password"
social_signup: "Or, you can sign up through Facebook or G+:"
required: "You need to log in before you can go that way."
login_switch: "Already have an account?"
recover:
recover_account_title: "Recover Account"
@ -291,7 +293,6 @@
tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
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..."
customize_wizard: "Customize Wizard"
game_menu:
inventory_tab: "Inventory"
@ -504,8 +505,6 @@
job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."
sample_profile: "See a sample profile"
view_profile: "View Your Profile"
wizard_tab: "Wizard"
wizard_color: "Wizard Clothes Color"
keyboard_shortcuts:
keyboard_shortcuts: "Keyboard Shortcuts"
@ -526,7 +525,6 @@
toggle_pathfinding: "Toggle pathfinding overlay."
beautify: "Beautify your code by standardizing its formatting."
maximize_editor: "Maximize/minimize code editor."
move_wizard: "Move your Wizard around the level."
community:
main_title: "CodeCombat Community"
@ -872,7 +870,6 @@
versions: "Versions"
items: "Items"
heroes: "Heroes"
wizard: "Wizard"
achievement: "Achievement"
clas: "CLAs"
play_counts: "Play Counts"

View file

@ -331,27 +331,27 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
prompt_body: "¿Quieres obtener más?"
prompt_button: "Ingresa a la tienda"
# subscribe:
# subscribe_title: "Subscribe"
# levels: "Unlock 17 extra levels! With 5 new ones every week!"
# heroes: "More powerful heroes!"
# gems: "3500 bonus gems every month!"
# items: "Over 250 bonus items!"
# parents: "For Parents"
# parents_title: "Your child will learn to code."
# parents_blurb1: "With CodeCombat, your child learns by writing real code. They start by learning simple commands, and progress to more advanced topics."
# parents_blurb2: "For $9.99 USD/mo, they get new challenges every week and personal email support from professional programmers."
# parents_blurb3: "No Risk: 100% money back guarantee, easy 1-click unsubscribe."
# subscribe_button: "Subscribe Now"
# stripe_description: "Monthly Subscription"
# subscription_required_to_play: "You'll need a subscription to play this level."
subscribe:
subscribe_title: "Suscríbete"
levels: "¡Desbloquea 17 niveles adicionales! ¡5 nuevos cada semana!"
heroes: "¡Más heroes poderosos!"
gems: "¡3500 joyas adicionales cada mes!"
items: "¡Más de 250 artículos adicionales!"
parents: "Para Padres"
parents_title: "Tus hijos aprenderan a programar."
parents_blurb1: "Con CodeCombat, tus hijos aprendes a desarrollar código real. Al inicio aprenden comandos simples, y avanzan a temas más avanzados."
parents_blurb2: "Por $9.99 USD/mes, tienen nuevos desafios cada semana y un correo personal con soporte de nuestros programadores profesionales."
parents_blurb3: "Sin riesgo: 100% garantía de devoluación de dinero, desuscripción con un simple click."
subscribe_button: "Suscríbete Ahora"
stripe_description: "Suscripción mensual"
subscription_required_to_play: "Necesitas una suscripción para jugar este nivel."
choose_hero:
choose_hero: "Selecciona tu Heroe"
programming_language: "Lenguaje de Programación"
programming_language_description: "¿Qué lenguaje de programación deseas usar?"
# default: "Default"
# experimental: "Experimental"
experimental: "Experimental"
python_blurb: "Simple pero poderoso."
javascript_blurb: "El lenguaje de la web."
coffeescript_blurb: "Sintaxsis de JavaScript mejorada."
@ -360,37 +360,37 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
io_blurb: "Simple pero oscuro."
status: "Estado"
weapons: "Armas"
# weapons_warrior: "Swords - Short Range, No Magic"
# weapons_ranger: "Crossbows, Guns - Long Range, No Magic"
# weapons_wizard: "Wands, Staffs - Long Range, Magic"
weapons_warrior: "Espadas - Corto Alcance, Sin Magia"
weapons_ranger: "Ballestas, Pistolas - Largo Alcance, Sin Magia"
weapons_wizard: "Varitas, Bastones - Largo Alcance, Magia"
attack: "Daño" # Can also translate as "Attack"
health: "Salud"
speed: "Velocidad"
# regeneration: "Regeneration"
# range: "Range" # As in "attack or visual range"
# blocks: "Blocks" # As in "this shield blocks this much damage"
regeneration: "Regeneración"
range: "Alcance" # As in "attack or visual range"
blocks: "Bloqueo" # As in "this shield blocks this much damage"
skills: "Habilidades"
# available_for_purchase: "Available for Purchase"
# level_to_unlock: "Level to unlock:"
# restricted_to_certain_heroes: "Only certain heroes can play this level."
available_for_purchase: "Disponible para Comprar"
level_to_unlock: "Nivel para desbloquear:"
restricted_to_certain_heroes: "Solo ciertos heroes pueden jugar este nivel."
# skill_docs:
skill_docs:
# writable: "writable" # Hover over "attack" in Your Skills while playing a level to see most of this
# read_only: "read-only"
# action_name: "name"
read_only: "Solo lectura"
action_name: "nombres"
# action_cooldown: "Takes"
# action_specific_cooldown: "Cooldown"
# action_damage: "Damage"
# action_range: "Range"
# action_radius: "Radius"
# action_duration: "Duration"
# example: "Example"
# ex: "ex" # Abbreviation of "example"
# current_value: "Current Value"
# default_value: "Default value"
# parameters: "Parameters"
# returns: "Returns"
# granted_by: "Granted by"
action_damage: "Daño"
action_range: "Alcance"
action_radius: "Radio"
action_duration: "Duración"
example: "Ejemplo"
ex: "ej" # Abbreviation of "example"
current_value: "Valor actual"
default_value: "Valor por defecto"
parameters: "Parámetros"
returns: "Devolver"
granted_by: "Otorgado por"
save_load:
granularity_saved_games: "Salvado"
@ -412,7 +412,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
editor_config_keybindings_label: "Atajos de teclado"
editor_config_keybindings_default: "Actual (Ace)"
editor_config_keybindings_description: "Permite el uso de atajos de teclado de algunos editores conocidos."
# editor_config_livecompletion_label: "Live Autocompletion"
editor_config_livecompletion_label: "Autocompletado en vivo"
editor_config_livecompletion_description: "Muestra sugerencias de autocompletado mientras se escribe."
editor_config_invisibles_label: "Mostrar elementos invisibles"
editor_config_invisibles_description: "Se pueden ver elementos invisibles como espacios o tabulaciones."
@ -513,10 +513,10 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
enter: "Enter"
escape: "Escape"
shift: "Shift"
# run_code: "Run current code."
run_code: "Ejecutar código actual."
run_real_time: "correr en tiempo real."
# continue_script: "Continue past current script."
# skip_scripts: "Skip past all skippable scripts."
continue_script: "Continuar después del script actual."
skip_scripts: "Saltar todos los scripts posibles."
# toggle_playback: "Toggle play/pause."
# scrub_playback: "Scrub back and forward through time."
# single_scrub_playback: "Scrub back and forward through time by a single frame."
@ -530,13 +530,13 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
community:
main_title: "Comunidad de CodeCombat"
# introduction: "Check out the ways you can get involved below and decide what sounds the most fun. We look forward to working with you!"
# level_editor_prefix: "Use the CodeCombat"
# level_editor_suffix: "to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!"
# thang_editor_prefix: "We call units within the game 'thangs'. Use the"
# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites."
# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the"
# article_editor_suffix: "and help CodeCombat players get the most out of their playtime."
introduction: "Descubre las formas en las que te puedes involucrar abajo y decide cual te suena más divertida. ¡Esperamos trabajar contigo!"
level_editor_prefix: "Usa CodeCombat"
level_editor_suffix: "para crear y editar niveles. Usuarios han creado niveles para sus clases, amigos, hackathons, estudiantes, y hermanos. Si crear un nivel te suena intimidante, ¡puedes empezar usando uno de los nuestros!"
thang_editor_prefix: "Llamamos a la unidades dentro del juego 'thangs'. Usa el"
thang_editor_suffix: "para modificar los artes fuente de CodeCombat. Permite a las unidades lanzar proyectiles, cambiar la dirección de la animación, cambiar los puntos de una unidad, o subir tus propios sprites vectoriales."
article_editor_prefix: "¿Viste un error en alguno de nuestros documentos? ¿Quieres hacer algunas instrucciones para tus propias creaciones? Revisa el"
article_editor_suffix: "y ayuda a juegadores de CodeCombat a obtener lo mejor de su tiempo en el juego."
find_us: "Encuentranos en estos sitios"
social_blog: "Lee el blog de CodeCombat en Sett"
social_discource: "Unete a la discusion en nuestro foro"
@ -624,7 +624,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# achievement_query_misc: "Key achievement off of miscellanea"
# achievement_query_goals: "Key achievement off of level goals"
level_completion: "Porcentaje de Nivel Completado"
# pop_i18n: "Populate I18N"
pop_i18n: "Poblar I18N"
article:
edit_btn_preview: "Vista preliminar"
@ -694,9 +694,9 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
diplomat_launch_url: "lanzamiento en octubre"
diplomat_introduction_suf: "hay un interés considerable en CodeCombat en otros paises, ¡especialmente Brasil! Estamos formando un cuerpo de traductores con ganas de traducir un grupo de palabras tras otro para hacer CodeCombat tan accesible para todo el mundo como sea posible. Si quieres recibir avances de próximos contenidos y quieres poner esos niveles a disposición de los que comparten tu idioma tan pronto como sea posible, entonces esta Clase es para ti."
diplomat_attribute_1: "Fluidez con el ingles y el lenguaje al que quieras traducir. Cuando de transmitir ideas complejas se trata, ¡es importante tener grandes conocimientos de ambas!"
# diplomat_i18n_page_prefix: "You can start translating our levels by going to our"
# diplomat_i18n_page: "translations page"
# diplomat_i18n_page_suffix: ", or our interface and website on GitHub."
diplomat_i18n_page_prefix: "Puedes traducir nuestros niveles yendo a nuestra"
diplomat_i18n_page: "página de traducciones"
diplomat_i18n_page_suffix: ", o en nuestra interfaz y sitio web en GitHub."
diplomat_join_pref_github: "Encuentra el fichero local de tu idioma "
diplomat_github_url: "en GitHub"
diplomat_join_suf_github: ", edítalo online, y solicita que sea revisado. Además, marca la casilla de abajo para mantenerte informado en nuevos progresos en Internacionalización."
@ -792,8 +792,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
amount_achieved: "Cantidad"
achievement: "Logro"
category_contributor: "Contribuidor"
# category_ladder: "Ladder"
# category_level: "Level"
category_ladder: "Escalera"
category_level: "Nivel"
category_miscellaneous: "Miscelanea"
category_levels: "Niveles"
category_undefined: "Sin categorizar"
@ -808,16 +808,16 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
account:
recently_played: "Jugado Recientemente"
no_recent_games: "No he jugado juegos en las ultimas dos semanas."
# payments: "Payments"
# service_apple: "Apple"
# service_web: "Web"
# paid_on: "Paid On"
# service: "Service"
# price: "Price"
# gems: "Gems"
# status_subscribed: "You're currently subscribed at $9.99 USD/mo. Thanks for your support!"
# 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!"
payments: "Pagos"
service_apple: "Apple"
service_web: "Web"
paid_on: "Pagado en"
service: "Servicio"
price: "Precio"
gems: "Joyas"
status_subscribed: "Estas suscrito por $9.99 USD/mes. ¡Gracias por tu colaboración!"
status_unsubscribed_active: "No estás suscrito y no seras facturado, pero tu cuenta sigue activa por ahora."
status_unsubscribed: "¡Obten acceso a nuevos niveles, heroes, artículos, y joyas adicionales con una suscripción a CodeCombat!"
loading_error:
could_not_load: "Error al cargar desde el servidor."
@ -858,7 +858,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
opponent_session: "Sesión del oponente"
article: "Artículo"
user_names: "Nombres de usuarios"
# thang_names: "Thang Names"
thang_names: "Nombres Thang"
files: "Archivos"
top_simulators: "Top simuladores"
source_document: "Documento fuente"
@ -867,8 +867,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
employers: "Empleados"
candidates: "Candidatos"
candidate_sessions: "Sesiones de Candidato"
# user_remark: "User Remark"
# user_remarks: "User Remarks"
user_remark: "Observación de Usuario"
user_remarks: "Observaciones de Usuario"
versions: "Versiones"
items: "Objetos"
heroes: "Heroes"
@ -883,8 +883,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
modified: "Modificado"
deleted: "Eliminado"
moved_index: "Indice Movido"
# text_diff: "Text Diff"
# merge_conflict_with: "MERGE CONFLICT WITH"
text_diff: "Diferencias"
merge_conflict_with: "MERGE EN CONFLICTO CON"
no_changes: "Sin Cambios"
guide:
@ -911,7 +911,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
practices_title: "Prácticas respetuosas"
practices_description: "Esto es lo que te prometemos a ti, el jugador, sin usar mucha jerga legal."
privacy_title: "Privacidad"
# privacy_description: "We will not sell any of your personal information."
privacy_description: "No venderemos tu información personal."
security_title: "Seguridad"
security_description: "Nos esforzamos por mantener segura tu información personal. Como proyecto de código abierto, nuestro sitio está abierto a cualquiera que quiera revisarlo y mejorar nuestros sistemas de seguridad."
email_title: "Correo electrónico"
@ -997,7 +997,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
next_long_description: "describe tu puesto de trabajo deseado."
next_skills: "Pon al menos cinco habilidades."
next_work: "Resume tu historia laboral."
# next_education: "recount your educational ordeals."
next_education: "Relatar tu experiencia educativa."
next_projects: "Muestranos tres proyectos en los que hayas trabajado."
next_links: "añade links personales o de redes sociales."
next_photo: "añadir una foto para el perfil profesional."
@ -1012,7 +1012,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
basics_header: "Actualizar información básica"
basics_active: "Abierto a ofertas"
basics_active_help: "Buscas entrevistas de trabajo ahora?"
# basics_job_title: "Desired Job Title"
basics_job_title: "Nombre del Cargo deseado"
basics_job_title_help: "Que tipo de rol estas buscando?"
basics_city: "Ciudad"
basics_city_help: "Ciudad en la que quieres trabajar (o en la que vives actualmente)."
@ -1035,11 +1035,11 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# short_description: "Tagline"
short_description_help: "¿Quién eres, y qué estás buscando? 140 caracteres como máximo."
skills_header: "Habilidades"
# skills_help: "Tag relevant developer skills in order of proficiency."
skills_help: "Etiqueta tus habilidades de desarrolloen orden de competencia."
long_description_header: "Describenos tu trabajo soñado"
long_description_blurb: "Cuenta a tus empleadores lo impresionante que eres y que trabajo estas buscando."
long_description: "Descripción Personal"
# long_description_help: "Describe yourself to potential employers. Keep it short and to the point. We recommend outlining the position that would most interest you. Tasteful markdown okay; 600 characters max."
long_description_help: "Descríbete a ti mismo para tus potenciales empleadores. Mantenlo corto y directo. Recomendamos describir la posición que más te interesa. 600 caracteres max."
work_experience: "Experiencia laboral"
work_header: "Cuentanos un poco de tu historial laboral"
work_years: "Años de experiencia"
@ -1047,15 +1047,15 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
work_blurb: "Haz un listado con la experiencia laboral relevante, los mas recientes primero."
work_employer: "Empresa/Empleador"
work_employer_help: "Nombre de la empresa /el empleador."
# work_role: "Job Title"
# work_role_help: "What was your job title or role?"
work_role: "Cargo"
work_role_help: "¿Cuál era tu cargo o rol?"
work_duration: "Duración"
# work_duration_help: "When did you hold this gig?"
work_description: "Descripción"
work_description_help: "Que has hecho alli? (140 caracteres maximo; opcional)"
education: "Educación"
# education_header: "Recount your academic ordeals"
# education_blurb: "List your academic ordeals."
education_header: "Detalla tu experiencia académica"
education_blurb: "Lista tu experiencia académica."
education_school: "Universidad"
education_school_help: "Nombre de la Universidad."
education_degree: "Titulo"
@ -1065,7 +1065,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
education_description: "Descripción"
education_description_help: "Resalta algo de tu experiencia educacional. (140 caracteres maximo; optional)"
our_notes: "Nuestras notas"
# remarks: "Remarks"
remarks: "Observaciones"
projects: "Proyectos"
projects_header: "Añade 3 proyectos"
projects_header_2: "Proyectos (Top 3)"

View file

@ -246,18 +246,51 @@ kbd
font-weight: bold
color: rgb(248, 197, 146)
&.btn-lg
border-width: 14px 20px 20px 20px
&.btn-primary
border-image-source: url(/images/common/button-background-primary-active-border.png)
&.btn-success
border-image-source: url(/images/common/button-background-success-active-border.png)
&.btn-warning
border-image-source: url(/images/common/button-background-warning-active-border.png)
&.btn-danger
border-image-source: url(/images/common/button-background-danger-active-border.png)
&:hover
color: lighten(rgb(248, 197, 146), 5%)
&:active
&.btn-lg
border-image-source: url(/images/common/button-background-pressed-border.png)
&:not(.btn-lg)
border-image: url(/images/common/button-background-pressed-border.png) 14 16 16 20 fill round
padding: 2px 0 0 2px
border-width: 7px 8px 8px 10px
&.btn-primary
border-image-source: url(/images/common/button-background-primary-pressed-border.png)
&.btn-success
border-image-source: url(/images/common/button-background-success-pressed-border.png)
&.btn-warning
border-image-source: url(/images/common/button-background-warning-pressed-border.png)
&.btn-danger
border-image-source: url(/images/common/button-background-danger-pressed-border.png)
&.disabled, &:disabled
border-image: url(/images/common/button-background-disabled-border.png) 14 20 20 20 fill round
@include opacity(1)
&.btn-primary
border-image-source: url(/images/common/button-background-primary-disabled-border.png)
&.btn-success
border-image-source: url(/images/common/button-background-success-disabled-border.png)
&.btn-warning
border-image-source: url(/images/common/button-background-warning-disabled-border.png)
&.btn-danger
border-image-source: url(/images/common/button-background-danger-disabled-border.png)
> *
@include opacity(0.5)
@ -281,38 +314,53 @@ html.no-borderimage
background-size: 100% 100%
padding: 7px 10px 10px 10px
&.btn-primary
background-image: url(/images/common/button-background-primary-active.png)
&.btn-success
background-image: url(/images/common/button-background-success-active.png)
&.btn-warning
background-image: url(/images/common/button-background-warning-active.png)
&.btn-danger
background-image: url(/images/common/button-background-danger-active.png)
&:active
background-image: url(/images/common/button-background-pressed.png)
padding: 9px 8px 8px 12px
border: 0
&.btn-primary
background-image: url(/images/common/button-background-primary-pressed.png)
&.btn-success
background-image: url(/images/common/button-background-success-pressed.png)
&.btn-warning
background-image: url(/images/common/button-background-warning-pressed.png)
&.btn-danger
background-image: url(/images/common/button-background-danger-pressed.png)
&.disabled, &:disabled
background-image: url(/images/common/button-background-disabled.png)
&.btn-primary
background-image: url(/images/common/button-background-primary-disabled.png)
&.btn-success
background-image: url(/images/common/button-background-success-disabled.png)
&.btn-warning
background-image: url(/images/common/button-background-warning-disabled.png)
&.btn-danger
background-image: url(/images/common/button-background-danger-disabled.png)
body > iframe[src^="https://apis.google.com"]
display: none
#module-loading-list
.modal-content
background: white
border-shadow: 2px 2px 10px black
#module-load-progress
position: absolute
top: 0
left: 0
right: 0
height: 5px
z-index: 1
transition: 1s
ul
max-height: 500px
overflow: scroll
li
padding: 2px 15px
font-size: 10px
.glyphicon
margin-right: 10px
&.loading
.glyphicon-ok
display: none
&.success
font-weight: bold
.glyphicon-minus
display: none
.progress-bar
background-color: lightblue

View file

@ -543,7 +543,18 @@ $itemSlotGridHeight: 51px
&.male
left: 55px
bottom: 63px
@include rotate(-15deg)
&.right-hand.female.Ranger[src="/file/db/thang.type/53f4e6e3d822c23505b74f42/warrior_female.png"]
// Special-case Builder's Hammer, since we don't yet have ranger-specific hand exports for it
@include rotate(180deg)
left: -95px
bottom: -89px
&.right-hand.male.Ranger[src="/file/db/thang.type/53f4e6e3d822c23505b74f42/warrior_male.png"]
// Special-case Builder's Hammer, since we don't yet have ranger-specific hand exports for it
@include rotate(180deg)
left: -138px
bottom: -55px
&.left-hand
z-index: 17

View file

@ -1,8 +1,209 @@
@import "app/styles/mixins"
@import "app/styles/bootstrap/variables"
#auth-modal
.network-login
//- Clear modal defaults
.modal-dialog
padding: 0
width: 666px
height: 694px
//- Background
.auth-modal-background
position: absolute
top: -90px
left: -40px
//- Header
h1
position: absolute
left: 183px
top: 0px
margin: 0
width: 255px
text-align: center
color: rgb(254,188,68)
font-size: 32px
text-shadow: black 2px 2px 0, black -2px -2px 0, black 2px -2px 0, black -2px 2px 0, black 2px 0px 0, black 0px -2px 0, black -2px 0px 0, black 0px 2px 0
&.long-title
top: -14px
//- Close modal button
#close-modal
position: absolute
left: 442px
top: -15px
width: 60px
height: 60px
color: white
text-align: center
font-size: 30px
padding-top: 15px
cursor: pointer
@include rotate(-3deg)
&:hover
color: yellow
//- Modal body content
.auth-form-content
position: absolute
top: 100px
left: 40px
width: 588px
.alert
margin-top: -25px
margin-bottom: 0
padding: 10px 15px
#recover-account-wrapper
float: right
margin-top: 7px
.form-group
color: rgb(51,51,51)
padding: 0
margin: 0
.input-border
border: 2px solid rgb(233, 221, 194)
border-radius: 4px
input
background-color: rgb(239, 232, 216)
border: 2px solid rgb(26, 21, 18)
border-radius: 4px
label
font-size: 20px
text-transform: uppercase
font-family: 'Open Sans Condensed'
margin-bottom: 0
//- Check boxes
.form-group.checkbox
margin: 10px 0
label
position: relative
line-height: 34px
span:not(.custom-checkbox)
margin-left: 40px
input
display: none
& + .custom-checkbox
.glyphicon
display: none
&:checked + .custom-checkbox .glyphicon
display: inline
color: rgb(248,169,67)
text-align: center
text-shadow: 0 0 3px black, 0 0 3px black, 0 0 3px black
font-size: 20px
position: relative
top: -2px
.input-border
border-radius: 4px
height: 34px
width: 34px
position: absolute
.custom-checkbox
border-radius: 4px
position: absolute
height: 30px
width: 30px
border: 2px solid rgb(26,21,18)
background: rgb(228,217,196)
text-align: center
//- Primary auth button
#login-button, #signup-button
position: absolute
top: 298px
height: 70px
font-size: 32px
line-height: 42px
border-image: url(/images/level/code_toolbar_submit_button_active.png) 14 20 20 20 fill round
border-width: 14px 20px 20px 20px
color: white
span
pointer-events: none
&:hover
border-image: url(/images/level/code_toolbar_submit_button_zazz.png) 14 20 20 20 fill round
color: white
&:active
border-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png) 14 20 20 20 fill round
padding: 2px 0 0 2px
color: white
//- Footer area
.auth-network-logins
position: absolute
top: 470px
width: 580px
left: 48px
padding-left: 29px
.btn.btn-lg.network-login
width: 251px
height: 60px
float: left
width: 100px
text-align: left
text-align: center
position: relative
margin-right: 15px
.network-logo
height: 30px
position: absolute
left: -10px
top: 2px
.sign-in-blurb
line-height: 34px
margin-left: 12px
.fb-login-button
$scaleX: 251 / 64
$scaleY: 60 / 23
transform: scale($scaleX, $scaleY)
position: absolute
top: 4px
left: 74px
@include opacity(0.01)
.gplus-login-wrapper
position: absolute
left: 65px
top: -6px
$scaleX: 251 / 84
$scaleY: 60 / 24
transform: scale($scaleX, $scaleY)
@include opacity(0.01)
#github-login-button
position: relative
@ -14,15 +215,67 @@
#gplus-login-button
position: relative
top: 1px
top: 8px
#recover-account-wrapper
float: right
.modal-footer
height: 70px
padding: 20px 10px
border-top: 1px solid darkgray
//- Extra bottom pane area
.extra-pane
background-image: url(/images/pages/modal/auth/extra-pane.png)
width: 633px
height: 139px
padding: 23px 23px 23px 168px
position: absolute
top: 520px
.switch-explanation
margin: 25px 10px 0 0
width: 200px
color: rgb(254,188,68)
font-size: 20px
font-family: 'Open Sans Condensed'
font-weight: bold
text-transform: uppercase
text-shadow: black 1px 1px 0, black -1px -1px 0, black 1px -1px 0, black -1px 1px 0, black 1px 0px 0, black 0px -1px 0, black -1px 0px 0, black 0px 1px 0
float: left
.btn
margin-right: 10px
float: right
margin-top: 20px
width: 230px
height: 70px
line-height: 40px
//- Login-specific styling
&.login
.modal-dialog
height: 582px
#login-button, #signup-button
top: 186px
.auth-network-logins
top: 358px
.extra-pane
top: 408px
html.no-borderimage #auth-modal
#login-button, #signup-button
border: 0
background-image: url(/images/level/code_toolbar_submit_button_active.png)
background-size: 100% 100%
padding: 7px 10px 10px 10px
&:hover
background-image: url(/images/level/code_toolbar_submit_button_zazz.png)
border: 0
&:active
background-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png)
padding: 9px 8px 8px 12px
border: 0

View file

@ -1,15 +1,24 @@
extends /templates/core/modal-base
.modal-dialog
.modal-content
block modal-header-content
if mode === 'login'
h3(data-i18n="login.log_in") Log In
img(src="/images/pages/modal/auth/login-background.png", draggable="false").auth-modal-background
else
img(src="/images/pages/modal/auth/signup-background.png", draggable="false").auth-modal-background
if mode === 'login'
h1(data-i18n="login.log_in") Log In
if mode === 'signup'
if title === 'short'
h3(data-i18n="login.sign_up") Create Account
h1(data-i18n="login.sign_up") Create Account
else
h3(data-i18n="signup.create_account_title") Create Account to Save Progress
h1(data-i18n="signup.create_account_title").long-title Create Account to Save Progress
block modal-body-content
div#close-modal
span.glyphicon.glyphicon-remove
.auth-form-content
if showRequiredError
.alert.alert-success
@ -19,67 +28,74 @@ block modal-body-content
p(data-i18n="signup.description") It's free. Just need a couple things and you'll be good to go:
form.form
if onEmployersPage
.form-group
input#email.input-large.form-control(name="email", type="email", value=formValues.email, placeholder="Email")
.form-group
input#password.input-large.form-control(name="password", type="password", value=formValues.password, placeholder="Password")
else
.form-group
label.control-label(for="email", data-i18n="general.email") Email
label.control-label(for="email")
span(data-i18n="general.email") Email
| :
.input-border
input#email.input-large.form-control(name="email", type="email", value=formValues.email)
.form-group
label.control-label(for="password", data-i18n="general.password") Password
if mode === 'login'
div#recover-account-wrapper
a(data-toggle="coco-modal", data-target="core/RecoverModal", data-i18n="login.forgo_password")#link-to-recover Forgot your password?
label.control-label(for="password")
span(data-i18n="general.password") Password
| :
.input-border
input#password.input-large.form-control(name="password", type="password", value=formValues.password)
if mode === 'signup'
.form-group
label.control-label(for="name", data-i18n="general.name") Name
label.control-label(for="name")
span(data-i18n="general.name") Name
| :
.input-border
if me.get('name')
input#name.input-large.form-control(name="name", type="text", value="#{me.get('name')}")
else
input#name.input-large.form-control(name="name", type="text", value="", placeholder="Anoner")
.form-group.checkbox
label.control-label(for="subscribe")
.input-border
input#subscribe(name="subscribe", type="checkbox", checked='checked')
span.custom-checkbox
.glyphicon.glyphicon-ok
span(data-i18n="signup.email_announcements") Receive announcements by email
.form-group.checkbox
label.control-label(for="confirm-age")
input#confirm-age(name="confirm-age", type="checkbox", checked='checked')
span(data-i18n="signup.coppa") 13+ or non-USA
a(href="https://en.wikipedia.org/wiki/Children's_Online_Privacy_Protection_Act", data-i18n="signup.coppa_why", target="_blank") (Why?)
if mode === 'login'
if onEmployersPage
input.btn.btn-info.btn-large#login-button(value=translate("login.log_in"), type="submit")
else
input.btn.btn-info.btn-large#login-button(value=translate("login.log_in"), type="submit")
.btn.btn-default.btn-large#switch-to-signup-button(data-i18n="login.sign_up") Create Account
input.btn.btn-lg.btn-illustrated.btn-block#login-button(value=translate("login.log_in"), type="submit")
else if mode === 'signup'
input.btn.btn-info.btn-large#signup-button(value=translate("signup.sign_up"), type="submit")
.btn.btn-default.btn-large#switch-to-login-button(data-i18n="login.log_in")
block modal-body-wait-content
input.btn.btn-lg.btn-illustrated.btn-block#signup-button(value=translate("signup.sign_up"), type="submit")
.wait.secret
if mode === 'login'
h3(data-i18n="login.logging_in") Logging In
if mode === 'signup'
h3(data-i18n="signup.creating") Creating Account...
block modal-footer
.modal-footer
.auth-network-logins
// GitHub login too buggy to survive
//div.network-login
// btn.btn.btn-sm.github-login-button#github-login-button
// img(src="/images/pages/modal/auth/github_icon.png")
// | GitHub
div.network-login
.btn.btn-primary.btn-lg.btn-illustrated.network-login
img.network-logo(src="/images/pages/community/logo_facebook.png", draggable="false")
span.sign-in-blurb(data-i18n="login.sign_in_with_facebook") Sign in with Facebook
.facebook-login-wrapper
.fb-login-button(data-show-faces="false", data-width="200", data-max-rows="1", data-scope="email")
// Google+ login causing script errors on IE10
if !isIE
div.network-login
.btn.btn-danger.btn-lg.btn-illustrated.network-login
img.network-logo(src="/images/pages/community/logo_g+.png", draggable="false")
span.sign-in-blurb(data-i18n="login.sign_in_with_gplus") Sign in with G+
.gplus-login-wrapper
.gplus-login-button#gplus-login-button
div#recover-account-wrapper
a(data-toggle="coco-modal", data-target="core/RecoverModal", data-i18n="login.recover")#link-to-recover recover account
.extra-pane
if mode === 'login'
.switch-explanation(data-i18n="login.signup_switch") Want to create an account?
.btn.btn-default.btn-lg.btn-illustrated#switch-to-signup-button(data-i18n="login.sign_up") Create Account
else if mode === 'signup'
.switch-explanation(data-i18n="signup.login_switch") Already have an account?
.btn.btn-default.btn-lg.btn-illustrated#switch-to-login-button(data-i18n="login.log_in")

View file

@ -74,16 +74,6 @@ block modal-body-content
dt(title=ctrlName + " " + shift + " M")
kbd #{ctrl} ⇧ M
dd(data-i18n="keyboard_shortcuts.maximize_editor") Maximize/minimize code editor.
dl.dl-horizontal
dt(title="Arrow keys")
kbd ←
| ,
kbd →
| ,
kbd ↑
| ,
kbd ↓
dd(data-i18n="keyboard_shortcuts.move_wizard") Move your Wizard around the level.
block modal-footer-content
a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="modal.close").btn.btn-primary Close

View file

@ -31,8 +31,9 @@
if itemGroups.availableItems.models.length
h4#available-description(data-i18n="inventory.available_item")
for item in itemGroups.availableItems.models
if selectedHeroClass && item.classes.indexOf(selectedHeroClass) > -1
.item.available(class=item.classes, data-item-id=item.id)
img(src=item.getPortraitURL())
img
button.btn.equip-item(data-i18n="inventory.equip")
.clearfix
@ -43,15 +44,17 @@
if itemGroups.restrictedItems.models.length
h4#restricted-description(data-i18n="inventory.restricted_title")
for item in itemGroups.restrictedItems.models
if selectedHeroClass && item.classes.indexOf(selectedHeroClass) > -1
.item(class=item.classes, data-item-id=item.id)
img(src=item.getPortraitURL(), draggable="false")
img(draggable="false")
.clearfix
if itemGroups.lockedItems.models.length
h4#locked-description(data-i18n="play.locked")
for item in itemGroups.lockedItems.models
if selectedHeroClass && item.classes.indexOf(selectedHeroClass) > -1
.item(class=item.classes, data-item-id=item.id)
img(src=item.getPortraitURL(), draggable="false")
img(draggable="false")
.clearfix
#item-details-view

View file

@ -14,11 +14,11 @@ module.exports = class AuthModal extends ModalView
# login buttons
'click #switch-to-signup-button': 'onSignupInstead'
'click #switch-to-login-button': 'onLoginInstead'
'click #confirm-age': 'checkAge'
'click #github-login-button': 'onGitHubLoginClicked'
'submit': 'onSubmitForm' # handles both submit buttons
'keyup #name': 'onNameChange'
'click #gplus-login-button': 'onClickGPlusLogin'
'click #close-modal': 'hide'
subscriptions:
'errors:server-error': 'onServerError'
@ -40,10 +40,13 @@ module.exports = class AuthModal extends ModalView
application.tracker.trackEvent 'Started Signup', authModalTitle: c.title, descriptionOn: c.descriptionOn
c.mode = @mode
c.formValues = @previousFormInputs or {}
c.onEmployersPage = Backbone.history.fragment is "employers"
c.me = me
c
afterRender: ->
super()
@$el.toggleClass('signup', @mode is 'signup').toggleClass('login', @mode is 'login')
afterInsert: ->
super()
_.delay (=> application.router.renderLoginButtons()), 500
@ -69,10 +72,6 @@ module.exports = class AuthModal extends ModalView
if @mode is 'login' then @loginAccount() else @createAccount()
false
checkAge: (e) ->
@playSound 'menu-button-click'
$('#signup-button', @$el).prop 'disabled', not $(e.target).prop('checked')
loginAccount: ->
forms.clearFormAlerts(@$el)
userObject = forms.formToObject @$el
@ -85,7 +84,6 @@ module.exports = class AuthModal extends ModalView
forms.clearFormAlerts(@$el)
userObject = forms.formToObject @$el
delete userObject.subscribe
delete userObject['confirm-age']
delete userObject.name if userObject.name is ''
userObject.name = @suggestedName if @suggestedName
for key, val of me.attributes when key in ['preferredLanguage', 'testGroupNumber', 'dateCreated', 'wizardColor1', 'name', 'music', 'volume', 'emails']

View file

@ -299,7 +299,7 @@ module.exports = class WorldMapView extends RootView
Backbone.Mediator.subscribeOnce 'audio-player:loaded', @playAmbientSound, @
return
@ambientSound = createjs.Sound.play src, loop: -1, volume: 0.1
createjs.Tween.get(@ambientSound).to({volume: 1.0}, 1000)
createjs.Tween.get(@ambientSound).to({volume: 0.5}, 1000)
playMusic: ->
@musicPlayer = new MusicPlayer()

View file

@ -35,6 +35,7 @@ module.exports = class InventoryModal extends ModalView
'click #close-modal': 'hide'
'click .buy-gems-prompt-button': 'onBuyGemsPromptButtonClicked'
'click': 'onClickedSomewhere'
'update #unequipped .nano': 'onScrollUnequipped'
shortcuts:
'esc': 'clearSelection'
@ -44,6 +45,7 @@ module.exports = class InventoryModal extends ModalView
#- Setup
initialize: (options) ->
@onScrollUnequipped = _.throttle(_.bind(@onScrollUnequipped, @), 200)
super(arguments...)
@items = new CocoCollection([], {model: ThangType})
# TODO: switch to item store loading system?
@ -121,6 +123,7 @@ module.exports = class InventoryModal extends ModalView
context.itemGroups = @itemGroups
context.slots = @slots
context.selectedHero = @selectedHero
context.selectedHeroClass = @selectedHero?.get('heroClass')
context.equipment = _.clone @equipment
context.equipment[slot] = @items.findWhere {original: itemOriginal} for slot, itemOriginal of context.equipment
context.gems = me.gems()
@ -526,6 +529,21 @@ module.exports = class InventoryModal extends ModalView
@$el.find('.unlock-button').popover 'destroy'
#- Dynamic portrait loading
onScrollUnequipped: ->
# dynamically load visible items when the user scrolls enough to see them
nanoContent = @$el.find('#unequipped .nano-content')
items = nanoContent.find('.item:visible:not(.loaded)')
threshold = nanoContent.height() + 100
for itemEl in items
itemEl = $(itemEl)
if itemEl.position().top < threshold
itemEl.addClass('loaded')
item = @items.get(itemEl.data('item-id'))
itemEl.find('img').attr('src', item.getPortraitURL())
#- Paper doll equipment updating
onEquipmentChanged: ->
heroClass = @selectedHero?.get('heroClass') ? 'Warrior'
@ -544,6 +562,7 @@ module.exports = class InventoryModal extends ModalView
@$el.find('#hero-image-thumb').toggle not ('gloves' in slotsWithImages)
@equipment = @options.equipment = equipment
@onScrollUnequipped()
removeDollImages: ->
@$el.find('.doll-image').remove()

View file

@ -53,10 +53,20 @@ module.exports = class SubscribeModal extends ModalView
return @openModalView new AuthModal() if me.get('anonymous')
application.tracker?.trackEvent 'Started subscription purchase', {}
application.tracker?.trackPageView "subscription/start-purchase", ['Google Analytics']
stripeHandler.open({
options = {
description: $.i18n.t('subscribe.stripe_description')
amount: @product.amount
})
}
# SALE LOGIC
# overwrite amount with sale price
# maybe also put in another description with details about how long it lasts, etc
# options = {
# description: 'Subscription. Half price for three months!'
# amount: 499
# }
stripeHandler.open(options)
onStripeReceivedToken: (e) ->
@state = 'purchasing'

View file

@ -68,6 +68,11 @@ class SubscriptionHandler extends Handler
checkForExistingSubscription: (req, user, customer, done) ->
couponID = user.get('stripe')?.couponID
# SALE LOGIC
# overwrite couponID with another for everyone-sales
# couponID = 'hoc_bonanza' if not couponID
if subscription = customer.subscriptions?.data?[0]
if subscription.cancel_at_period_end