From 013ace65f6e050b7d72fddb758d808ef2622c4a7 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 9 Jul 2014 16:24:14 -0700 Subject: [PATCH 01/58] Basic email structure plus distributed locking system --- app/schemas/models/mail_sent.coffee | 16 +++++++++++++++ app/schemas/models/mail_task.coffee | 21 +++++++++++++++++++ server/commons/LockManager.coffee | 24 ++++++++++++++++++++++ server/commons/mapping.coffee | 2 ++ server/mail/sent/MailSent.coffee | 11 ++++++++++ server/mail/sent/mail_sent_handler.coffee | 12 +++++++++++ server/mail/tasks/MailTask.coffee | 7 +++++++ server/mail/tasks/mail_task_handler.coffee | 12 +++++++++++ server/routes/mail.coffee | 20 +++++++++++++++++- server_config.coffee | 4 ++++ 10 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 app/schemas/models/mail_sent.coffee create mode 100644 app/schemas/models/mail_task.coffee create mode 100644 server/commons/LockManager.coffee create mode 100644 server/mail/sent/MailSent.coffee create mode 100644 server/mail/sent/mail_sent_handler.coffee create mode 100644 server/mail/tasks/MailTask.coffee create mode 100644 server/mail/tasks/mail_task_handler.coffee diff --git a/app/schemas/models/mail_sent.coffee b/app/schemas/models/mail_sent.coffee new file mode 100644 index 000000000..4236ad94b --- /dev/null +++ b/app/schemas/models/mail_sent.coffee @@ -0,0 +1,16 @@ +c = require './../schemas' +#This will represent transactional emails which have been sent + +MailSentSchema = c.object { + title: 'Sent mail' + description: 'Emails which have been sent through the system' +} +_.extend MailSentSchema.properties, + mailTask: c.objectId {} + user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}] + sent: c.date title: 'Sent', readOnly: true + +c.extendBasicProperties MailSentSchema, 'mail.sent' + +module.exports = MailSentSchema + \ No newline at end of file diff --git a/app/schemas/models/mail_task.coffee b/app/schemas/models/mail_task.coffee new file mode 100644 index 000000000..ac450e0ee --- /dev/null +++ b/app/schemas/models/mail_task.coffee @@ -0,0 +1,21 @@ +c = require './../schemas' +#This will represent transactional emails which have been sent + +MailTaskSchema = c.object { + title: 'Mail task' + description: 'Mail tasks to call at certain intervals' +} +_.extend MailTaskSchema.properties, + url: + title: 'URL' + description: 'The associated URL of the mailtask to call' + type: 'string' + frequency: + title: 'Frequency' + description: 'The number of seconds the servers should check whether or not to send the email' + type: 'integer' + +c.extendBasicProperties MailTaskSchema, 'mail.task' + +module.exports = MailTaskSchema + \ No newline at end of file diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee new file mode 100644 index 000000000..83dd43efc --- /dev/null +++ b/server/commons/LockManager.coffee @@ -0,0 +1,24 @@ +config = require '../../server_config' +redis = require 'redis' +class LockManager + constructor: -> + unless config.isProduction or config.redis.host isnt "localhost" + throw "You shouldn't be instantiating distributed locks unless in production." + @redisClient = redis.createClient config.redis.port, config.redis.host + @lockValues = {} + @unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end" + + setLock: (lockName, timeoutMs, cb) => + randomNumber = Math.floor(Math.random() * 1000000000) + @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) -> + if err? then return cb err, null + @lockValues[lockName] = randomNumber + cb null, res + + releaseLock: (lockName, cb) => + @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> + if err? then return cb err, null + #1 represents success, 0 failure + cb null, Boolean(Number(res)) + +module.exports = new RedisLock() \ No newline at end of file diff --git a/server/commons/mapping.coffee b/server/commons/mapping.coffee index 802b33790..faa0ef551 100644 --- a/server/commons/mapping.coffee +++ b/server/commons/mapping.coffee @@ -9,6 +9,8 @@ module.exports.handlers = 'thang_type': 'levels/thangs/thang_type_handler' 'user': 'users/user_handler' 'user_remark': 'users/remarks/user_remark_handler' + 'mail_task': 'mail/tasks/mail_task_handler' + 'mail_sent': 'mail/sent/mail_sent_handler' 'achievement': 'achievements/achievement_handler' 'earned_achievement': 'achievements/earned_achievement_handler' diff --git a/server/mail/sent/MailSent.coffee b/server/mail/sent/MailSent.coffee new file mode 100644 index 000000000..7f59dd5b0 --- /dev/null +++ b/server/mail/sent/MailSent.coffee @@ -0,0 +1,11 @@ +mongoose = require 'mongoose' +plugins = require '../../plugins/plugins' +jsonschema = require '../../../app/schemas/models/mail_sent' + +MailSent = new mongoose.Schema({ + sent: + type: Date + 'default': Date.now +}, {strict: false}) + +module.exports = MailSent = mongoose.model('mailSent', MailSent) diff --git a/server/mail/sent/mail_sent_handler.coffee b/server/mail/sent/mail_sent_handler.coffee new file mode 100644 index 000000000..35e920c2b --- /dev/null +++ b/server/mail/sent/mail_sent_handler.coffee @@ -0,0 +1,12 @@ +MailSent = require './MailSent' +Handler = require '../../commons/Handler' + +class MailSentHandler extends Handler + modelClass: MailSent + editableProperties: ['mailTask','user','sent'] + jsonSchema: require '../../../app/schemas/models/mail_sent' + + hasAccess: (req) -> + req.user?.isAdmin() + +module.exports = new MailSentHandler() diff --git a/server/mail/tasks/MailTask.coffee b/server/mail/tasks/MailTask.coffee new file mode 100644 index 000000000..10a536787 --- /dev/null +++ b/server/mail/tasks/MailTask.coffee @@ -0,0 +1,7 @@ +mongoose = require 'mongoose' +plugins = require '../../plugins/plugins' +jsonschema = require '../../../app/schemas/models/mail_task' + +MailTaskSchema = new mongoose.Schema({}, {strict: false}) + +module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema) diff --git a/server/mail/tasks/mail_task_handler.coffee b/server/mail/tasks/mail_task_handler.coffee new file mode 100644 index 000000000..12b6be53a --- /dev/null +++ b/server/mail/tasks/mail_task_handler.coffee @@ -0,0 +1,12 @@ +MailTask = require './MailTask' +Handler = require '../../commons/Handler' + +class MailTaskHandler extends Handler + modelClass: MailTask + editableProperties: ['url','frequency'] + jsonSchema: require '../../../app/schemas/models/mail_task' + + hasAccess: (req) -> + req.user?.isAdmin() + +module.exports = new MailTaskHandler() diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 4fdcef128..ae8b62e86 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,4 +1,5 @@ mail = require '../commons/mail' +MailTask = require '../mail/tasks/MailTask' User = require '../users/User' errors = require '../commons/errors' config = require '../../server_config' @@ -6,11 +7,16 @@ LevelSession = require '../levels/sessions/LevelSession' Level = require '../levels/Level' log = require 'winston' sendwithus = require '../sendwithus' - +if config.isProduction || true + redis = require 'redis' + redisClient = redis.createClient(config.redis.port,config.redis.host) module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate + app.post '/mail/task', createMailTask + + #setInterval(handleScheduledMail, 5000) DEBUGGING = false @@ -28,6 +34,18 @@ isRequestFromDesignatedCronHandler = (req, res) -> return false return true +createMailTask = (req, res) -> + #unless req.user?.isAdmin() then return errors.forbidden(res) + unless req.body.url and req.body.frequency then return errors.badInput(res) + console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}" + newMailTask = new MailTask {} + newMailTask.set("url",req.body.url) + newMailTask.set("frequency",req.body.frequency) + newMailTask.save (err) -> + if err? then return errors.serverError(res, err) + res.send("Created mail task!") + res.end() + handleLadderUpdate = (req, res) -> log.info('Going to see about sending ladder update emails.') requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res diff --git a/server_config.coffee b/server_config.coffee index 6018bf84f..13fc4e7d1 100644 --- a/server_config.coffee +++ b/server_config.coffee @@ -12,6 +12,10 @@ config.mongo = host: process.env.COCO_MONGO_HOST or 'localhost' db: process.env.COCO_MONGO_DATABASE_NAME or 'coco' mongoose_replica_string: process.env.COCO_MONGO_MONGOOSE_REPLICA_STRING or '' + +config.redis = + port: process.env.COCO_REDIS_PORT or 6379 + host: process.env.COCO_REDIS_HOST or 'localhost' if config.unittest config.port += 1 From b74bdfbf51e000af18c5537835a49c898b5030b7 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 12:12:11 -0700 Subject: [PATCH 02/58] Added metadata to mail sent schema --- app/schemas/models/mail_sent.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/schemas/models/mail_sent.coffee b/app/schemas/models/mail_sent.coffee index 4236ad94b..4cd54e241 100644 --- a/app/schemas/models/mail_sent.coffee +++ b/app/schemas/models/mail_sent.coffee @@ -9,6 +9,7 @@ _.extend MailSentSchema.properties, mailTask: c.objectId {} user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}] sent: c.date title: 'Sent', readOnly: true + metadata: c.object {}, {} c.extendBasicProperties MailSentSchema, 'mail.sent' From 3ef5d88e2ac4f07500b0a5cd1e9616c01512d8bf Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 12:12:25 -0700 Subject: [PATCH 03/58] Updated sendwithus to fix memory leak --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cba6e383e..21231684c 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "express-useragent": "~0.0.9", "gridfs-stream": "0.4.x", "stream-buffers": "0.2.x", - "sendwithus": "2.0.x", + "sendwithus": "2.1.x", "aws-sdk": "~2.0.0", "bayesian-battle": "0.0.x", "redis": "", From 449f1e1afcb0e1a7f6ac4b3386b78822d9c1adf6 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 12:12:44 -0700 Subject: [PATCH 04/58] Updated locking/release procedure --- server/commons/LockManager.coffee | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee index 83dd43efc..56604381b 100644 --- a/server/commons/LockManager.coffee +++ b/server/commons/LockManager.coffee @@ -1,5 +1,6 @@ config = require '../../server_config' redis = require 'redis' + class LockManager constructor: -> unless config.isProduction or config.redis.host isnt "localhost" @@ -10,15 +11,20 @@ class LockManager setLock: (lockName, timeoutMs, cb) => randomNumber = Math.floor(Math.random() * 1000000000) - @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) -> + @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) => if err? then return cb err, null - @lockValues[lockName] = randomNumber - cb null, res + if res is "OK" + @lockValues[lockName] = randomNumber + return cb null, "Lock set!" + unless res + return cb "Lock already set!", null releaseLock: (lockName, cb) => @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> if err? then return cb err, null - #1 represents success, 0 failure - cb null, Boolean(Number(res)) - -module.exports = new RedisLock() \ No newline at end of file + if res + cb null, "The lock was released!" + else + cb "The lock was not released.", null + +module.exports = new LockManager() From 3a405e22f3ee2efe31f7a4f0b22e7c7bbcdc9de7 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 12:12:54 -0700 Subject: [PATCH 05/58] Changed name of mail sent collection --- server/mail/sent/MailSent.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/mail/sent/MailSent.coffee b/server/mail/sent/MailSent.coffee index 7f59dd5b0..f8479033a 100644 --- a/server/mail/sent/MailSent.coffee +++ b/server/mail/sent/MailSent.coffee @@ -8,4 +8,4 @@ MailSent = new mongoose.Schema({ 'default': Date.now }, {strict: false}) -module.exports = MailSent = mongoose.model('mailSent', MailSent) +module.exports = MailSent = mongoose.model('mail.sent', MailSent) From e218c2297db205a02cd701d97b37ff738ab347aa Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 12:13:21 -0700 Subject: [PATCH 06/58] Some emails working --- server/routes/mail.coffee | 201 +++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 5 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index ae8b62e86..784f4c099 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,23 +1,213 @@ mail = require '../commons/mail' MailTask = require '../mail/tasks/MailTask' +MailSent = require '../mail/sent/MailSent' User = require '../users/User' +async = require 'async' errors = require '../commons/errors' config = require '../../server_config' LevelSession = require '../levels/sessions/LevelSession' Level = require '../levels/Level' log = require 'winston' sendwithus = require '../sendwithus' -if config.isProduction || true - redis = require 'redis' - redisClient = redis.createClient(config.redis.port,config.redis.host) +if config.isProduction or config.redis.host isnt "localhost" + lockManager = require '../commons/LockManager' + module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate app.post '/mail/task', createMailTask - - #setInterval(handleScheduledMail, 5000) + if lockManager + setupScheduledEmails() +setupScheduledEmails = -> + testForLockManager() + mailTaskMap = + "test_mail_task": candidateUpdateProfileTask + + MailTask.find({}).lean().exec (err, mailTasks) -> + if err? then throw "Failed to schedule mailTasks! #{err}" + for mailTask in mailTasks + setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 + +testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" + +### Candidate Update Reminder Task ### +emailTimeRange = (timeRange, finalCallback) -> + waterfallContext = + "timeRange": timeRange + "mailTaskName": @mailTaskName + async.waterfall [ + findAllCandidatesWithinTimeRange.bind(waterfallContext) + (unfilteredCandidates, cb) -> #now filter the candidates to see if they are eligible + async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), (filtered) -> cb null, filtered + (filteredCandidates, cb) -> #Now send emails to the eligible candidates and record. + async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb + ], finalCallback + +findAllCandidatesWithinTimeRange = (cb) -> + findParameters = + "jobProfile.updated": + $gt: @timeRange.start + $lte: @timeRange.end + selection = "_id email jobProfile.name jobProfile.updated" + User.find(findParameters).select(selection).lean().exec cb + +candidateFilter = (candidate, sentEmailFilterCallback) -> + findParameters = + "user": candidate._id + "mailTask": @mailTaskName + "metadata.timeRangeName": @timeRange.name + "metadata.updated": candidate.jobProfile.updated + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? then return errors.serverError("Error fetching sent mail in email task") + sentEmailFilterCallback Boolean(sentMail.length) + +findEmployersSignedUpAfterDate = (dateObject, cb) -> + countParameters = + $or: [{"dateCreated": {$gte: dateObject}},{"signedEmployerAgreement":{$gte: dateObject}}] + employerAt: {$exists: true} + permissions: "employer" + User.count countParameters, cb + +sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> + findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) => + context = + email_id: "tem_CtTLsKQufxrxoPMn7upKiL" + recipient: + address: candidate.email + name: candidate.jobProfile.name + email_data: + profile_updated: candidate.jobProfile.updated #format nicely + new_company: employersAfterCount + log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})" + newSentMail = + mailTask: @mailTaskName + user: candidate._id + metadata: + timeRangeName: @timeRange.name + updated: candidate.jobProfile.updated + MailSent.create newSentMail, (err) -> + if err? then return sendEmailCallback err + sendwithus.api.send context, (err, result) -> + log.error "Error sending ladder update email: #{err} with result #{result}" if err + sendEmailCallback err + +generateWeekOffset = (originalDate, numberOfWeeks) -> + return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString() + +candidateUpdateProfileTask = -> + mailTaskName = "candidateUpdateProfileTask" + lockDurationMs = 6000 + currentDate = new Date() + timeRanges = [] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] + timeRanges.push + start: generateWeekOffset currentDate, weekPair[0] + end: generateWeekOffset currentDate, weekPair[1] + name: weekPair[2] + lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + if err? then return log.error "Error getting a task lock!" + async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) -> + if err then return log.error JSON.stringify err else log.info "Sent candidate update reminders!" + lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err + +### End Candidate Update Reminder Task ### +### Internal Candidate Update Reminder Email ### + +emailInternalCandidateUpdateReminder = (cb) -> + currentTime = new Date() + beginningOfUTCDay = new Date() + beginningOfUTCDay.setUTCHours(0,0,0,0) + asyncContext = + "beginningOfUTCDay": beginningOfUTCDay + "currentTime": currentTime + "mailTaskName": @mailTaskName + + async.waterfall [ + findCandidatesWhoUpdatedJobProfileToday.bind(asyncContext) + (unfilteredCandidates, cb) -> + async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null) + (filteredCandidates, cb) -> + async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb + ], cb + +findCandidatesWhoUpdatedJobProfileToday = (cb) -> + findParameters = + "jobProfile.updated": + $lte: @currentTime.toISOString() + gt: @beginningOfUTCDay.toISOString() + User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb + +candidatesUpdatedTodayFilter = (candidate, cb) -> + findParameters = + "user": candidate._id + "mailTask": @mailTaskName + "metadata.beginningOfUTCDay": @beginningOfUTCDay + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}") + cb Boolean(sentMail.length) + +sendInternalCandidateUpdateReminder = (candidate, cb) -> + context = + email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE" + recipient: + address: "team@codecombat.com" #Change to whatever email address is necessary + name: "The CodeCombat Team" + log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}" + + newSentMail = + mailTask: @mailTaskName + user: candidate._id + metadata: + beginningOfUTCDay: @beginningOfUTCDay + + MailSent.create newSentMail, (err) -> + if err? then return cb err + sendwithus.api.send context, (err, result) -> + log.error "Error sending ladder update email: #{err} with result #{result}" if err + cb err + +internalCandidateUpdateTask = -> + mailTaskName = "internalCandidateUpdateTask" + lockDurationMs = 6000 + lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + if err? then return log.error "Error getting a task lock!" + emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> + if err? then return log.error "There was an error sending the internal candidate update reminder." + lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err +### End Internal Candidate Update Reminder Email ### + +### Employer New Candidates Available Email ### +employerNewCandidatesAvailableTask = -> + # tem_CCcHKr95Nvu5bT7c7iHCtm + #initialize featuredDate to job profile updated + mailTaskName = "employerNewCandidatesAvailableTask" + lockDurationMs = 6000 + lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + +### End Employer New Candidates Available Email ### + +### New Recruit Leaderboard Email ### +newRecruitLeaderboardEmailTask = -> + # tem_kMQFCKX3v4DNAQDsMAsPJC + #maxRank and maxRankTime should be recorded if isSimulating is false + mailTaskName = "newRecruitLeaderboardEmailTask" + lockDurationMs = 6000 + lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + +### End New Recruit Leaderboard Email ### + +### Employer Matching Candidate Notification Email ### +employerMatchingCandidateNotificationTask = -> + # tem_mYsepTfWQ265noKfZJcbBH + #save email filters in their own collection + mailTaskName = "employerMatchingCandidateNotificationTask" + lockDurationMs = 6000 + lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + +### End Employer Matching Candidate Notification Email ### +### Ladder Update Email ### DEBUGGING = false LADDER_PREGAME_INTERVAL = 2 * 3600 * 1000 # Send emails two hours before players last submitted. @@ -169,6 +359,7 @@ getScoreHistoryGraphURL = (session, daysAgo) -> chartData = times.join(',') + '|' + scores.join(',') "https://chart.googleapis.com/chart?chs=600x75&cht=lxy&chtt=Score%3A+#{currentScore}&chts=222222,12,r&chf=a,s,000000FF&chls=2&chd=t:#{chartData}&chxt=y&chxr=0,#{minScore},#{maxScore}" +### End Ladder Update Email ### handleMailchimpWebHook = (req, res) -> post = req.body From 67f2eeb584eda3232d74432b5639cf0512c8a820 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 13:14:09 -0700 Subject: [PATCH 07/58] Progress on employer new candidates available email --- server/routes/mail.coffee | 64 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 784f4c099..dd09a5d02 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -23,7 +23,7 @@ module.exports.setup = (app) -> setupScheduledEmails = -> testForLockManager() mailTaskMap = - "test_mail_task": candidateUpdateProfileTask + "test_mail_task": employerNewCandidatesAvailableTask MailTask.find({}).lean().exec (err, mailTasks) -> if err? then throw "Failed to schedule mailTasks! #{err}" @@ -50,6 +50,7 @@ findAllCandidatesWithinTimeRange = (cb) -> "jobProfile.updated": $gt: @timeRange.start $lte: @timeRange.end + "jobProfileApproved": true selection = "_id email jobProfile.name jobProfile.updated" User.find(findParameters).select(selection).lean().exec cb @@ -109,7 +110,7 @@ candidateUpdateProfileTask = -> lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> if err? then return log.error "Error getting a task lock!" async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) -> - if err then return log.error JSON.stringify err else log.info "Sent candidate update reminders!" + if err then log.error JSON.stringify err else log.info "Sent candidate update reminders!" lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err ### End Candidate Update Reminder Task ### @@ -125,18 +126,19 @@ emailInternalCandidateUpdateReminder = (cb) -> "mailTaskName": @mailTaskName async.waterfall [ - findCandidatesWhoUpdatedJobProfileToday.bind(asyncContext) + findNonApprovedCandidatesWhoUpdatedJobProfileToday.bind(asyncContext) (unfilteredCandidates, cb) -> async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null) (filteredCandidates, cb) -> async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb ], cb -findCandidatesWhoUpdatedJobProfileToday = (cb) -> +findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) -> findParameters = "jobProfile.updated": $lte: @currentTime.toISOString() gt: @beginningOfUTCDay.toISOString() + "jobProfileApproved": false User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb candidatesUpdatedTodayFilter = (candidate, cb) -> @@ -174,17 +176,69 @@ internalCandidateUpdateTask = -> lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> if err? then return log.error "Error getting a task lock!" emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> - if err? then return log.error "There was an error sending the internal candidate update reminder." + if err? then log.error "There was an error sending the internal candidate update reminder." lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err ### End Internal Candidate Update Reminder Email ### ### Employer New Candidates Available Email ### + +emailEmployerNewCandidatesAvailableEmail = (cb) -> + currentTime = new Date() + asyncContext = + "currentTime": currentTime + "mailTaskName": @mailTaskName + + async.waterfall [ + findAllEmployers + makeEmployerNamesEasilyAccessible + (allEmployers, cb) -> + console.log "Found #{allEmployers.length} employers to email about new candidates available" + async.reject allEmployers, employersEmailedDigestMoreThanWeekAgoFilter.bind(asyncContext), cb.bind(null,null) + (employersToEmail, cb) -> + async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb + ], cb + +findAllEmployers = (cb) -> + findParameters = + "employerAt": + $exists: true + permissions: "employer" + User.find(findParameters).select("_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName").lean().exec cb + +makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> + #Make names easily accessible + for employer, index in allEmployers + if employer.signedEmployerAgreement?.data?.firstName + employer.name = employer.signedEmployerAgreement.data.firstName + " " + employer.signedEmployerAgreement.data.lastName + delete employer.signedEmployerAgreement + allEmployers[index] = employer + cb null, allEmployers + +employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> + findParameters = + "user": employer._id + "mailTask": @mailTaskName + "sent": + $lte: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}") + cb Boolean(sentMail.length) + +sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> + cb null + + employerNewCandidatesAvailableTask = -> # tem_CCcHKr95Nvu5bT7c7iHCtm #initialize featuredDate to job profile updated mailTaskName = "employerNewCandidatesAvailableTask" lockDurationMs = 6000 lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> + if err? then return log.error "There was an error getting a task lock!" + emailEmployerNewCandidatesAvailableEmail.apply {"mailTaskName":mailTaskName}, (err) -> + if err? then return log.error "There was an error performing the #{mailTaskName} email task." + lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err + ### End Employer New Candidates Available Email ### From 3c257a488df971e0ad1e3b6d7167984e838a0be7 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 13:54:05 -0700 Subject: [PATCH 08/58] Employer candidates available email completed --- server/routes/mail.coffee | 43 ++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index dd09a5d02..ee1728f1f 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -203,7 +203,8 @@ findAllEmployers = (cb) -> "employerAt": $exists: true permissions: "employer" - User.find(findParameters).select("_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName").lean().exec cb + selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated" + User.find(findParameters).select(selection).lean().exec cb makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> #Make names easily accessible @@ -219,17 +220,49 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> "user": employer._id "mailTask": @mailTaskName "sent": - $lte: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) + $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) MailSent.find(findParameters).lean().exec (err, sentMail) -> if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}") cb Boolean(sentMail.length) sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> - cb null - + lastLoginDate = employer.activity?.login?.last ? employer.dateCreated + countParameters = + "jobProfileApproved": true + "jobProfile": + $exists: true + $or: [ + jobProfileApprovedDate: + $gt: lastLoginDate.toISOString() + , + jobProfileApprovedDate: + $exists: false + "jobProfile.updated": + $gt: lastLoginDate.toISOString() + ] + User.count countParameters, (err, numberOfCandidatesSinceLogin) => + if err? then return cb err + context = + email_id: "tem_CCcHKr95Nvu5bT7c7iHCtm" + recipient: + address: employer.email + name: employer.name + email_data: + new_candidates: numberOfCandidatesSinceLogin + employer_company_name: employer.employerAt + company_name: "CodeCombat" + + log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})" + newSentMail = + mailTask: @mailTaskName + user: employer._id + MailSent.create newSentMail, (err) -> + if err? then return cb err + sendwithus.api.send context, (err, result) -> + log.error "Error sending ladder update email: #{err} with result #{result}" if err + cb err employerNewCandidatesAvailableTask = -> - # tem_CCcHKr95Nvu5bT7c7iHCtm #initialize featuredDate to job profile updated mailTaskName = "employerNewCandidatesAvailableTask" lockDurationMs = 6000 From 5c0c25ebd1235c9a225862496b40a031c966d21d Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 13:56:23 -0700 Subject: [PATCH 09/58] Async must not break upon sendwithus failure --- server/routes/mail.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index ee1728f1f..8983a7224 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -91,8 +91,8 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> MailSent.create newSentMail, (err) -> if err? then return sendEmailCallback err sendwithus.api.send context, (err, result) -> - log.error "Error sending ladder update email: #{err} with result #{result}" if err - sendEmailCallback err + log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err + sendEmailCallback null generateWeekOffset = (originalDate, numberOfWeeks) -> return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString() @@ -167,8 +167,8 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> MailSent.create newSentMail, (err) -> if err? then return cb err sendwithus.api.send context, (err, result) -> - log.error "Error sending ladder update email: #{err} with result #{result}" if err - cb err + log.error "Error sending interal candidate update email: #{err} with result #{result}" if err + cb null internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" @@ -259,8 +259,8 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> MailSent.create newSentMail, (err) -> if err? then return cb err sendwithus.api.send context, (err, result) -> - log.error "Error sending ladder update email: #{err} with result #{result}" if err - cb err + log.error "Error sending employer candidates available email: #{err} with result #{result}" if err + cb null employerNewCandidatesAvailableTask = -> #initialize featuredDate to job profile updated From 59a35c844fd0e04de3a9c75d9ea8dd53d7adc69a Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 14:29:30 -0700 Subject: [PATCH 10/58] Made mail system resilient to redis failures --- server/commons/LockManager.coffee | 12 ++++++++++++ server/routes/mail.coffee | 8 +++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee index 56604381b..bdd847bf7 100644 --- a/server/commons/LockManager.coffee +++ b/server/commons/LockManager.coffee @@ -1,15 +1,26 @@ config = require '../../server_config' redis = require 'redis' +log = require 'winston' class LockManager constructor: -> unless config.isProduction or config.redis.host isnt "localhost" throw "You shouldn't be instantiating distributed locks unless in production." @redisClient = redis.createClient config.redis.port, config.redis.host + @redisClient.on "ready", => + log.info "Redis ready!" + @redisNotAvailable = false + @redisClient.on "error", (err) => + @redisNotAvailable = true + log.error "Redis connection error! Err: #{err}" + @redisClient.on "end", => + @redisNotAvailable = true + log.error "Redis connection ended!" @lockValues = {} @unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end" setLock: (lockName, timeoutMs, cb) => + if @redisNotAvailable is true then return cb "Redis not available!" randomNumber = Math.floor(Math.random() * 1000000000) @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) => if err? then return cb err, null @@ -20,6 +31,7 @@ class LockManager return cb "Lock already set!", null releaseLock: (lockName, cb) => + if @redisNotAvailable is true then return cb "Redis not available!" @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> if err? then return cb err, null if res diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 8983a7224..0e34e06db 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -274,25 +274,27 @@ employerNewCandidatesAvailableTask = -> ### End Employer New Candidates Available Email ### - + ### New Recruit Leaderboard Email ### +### newRecruitLeaderboardEmailTask = -> # tem_kMQFCKX3v4DNAQDsMAsPJC #maxRank and maxRankTime should be recorded if isSimulating is false mailTaskName = "newRecruitLeaderboardEmailTask" lockDurationMs = 6000 lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> - +### ### End New Recruit Leaderboard Email ### ### Employer Matching Candidate Notification Email ### +### employerMatchingCandidateNotificationTask = -> # tem_mYsepTfWQ265noKfZJcbBH #save email filters in their own collection mailTaskName = "employerMatchingCandidateNotificationTask" lockDurationMs = 6000 lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> - +### ### End Employer Matching Candidate Notification Email ### ### Ladder Update Email ### From 24bcfd9f26b336a3ee98302e3b0ef12345f8fe63 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 15:50:31 -0700 Subject: [PATCH 11/58] Reviewed code, almost ready for release --- server/routes/mail.coffee | 196 +++++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 89 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 0e34e06db..6939d8080 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -9,9 +9,20 @@ LevelSession = require '../levels/sessions/LevelSession' Level = require '../levels/Level' log = require 'winston' sendwithus = require '../sendwithus' -if config.isProduction or config.redis.host isnt "localhost" +if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones lockManager = require '../commons/LockManager' - +#TODO: Ask Nick about email unsubscriptions +createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks + unless req.user?.isAdmin() then return errors.forbidden(res) + unless req.body.url and req.body.frequency then return errors.badInput(res) + console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}" + newMailTask = new MailTask {} + newMailTask.set("url",req.body.url) + newMailTask.set("frequency",req.body.frequency) + newMailTask.save (err) -> + if err? then return errors.serverError(res, err) + res.send("Created mail task!") + res.end() module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook @@ -22,28 +33,52 @@ module.exports.setup = (app) -> setupScheduledEmails = -> testForLockManager() - mailTaskMap = - "test_mail_task": employerNewCandidatesAvailableTask + mailTaskMap = #TODO: Edit this to include additional emails + "test_mail_task": candidateUpdateProfileTask - MailTask.find({}).lean().exec (err, mailTasks) -> + MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this if err? then throw "Failed to schedule mailTasks! #{err}" for mailTask in mailTasks - setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 + setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" ### Candidate Update Reminder Task ### -emailTimeRange = (timeRange, finalCallback) -> + +candidateUpdateProfileTask = -> + mailTaskName = "candidateUpdateProfileTask" + lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency) + currentDate = new Date() + timeRanges = [] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] + timeRanges.push + start: generateWeekOffset currentDate, weekPair[0] + end: generateWeekOffset currentDate, weekPair[1] + name: weekPair[2] + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" + async.each timeRanges, emailTimeRange.bind({mailTaskName: mailTaskName}), (err) -> + if err + log.error "There was an error sending the candidate profile update reminder emails: #{err}" + else + log.info "Completed mail task #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +generateWeekOffset = (originalDate, numberOfWeeks) -> + return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString() + +emailTimeRange = (timeRange, emailTimeRangeCallback) -> waterfallContext = "timeRange": timeRange "mailTaskName": @mailTaskName async.waterfall [ findAllCandidatesWithinTimeRange.bind(waterfallContext) - (unfilteredCandidates, cb) -> #now filter the candidates to see if they are eligible - async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), (filtered) -> cb null, filtered - (filteredCandidates, cb) -> #Now send emails to the eligible candidates and record. + (unfilteredCandidates, cb) -> + async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), cb.bind(null, null) + (filteredCandidates, cb) -> async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb - ], finalCallback + ], emailTimeRangeCallback findAllCandidatesWithinTimeRange = (cb) -> findParameters = @@ -61,8 +96,11 @@ candidateFilter = (candidate, sentEmailFilterCallback) -> "metadata.timeRangeName": @timeRange.name "metadata.updated": candidate.jobProfile.updated MailSent.find(findParameters).lean().exec (err, sentMail) -> - if err? then return errors.serverError("Error fetching sent mail in email task") - sentEmailFilterCallback Boolean(sentMail.length) + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" + sentEmailFilterCallback true + else + sentEmailFilterCallback Boolean(sentMail.length) findEmployersSignedUpAfterDate = (dateObject, cb) -> countParameters = @@ -73,14 +111,18 @@ findEmployersSignedUpAfterDate = (dateObject, cb) -> sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) => + if err? + log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}" + return sendEmailCallback err context = email_id: "tem_CtTLsKQufxrxoPMn7upKiL" recipient: address: candidate.email name: candidate.jobProfile.name email_data: - profile_updated: candidate.jobProfile.updated #format nicely new_company: employersAfterCount + company_name: "CodeCombat" + user_profile: "http://codecombat.com/account/profile/#{candidate._id}" log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})" newSentMail = mailTask: @mailTaskName @@ -93,30 +135,22 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> sendwithus.api.send context, (err, result) -> log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err sendEmailCallback null - -generateWeekOffset = (originalDate, numberOfWeeks) -> - return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString() - -candidateUpdateProfileTask = -> - mailTaskName = "candidateUpdateProfileTask" - lockDurationMs = 6000 - currentDate = new Date() - timeRanges = [] - for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] - timeRanges.push - start: generateWeekOffset currentDate, weekPair[0] - end: generateWeekOffset currentDate, weekPair[1] - name: weekPair[2] - lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> - if err? then return log.error "Error getting a task lock!" - async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) -> - if err then log.error JSON.stringify err else log.info "Sent candidate update reminders!" - lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err - ### End Candidate Update Reminder Task ### ### Internal Candidate Update Reminder Email ### +internalCandidateUpdateTask = -> + mailTaskName = "internalCandidateUpdateTask" + lockDurationMs = 6000 #TODO: Change lock duration + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" + emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> + if err + log.error "There was an error sending the internal candidate update reminder.: #{err}" + else + log.info "Sent internal candidate update reminder email!" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" -emailInternalCandidateUpdateReminder = (cb) -> +emailInternalCandidateUpdateReminder = (internalCandidateUpdateReminderCallback) -> currentTime = new Date() beginningOfUTCDay = new Date() beginningOfUTCDay.setUTCHours(0,0,0,0) @@ -124,40 +158,43 @@ emailInternalCandidateUpdateReminder = (cb) -> "beginningOfUTCDay": beginningOfUTCDay "currentTime": currentTime "mailTaskName": @mailTaskName - async.waterfall [ findNonApprovedCandidatesWhoUpdatedJobProfileToday.bind(asyncContext) (unfilteredCandidates, cb) -> async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null) (filteredCandidates, cb) -> async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb - ], cb + ], internalCandidateUpdateReminderCallback findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) -> findParameters = "jobProfile.updated": $lte: @currentTime.toISOString() gt: @beginningOfUTCDay.toISOString() - "jobProfileApproved": false + "jobProfileApproved": false User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb candidatesUpdatedTodayFilter = (candidate, cb) -> findParameters = "user": candidate._id "mailTask": @mailTaskName - "metadata.beginningOfUTCDay": @beginningOfUTCDay + "metadata.beginningOfUTCDay": @beginningOfUTCDay MailSent.find(findParameters).lean().exec (err, sentMail) -> - if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}") - cb Boolean(sentMail.length) + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" + cb true + else + cb Boolean(sentMail.length) sendInternalCandidateUpdateReminder = (candidate, cb) -> context = email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE" - recipient: + recipient: address: "team@codecombat.com" #Change to whatever email address is necessary name: "The CodeCombat Team" + email_data: + new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}" log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}" - newSentMail = mailTask: @mailTaskName user: candidate._id @@ -169,20 +206,23 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> sendwithus.api.send context, (err, result) -> log.error "Error sending interal candidate update email: #{err} with result #{result}" if err cb null - -internalCandidateUpdateTask = -> - mailTaskName = "internalCandidateUpdateTask" - lockDurationMs = 6000 - lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> - if err? then return log.error "Error getting a task lock!" - emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> - if err? then log.error "There was an error sending the internal candidate update reminder." - lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err -### End Internal Candidate Update Reminder Email ### - -### Employer New Candidates Available Email ### -emailEmployerNewCandidatesAvailableEmail = (cb) -> +### End Internal Candidate Update Reminder Email ### +### Employer New Candidates Available Email ### +employerNewCandidatesAvailableTask = -> + mailTaskName = "employerNewCandidatesAvailableTask" + lockDurationMs = 6000 #TODO: Update this lock duration + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "There was an error getting a task lock!" + emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) -> + if err + log.error "There was an error completing the new candidates available task: #{err}" + else + log.info "Completed the employer new candidates available task!" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallback) -> currentTime = new Date() asyncContext = "currentTime": currentTime @@ -192,22 +232,20 @@ emailEmployerNewCandidatesAvailableEmail = (cb) -> findAllEmployers makeEmployerNamesEasilyAccessible (allEmployers, cb) -> - console.log "Found #{allEmployers.length} employers to email about new candidates available" async.reject allEmployers, employersEmailedDigestMoreThanWeekAgoFilter.bind(asyncContext), cb.bind(null,null) (employersToEmail, cb) -> async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb - ], cb + ], emailEmployerNewCandidatesAvailableCallback findAllEmployers = (cb) -> findParameters = "employerAt": - $exists: true + $exists: true permissions: "employer" selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated" User.find(findParameters).select(selection).lean().exec cb makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> - #Make names easily accessible for employer, index in allEmployers if employer.signedEmployerAgreement?.data?.firstName employer.name = employer.signedEmployerAgreement.data.firstName + " " + employer.signedEmployerAgreement.data.lastName @@ -222,15 +260,16 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> "sent": $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) MailSent.find(findParameters).lean().exec (err, sentMail) -> - if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}") - cb Boolean(sentMail.length) + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and employer #employer._id}!" + cb true + else + cb Boolean(sentMail.length) sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> - lastLoginDate = employer.activity?.login?.last ? employer.dateCreated + lastLoginDate = employer.activity?.login?.last ? employer.dateCreated countParameters = "jobProfileApproved": true - "jobProfile": - $exists: true $or: [ jobProfileApprovedDate: $gt: lastLoginDate.toISOString() @@ -246,12 +285,12 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> email_id: "tem_CCcHKr95Nvu5bT7c7iHCtm" recipient: address: employer.email - name: employer.name email_data: new_candidates: numberOfCandidatesSinceLogin employer_company_name: employer.employerAt company_name: "CodeCombat" - + if employer.name + context.recipient.name = employer.name log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})" newSentMail = mailTask: @mailTaskName @@ -262,17 +301,6 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> log.error "Error sending employer candidates available email: #{err} with result #{result}" if err cb null -employerNewCandidatesAvailableTask = -> - #initialize featuredDate to job profile updated - mailTaskName = "employerNewCandidatesAvailableTask" - lockDurationMs = 6000 - lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> - if err? then return log.error "There was an error getting a task lock!" - emailEmployerNewCandidatesAvailableEmail.apply {"mailTaskName":mailTaskName}, (err) -> - if err? then return log.error "There was an error performing the #{mailTaskName} email task." - lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err - - ### End Employer New Candidates Available Email ### ### New Recruit Leaderboard Email ### @@ -313,17 +341,7 @@ isRequestFromDesignatedCronHandler = (req, res) -> return false return true -createMailTask = (req, res) -> - #unless req.user?.isAdmin() then return errors.forbidden(res) - unless req.body.url and req.body.frequency then return errors.badInput(res) - console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}" - newMailTask = new MailTask {} - newMailTask.set("url",req.body.url) - newMailTask.set("frequency",req.body.frequency) - newMailTask.save (err) -> - if err? then return errors.serverError(res, err) - res.send("Created mail task!") - res.end() + handleLadderUpdate = (req, res) -> log.info('Going to see about sending ladder update emails.') From ae23679a26babc948d7b961ae4a7755e96ad5747 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 16:37:06 -0700 Subject: [PATCH 12/58] Hard code mail tasks and add unsubscribe --- app/schemas/models/mail_task.coffee | 21 ---------- server/mail/tasks/MailTask.coffee | 7 ---- server/mail/tasks/mail_task_handler.coffee | 12 ------ server/routes/auth.coffee | 5 ++- server/routes/mail.coffee | 49 +++++++++++----------- 5 files changed, 28 insertions(+), 66 deletions(-) delete mode 100644 app/schemas/models/mail_task.coffee delete mode 100644 server/mail/tasks/MailTask.coffee delete mode 100644 server/mail/tasks/mail_task_handler.coffee diff --git a/app/schemas/models/mail_task.coffee b/app/schemas/models/mail_task.coffee deleted file mode 100644 index ac450e0ee..000000000 --- a/app/schemas/models/mail_task.coffee +++ /dev/null @@ -1,21 +0,0 @@ -c = require './../schemas' -#This will represent transactional emails which have been sent - -MailTaskSchema = c.object { - title: 'Mail task' - description: 'Mail tasks to call at certain intervals' -} -_.extend MailTaskSchema.properties, - url: - title: 'URL' - description: 'The associated URL of the mailtask to call' - type: 'string' - frequency: - title: 'Frequency' - description: 'The number of seconds the servers should check whether or not to send the email' - type: 'integer' - -c.extendBasicProperties MailTaskSchema, 'mail.task' - -module.exports = MailTaskSchema - \ No newline at end of file diff --git a/server/mail/tasks/MailTask.coffee b/server/mail/tasks/MailTask.coffee deleted file mode 100644 index 10a536787..000000000 --- a/server/mail/tasks/MailTask.coffee +++ /dev/null @@ -1,7 +0,0 @@ -mongoose = require 'mongoose' -plugins = require '../../plugins/plugins' -jsonschema = require '../../../app/schemas/models/mail_task' - -MailTaskSchema = new mongoose.Schema({}, {strict: false}) - -module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema) diff --git a/server/mail/tasks/mail_task_handler.coffee b/server/mail/tasks/mail_task_handler.coffee deleted file mode 100644 index 12b6be53a..000000000 --- a/server/mail/tasks/mail_task_handler.coffee +++ /dev/null @@ -1,12 +0,0 @@ -MailTask = require './MailTask' -Handler = require '../../commons/Handler' - -class MailTaskHandler extends Handler - modelClass: MailTask - editableProperties: ['url','frequency'] - jsonSchema: require '../../../app/schemas/models/mail_task' - - hasAccess: (req) -> - req.user?.isAdmin() - -module.exports = new MailTaskHandler() diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index 5c3298f44..36c836741 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -143,7 +143,10 @@ module.exports.setup = (app) -> emails.recruitNotes ?= {} emails.recruitNotes.enabled = false msg = "Unsubscribed #{req.query.email} from recruiting emails." - + else if req.query.employerNotes + emails.employerNotes ?= {} + emails.employerNotes.enabled = false + msg = "Unsubscribed #{req.query.email} from employer emails." else msg = "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!" emailSettings.enabled = false for emailSettings in _.values(emails) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 6939d8080..3a41e5316 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,5 +1,4 @@ mail = require '../commons/mail' -MailTask = require '../mail/tasks/MailTask' MailSent = require '../mail/sent/MailSent' User = require '../users/User' async = require 'async' @@ -12,42 +11,36 @@ sendwithus = require '../sendwithus' if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones lockManager = require '../commons/LockManager' #TODO: Ask Nick about email unsubscriptions -createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks - unless req.user?.isAdmin() then return errors.forbidden(res) - unless req.body.url and req.body.frequency then return errors.badInput(res) - console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}" - newMailTask = new MailTask {} - newMailTask.set("url",req.body.url) - newMailTask.set("frequency",req.body.frequency) - newMailTask.save (err) -> - if err? then return errors.serverError(res, err) - res.send("Created mail task!") - res.end() module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate - app.post '/mail/task', createMailTask if lockManager setupScheduledEmails() setupScheduledEmails = -> testForLockManager() - mailTaskMap = #TODO: Edit this to include additional emails - "test_mail_task": candidateUpdateProfileTask + mailTasks = [ + taskFunction: candidateUpdateProfileTask + frequencyMs: 30 * 60 * 1000 #30 minutes + , + taskFunction: internalCandidateUpdateTask + frequencyMs: 10 * 60 * 1000 #10 minutes + , + taskFunction: employerNewCandidatesAvailableTask + frequencyMs: 30 * 60 * 1000 #30 minutes + ] + + for mailTask in mailTasks + setInterval mailTask.taskFunction, mailTask.frequencyMs - MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this - if err? then throw "Failed to schedule mailTasks! #{err}" - for mailTask in mailTasks - setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention - testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" ### Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" - lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency) + lockDurationMs = 2 * 60 * 1000 currentDate = new Date() timeRanges = [] for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] @@ -86,10 +79,13 @@ findAllCandidatesWithinTimeRange = (cb) -> $gt: @timeRange.start $lte: @timeRange.end "jobProfileApproved": true - selection = "_id email jobProfile.name jobProfile.updated" + selection = "_id email jobProfile.name jobProfile.updated emails" #make sure to check for anyNotes too. User.find(findParameters).select(selection).lean().exec cb candidateFilter = (candidate, sentEmailFilterCallback) -> + if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false + log.info "Candidate #{candidate.jobProfile.name} opted out of emails, not sending to them." + return sentEmailFilterCallback true findParameters = "user": candidate._id "mailTask": @mailTaskName @@ -139,7 +135,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" - lockDurationMs = 6000 #TODO: Change lock duration + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> @@ -211,7 +207,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> ### Employer New Candidates Available Email ### employerNewCandidatesAvailableTask = -> mailTaskName = "employerNewCandidatesAvailableTask" - lockDurationMs = 6000 #TODO: Update this lock duration + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "There was an error getting a task lock!" emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) -> @@ -242,7 +238,7 @@ findAllEmployers = (cb) -> "employerAt": $exists: true permissions: "employer" - selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated" + selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated emails" User.find(findParameters).select(selection).lean().exec cb makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> @@ -254,6 +250,9 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> cb null, allEmployers employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> + if employer.emails?.employerNotes?.enabled is false + log.info "Employer #{employer.name}(#{employer.email}) opted out of emails, not sending to them." + return sentEmailFilterCallback true findParameters = "user": employer._id "mailTask": @mailTaskName From fc4568a100dcc922e10564b5fabf58715c4885b4 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 17:02:40 -0700 Subject: [PATCH 13/58] Fixed misc bugs --- server/routes/mail.coffee | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 3a41e5316..45f90ac2d 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -10,8 +10,7 @@ log = require 'winston' sendwithus = require '../sendwithus' if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones lockManager = require '../commons/LockManager' -#TODO: Ask Nick about email unsubscriptions - + module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate @@ -84,7 +83,6 @@ findAllCandidatesWithinTimeRange = (cb) -> candidateFilter = (candidate, sentEmailFilterCallback) -> if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false - log.info "Candidate #{candidate.jobProfile.name} opted out of emails, not sending to them." return sentEmailFilterCallback true findParameters = "user": candidate._id @@ -138,7 +136,7 @@ internalCandidateUpdateTask = -> lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" - emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) -> + emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) -> if err log.error "There was an error sending the internal candidate update reminder.: #{err}" else @@ -166,7 +164,7 @@ findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) -> findParameters = "jobProfile.updated": $lte: @currentTime.toISOString() - gt: @beginningOfUTCDay.toISOString() + $gt: @beginningOfUTCDay.toISOString() "jobProfileApproved": false User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb @@ -209,8 +207,8 @@ employerNewCandidatesAvailableTask = -> mailTaskName = "employerNewCandidatesAvailableTask" lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> - if err? then return log.error "There was an error getting a task lock!" - emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) -> + if err? then return log.error "There was an error getting a task lock!: #{err}" + emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) -> if err log.error "There was an error completing the new candidates available task: #{err}" else From d821e459d171d438b62ea750c01864258686aea8 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 19:46:06 -0700 Subject: [PATCH 14/58] Encode/decode emails as URIs This helps to handle special characters like plusses. --- server/routes/auth.coffee | 6 ++++-- server/routes/mail.coffee | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index 36c836741..dd9dffee7 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -117,7 +117,8 @@ module.exports.setup = (app) -> ) ) - app.get '/auth/unsubscribe', (req, res) -> + app.get '/auth/unsubscribe', (req, res) -> + req.query.email = decodeURIComponent(req.query.email) email = req.query.email unless req.query.email return errors.badInput res, 'No email provided to unsubscribe.' @@ -131,7 +132,7 @@ module.exports.setup = (app) -> return errors.serverError res, 'Database failure.' if err res.send "Unsubscribed #{req.query.email} from CodeCombat emails for #{session.levelName} #{session.team} ladder updates. Sorry to see you go! <p><a href='/play/ladder/#{session.levelID}#my-matches'>Ladder preferences</a></p>" res.end() - + User.findOne({emailLower: req.query.email.toLowerCase()}).exec (err, user) -> if not user return errors.notFound res, "No user found with email '#{req.query.email}'" @@ -146,6 +147,7 @@ module.exports.setup = (app) -> else if req.query.employerNotes emails.employerNotes ?= {} emails.employerNotes.enabled = false + msg = "Unsubscribed #{req.query.email} from employer emails." else msg = "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!" diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 45f90ac2d..6490b4394 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -21,13 +21,13 @@ setupScheduledEmails = -> testForLockManager() mailTasks = [ taskFunction: candidateUpdateProfileTask - frequencyMs: 30 * 60 * 1000 #30 minutes + frequencyMs: 10 * 60 * 1000 #10 minutes , taskFunction: internalCandidateUpdateTask frequencyMs: 10 * 60 * 1000 #10 minutes , taskFunction: employerNewCandidatesAvailableTask - frequencyMs: 30 * 60 * 1000 #30 minutes + frequencyMs: 10 * 60 * 1000 #10 minutes ] for mailTask in mailTasks @@ -48,7 +48,7 @@ candidateUpdateProfileTask = -> end: generateWeekOffset currentDate, weekPair[1] name: weekPair[2] lockManager.setLock mailTaskName, lockDurationMs, (err) -> - if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" async.each timeRanges, emailTimeRange.bind({mailTaskName: mailTaskName}), (err) -> if err log.error "There was an error sending the candidate profile update reminder emails: #{err}" @@ -108,6 +108,8 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> if err? log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}" return sendEmailCallback err + if employersAfterCount < 2 + employersAfterCount = 2 context = email_id: "tem_CtTLsKQufxrxoPMn7upKiL" recipient: @@ -117,6 +119,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> new_company: employersAfterCount company_name: "CodeCombat" user_profile: "http://codecombat.com/account/profile/#{candidate._id}" + recipient_address: encodeURIComponent(candidate.email) log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})" newSentMail = mailTask: @mailTaskName @@ -135,7 +138,7 @@ internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> - if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!" + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) -> if err log.error "There was an error sending the internal candidate update reminder.: #{err}" @@ -207,7 +210,7 @@ employerNewCandidatesAvailableTask = -> mailTaskName = "employerNewCandidatesAvailableTask" lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> - if err? then return log.error "There was an error getting a task lock!: #{err}" + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) -> if err log.error "There was an error completing the new candidates available task: #{err}" @@ -249,7 +252,6 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> if employer.emails?.employerNotes?.enabled is false - log.info "Employer #{employer.name}(#{employer.email}) opted out of emails, not sending to them." return sentEmailFilterCallback true findParameters = "user": employer._id @@ -286,6 +288,7 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> new_candidates: numberOfCandidatesSinceLogin employer_company_name: employer.employerAt company_name: "CodeCombat" + recipient_address: encodeURIComponent(employer.email) if employer.name context.recipient.name = employer.name log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})" From c717e609eaace0e9e46ef06f05ba9f427cfba476 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 19:46:30 -0700 Subject: [PATCH 15/58] Initialize value of this.redisNotAvailable --- server/commons/LockManager.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee index bdd847bf7..bd0a89171 100644 --- a/server/commons/LockManager.coffee +++ b/server/commons/LockManager.coffee @@ -6,6 +6,7 @@ class LockManager constructor: -> unless config.isProduction or config.redis.host isnt "localhost" throw "You shouldn't be instantiating distributed locks unless in production." + @redisNotAvailable = true @redisClient = redis.createClient config.redis.port, config.redis.host @redisClient.on "ready", => log.info "Redis ready!" From 2a865a0ca06ddf453d9d02200f291a47d8def9dc Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Wed, 16 Jul 2014 19:49:48 -0700 Subject: [PATCH 16/58] Remove testing conditions --- server/commons/LockManager.coffee | 2 +- server/routes/mail.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee index bd0a89171..36936b236 100644 --- a/server/commons/LockManager.coffee +++ b/server/commons/LockManager.coffee @@ -4,7 +4,7 @@ log = require 'winston' class LockManager constructor: -> - unless config.isProduction or config.redis.host isnt "localhost" + unless config.isProduction throw "You shouldn't be instantiating distributed locks unless in production." @redisNotAvailable = true @redisClient = redis.createClient config.redis.port, config.redis.host diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 6490b4394..4098402b0 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -8,7 +8,7 @@ LevelSession = require '../levels/sessions/LevelSession' Level = require '../levels/Level' log = require 'winston' sendwithus = require '../sendwithus' -if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones +if config.isProduction lockManager = require '../commons/LockManager' module.exports.setup = (app) -> From c56be0222295aa404ddcbd167b7e590eecd1e9d6 Mon Sep 17 00:00:00 2001 From: Alan Shen <sunzenshen@gmail.com> Date: Thu, 17 Jul 2014 01:16:08 -0600 Subject: [PATCH 17/58] Fixed typo: Chose -> Choose It may be late to describe incoming targets with past tense. --- app/views/play_view.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index bd7a412e7..c6679a3f4 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -117,7 +117,7 @@ module.exports = class PlayView extends View difficulty: 2 id: 'emphasis-on-aim' image: '/file/db/level/525f384d96cd77000000000f/munchkin_masher_icon.png' - description: 'Chose your targets carefully.' + description: 'Choose your targets carefully.' } { name: 'Zone of Danger' From 1b6fc95d7721d4d1cc0820c00eb68a6a30b80901 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Thu, 17 Jul 2014 13:25:25 +0100 Subject: [PATCH 18/58] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 278fc30f6..709320fc5 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -186,7 +186,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: error_saving: "Erro ao Guardar" saved: "Alterações Guardadas" password_mismatch: "As palavras-passe não coincidem." -# password_repeat: "Please repeat your password." + password_repeat: "Por favor repita a sua palavra-passe." job_profile: "Perfil de Emprego" job_profile_approved: "O seu perfil de emprego foi aprovado pelo CodeCombat. Os empregadores poderão vê-lo até que o defina como inativo ou não o tenha alterado à 4 semanas." job_profile_explanation: "Olá! Preencha isto e entraremos em contacto consigo sobre encontrar um emprego de desenvolvedor de software para si." @@ -327,7 +327,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # pass_screen_blurb: "Review each candidate's code before reaching out. One employer found that 5x as many of our devs passed their technical screen than hiring from Hacker News." # make_hiring_easier: "Make my hiring easier, please." what: "O que é o CodeCombat?" - what_blurb: "O CodeCombat é um jogo de programação, no navegador e multijogador. Os jogadores escrevem código para controlar as forças deles em batalha contra outros desenvolvedores. Nós suportamos JavaScript, Python, Lua, Clojure, CoffeeScript e Io." + what_blurb: "O CodeCombat é um jogo de programação, no navegador e multijogador. Os jogadores escrevem código para controlar as forças deles em batalha contra outros desenvolvedores. Os nossos jogadores têm experiência com todos os conceitos tecnológicos principais." cost: "Quanto é que cobramos?" cost_blurb: "Cobramos 15% do salário do primeiro ano e ofereçemos uma garantia de devolução de 100% do dinheiro durante 90 dias. Não cobramos por candidatos que já estejam a ser ativamente entrevistados na sua companhia." candidate_name: "Nome" From 991ef61d6220da3e8eabbf7c8f872f9d9ed5b6e4 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Thu, 17 Jul 2014 13:44:14 +0100 Subject: [PATCH 19/58] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 709320fc5..155289e42 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -503,13 +503,13 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: pick_a_terrain: "Escolha Um Terreno" small: "Pequeno" grassy: "Com Relva" -# fork_title: "Fork New Version" -# fork_creating: "Creating Fork..." + fork_title: "Bifurcar Nova Versão" + fork_creating: "A Criar Bifurcação..." # randomize: "Randomize" -# more: "More" -# wiki: "Wiki" -# live_chat: "Live Chat" - level_some_options: "Algumas opções?" + more: "Mais" + wiki: "Wiki" + live_chat: "Chat Ao Vivo" + level_some_options: "Algumas Opções?" level_tab_thangs: "Thangs" level_tab_scripts: "Scripts" level_tab_settings: "Configurações" @@ -522,19 +522,19 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # delete: "Delete" # duplicate: "Duplicate" level_settings_title: "Configurações" - level_component_tab_title: "Componentes atuais" - level_component_btn_new: "Cria um novo Componente" - level_systems_tab_title: "Sistemas atuais" - level_systems_btn_new: "Cria um novo Sistema" - level_systems_btn_add: "Adiciona um Sistema" + level_component_tab_title: "Componentes Atuais" + level_component_btn_new: "Criar Novo Componente" + level_systems_tab_title: "Sistemas Atuais" + level_systems_btn_new: "Cria Novo Sistema" + level_systems_btn_add: "Adicionar Sistema" level_components_title: "Voltar para Todos os Thangs" level_components_type: "Tipo" level_component_edit_title: "Editar Componente" # level_component_config_schema: "Config Schema" level_component_settings: "Configurações" level_system_edit_title: "Editar Sistema" - create_system_title: "Criar novo Sistema" - new_component_title: "Criar novo Componente" + create_system_title: "Criar Novo Sistema" + new_component_title: "Criar Novo Componente" new_component_field_system: "Sistema" new_article_title: "Criar um Novo Artigo" new_thang_title: "Criar um Novo Tipo de Thang" @@ -559,20 +559,20 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: name: "Nome" body: "Corpo" version: "Versão" - commit_msg: "Mensagem de Commit" -# version_history: "Version History" - version_history_for: "Histórico de versões por: " + commit_msg: "Enviar Mensagem" + version_history: "Histórico de Versões" + version_history_for: "Histórico de Versões para: " result: "Resultado" results: "Resultados" description: "Descrição" or: "ou" -# subject: "Subject" + subject: "Assunto" email: "E-mail" password: "Palavra-passe" message: "Mensagem" code: "Código" ladder: "Classificação" - when: "quando" + when: "Quando" opponent: "Adversário" rank: "Classificação" score: "Resultado" From 17a4a689e4a73340a2453e1174ef05ba58200e2d Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Thu, 17 Jul 2014 14:18:29 +0100 Subject: [PATCH 20/58] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 46 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 155289e42..ec504f6db 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -768,17 +768,17 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: ambassador_title_description: "(Suporte)" ladder: - please_login: "Por favor, faz log in antes de jogar um jogo para o campeonato." - my_matches: "Os meus jogos" + please_login: "Por favor inicie sessão antes de jogar um jogo do campeonato." + my_matches: "Os Meus Jogos" simulate: "Simular" - simulation_explanation: "Simulando jogos podes fazer com que o teu jogo seja classificado mais rapidamente!" + simulation_explanation: "Ao simular jogos pode ter o seu jogo classificado mais rapidamente!" simulate_games: "Simular Jogos!" # simulate_all: "RESET AND SIMULATE GAMES" -# games_simulated_by: "Games simulated by you:" -# games_simulated_for: "Games simulated for you:" -# games_simulated: "Games simulated" -# games_played: "Games played" -# ratio: "Ratio" + games_simulated_by: "Jogos simulados por si:" + games_simulated_for: "Jogos simulados para si:" + games_simulated: "Jogos simulados" + games_played: "Jogos jogados" + ratio: "Rácio" leaderboard: "Tabela de Classificação" battle_as: "Lutar como " summary_your: "As tuas " @@ -868,29 +868,29 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # server_error: "Server error." # unknown: "Unknown error." -# resources: -# your_sessions: "Your Sessions" -# level: "Level" + resources: + your_sessions: "As Suas Sessões" + level: "Nível" # social_network_apis: "Social Network APIs" # facebook_status: "Facebook Status" -# facebook_friends: "Facebook Friends" + facebook_friends: "Amigos do Facebook" # facebook_friend_sessions: "Facebook Friend Sessions" -# gplus_friends: "G+ Friends" + gplus_friends: "Amigos do Google+" # gplus_friend_sessions: "G+ Friend Sessions" -# leaderboard: "Leaderboard" + leaderboard: "Tabela de Classificação" # user_schema: "User Schema" # user_profile: "User Profile" # patches: "Patches" # patched_model: "Source Document" # model: "Model" -# system: "System" -# component: "Component" -# components: "Components" -# thang: "Thang" -# thangs: "Thangs" -# level_session: "Your Session" -# opponent_session: "Opponent Session" -# article: "Article" + system: "Sistema" + component: "Componente" + components: "Componentes" + thang: "Thang" + thangs: "Thangs" + level_session: "A Sua Sessão" + opponent_session: "Sessão Do Oponente" + article: "Artigo" # user_names: "User Names" # thang_names: "Thang Names" # files: "Files" @@ -900,7 +900,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # sprite_sheet: "Sprite Sheet" # candidate_sessions: "Candidate Sessions" # user_remark: "User Remark" -# versions: "Versions" + versions: "Versões" # delta: # added: "Added" From 337de506dd9786dc7b0d65a29b4d98e4fcc9ca9d Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Thu, 17 Jul 2014 07:15:14 -0700 Subject: [PATCH 21/58] Removed mail task from server mapping --- server/commons/mapping.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/server/commons/mapping.coffee b/server/commons/mapping.coffee index faa0ef551..69f8abfc0 100644 --- a/server/commons/mapping.coffee +++ b/server/commons/mapping.coffee @@ -9,7 +9,6 @@ module.exports.handlers = 'thang_type': 'levels/thangs/thang_type_handler' 'user': 'users/user_handler' 'user_remark': 'users/remarks/user_remark_handler' - 'mail_task': 'mail/tasks/mail_task_handler' 'mail_sent': 'mail/sent/mail_sent_handler' 'achievement': 'achievements/achievement_handler' 'earned_achievement': 'achievements/earned_achievement_handler' From 58a80f2512e9d32bd83659985faf16d3f1191e8f Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Thu, 17 Jul 2014 07:17:25 -0700 Subject: [PATCH 22/58] Removed old comment --- server/routes/mail.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 4098402b0..0f648178e 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -187,7 +187,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> context = email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE" recipient: - address: "team@codecombat.com" #Change to whatever email address is necessary + address: "team@codecombat.com" name: "The CodeCombat Team" email_data: new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}" From c145f8088c6c1f64189413de990e9287728af817 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:12 -0700 Subject: [PATCH 23/58] Fixed the avatar endpoint handling when the user object DNE. --- server/users/user_handler.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 020d30f20..275807ad7 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -219,6 +219,7 @@ UserHandler = class UserHandler extends Handler avatar: (req, res, id) -> @modelClass.findById(id).exec (err, document) => return @sendDatabaseError(res, err) if err + return @sendNotFoundError(res) unless document photoURL = document?.get('photoURL') if photoURL photoURL = "/file/#{photoURL}" From 7454c051f0f228a2bd4705b64b19f2e5c4b94b8b Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:21 -0700 Subject: [PATCH 24/58] Added a job profile view demo. --- .../views/user/JobProfileView.demo.coffee | 627 ++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 test/demo/views/user/JobProfileView.demo.coffee diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee new file mode 100644 index 000000000..71e26022d --- /dev/null +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -0,0 +1,627 @@ +ProfileView = require 'views/account/profile_view' + +responses = + '/db/user/joe/nameToID':'512ef4805a67a8c507000001' + '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"} + '/db/user/5162fab9c92b4c751e000274/track/view_candidate': {"result":"success"} + '/db/user/512ef4805a67a8c507000001/remark': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"} + '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ + { + "_id": "53179b49b483edfcdb7ef13e", + "code": { + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + }, + "programmable-tharin": { + "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;" + }, + "programmable-librarian": { + "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});" + }, + "nazgareth": { + "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + }, + "ironjaw": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n if(!this.getCooldown('jump')) {\n this.jumpTo(enemy.pos);\n this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 10, y: 30});\n}" + }, + "poult": { + "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + } + }, + "submitted": false, + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submittedCodeLanguage": "javascript", + "playtime": 33, + "codeLanguage": "javascript" + }, + { + "_id": "53336ee91506ed33756f73e5", + "code": { + "tharin": { + "chooseAction": "this.say(\"Say, who's in charge around here?\"); // Should fill in some default source" + }, + "programmable-coin": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\n this.teleportRandom();\n//}o" + }, + "wizard-purple": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n this.build('coin');\n// console.log(\"build coin\");\n//}" + } + }, + "levelID": "gold-rush", + "levelName": "Resource gathering multiplayer", + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "52ae32cbef42c52f1300000d", + "levelID": "gridmancer", + "levelName": "Gridmancer", + "code": { + "captain-anya": { + "plan": "function largestRectangle(grid, bottomY, leftX, width, height) {\n var coveredRows = [];\n var shortestCoveredRow = width - leftX;\n var done = false;\n for(var y = bottomY; !done && y < height; ++y) {\n var coveredRow = 0, done2 = false;\n for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n if(!grid[y][x].length)\n ++coveredRow;\n else\n done2 = true;\n }\n if(!coveredRow)\n done = true;\n else {\n coveredRows.push(coveredRow);\n shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n }\n }\n var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n var rowLength = coveredRows[rowIndex];\n if(!shortestRow)\n shortestRow = rowLength;\n area = rowLength * (rowIndex + 1);\n if(area > maxArea) {\n maxAreaRows = rowIndex +1;\n maxAreaRowLength = shortestRow;\n maxArea = area;\n }\n shortestRow = Math.min(rowLength, shortestRow);\n }\n return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n this.addRect(rect.x, rect.y, rect.width, rect.height);\n //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \", \" + grid.length + \", \" + x + \", \" + y);\n this.wait(0.1);\n for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n grid[y2][x2] = [rect];\n }\n }\n }\n }\n}\n" + }, + "thoktar": { + "plan": "var grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar canOverlap = false;\nvar i, rect;\nthis.doWait = function() {\n this.wait(1);\n this.say(\"hi\");\n this.wait(1);\n this.say(\"there\");\n this.wait(1);\n};\nthis.doWait();\nfor (var y = 0; y + tileSize < grid.length; y += tileSize) {\n for (var x = 0; x + tileSize < grid[0].length;) {\n // check if wall\n var occupied = grid[y][x].length > 0;\n // check if already covered by another rect\n if (!occupied) {\n for (i = 0; i < this.spawnedRectangles.length; ++i) {\n rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x && x < rect.pos.x + rect.width / 2 && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n occupied = true;\n }\n }\n if (!occupied) {\n var x2 = x,\n y2 = y;\n // expand to the right until we find a wall\n while (x2 < grid[0].length - 1 && grid[y][x2 + tileSize].length === 0)\n x2 += tileSize;\n // expand current horizontal rectangle vertically until wall\n var ok = true;\n while (y2 + tileSize < grid.length && ok) {\n var yt = y2 + tileSize;\n // check each cell\n for (var xt = x; xt <= x2; xt += tileSize) {\n if (grid[yt][xt].length > 0) {\n ok = false;\n }\n }\n if (!canOverlap) {\n // check if tile to the left is non-wall\n if (x > 0 && grid[yt][x - tileSize].length === 0) {\n // check if already has a rect\n var covered = false;\n for (i = 0; i < this.spawnedRectangles.length; ++i) {\n rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x - tileSize &&\n x - tileSize < rect.pos.x + rect.width / 2 &&\n rect.pos.y - rect.height / 2 < yt &&\n rect.pos.y + rect.height / 2 > yt)\n covered = true;\n }\n // if no wall and no rect leave open to avoid future overlap\n if (!covered)\n ok = false;\n }\n }\n // advance\n if (ok)\n y2 += tileSize;\n }\n // done\n this.addRect(x + tileSize / 2 + (x2 - x) / 2, y + tileSize / 2 + (y2 - y) / 2,\n tileSize + (x2 - x), tileSize + (y2 - y));\n x = x2 + tileSize;\n this.wait();\n } else {\n x += tileSize;\n }\n }\n}\n\n/*\nvar tileSize = 4;\n\nvar grid;\nvar occupied, occupiedArray;\nvar numTilesX, numTilesY;\nvar x, y, y2, x2, x3, y3, lastX, lastY;\nvar width, height;\n\ngrid = this.getNavGrid().grid;\noccupiedArray = [];\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n occupiedArray[y] = [];\n for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n {\n occupiedArray[y][x] = (grid[y][x].length > 0);\n }\n}\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n {\n if(!occupiedArray[y][x])\n {\n //Check width of rectangle\n lastX = x;\n y2 = y;\n numTilesX = 0;\n var okay = true;\n for(x2 = x; okay &&x2 + tileSize < grid[y].length; x2 += tileSize)\n {\n if(occupiedArray[y2][x2])\n {\n okay = false;\n //x2 = grid[y].length;\n }\n else\n {\n lastX = x2;\n numTilesX++;\n }\n }\n\n // Check height of rectangle\n lastY = y;\n x2 = x;\n numTilesY = 0;\n okay = true;\n for(y2 = y; okay && y2 + tileSize < grid.length; y2 += tileSize)\n {\n var okay2 = true;\n for(x3 = x; okay2 && x3 <= lastX; x3 += tileSize)\n {\n occupied = occupiedArray[y2][x3];\n if(occupied)\n {\n okay2 = false;\n //x3 = grid[y].length;\n }\n }\n if(occupied)\n {\n okay = false;\n //y2 = grid.length;\n }\n else\n {\n lastY = y2;\n numTilesY++;\n }\n }\n\n for(y3 = y; y3 <= lastY; y3 += tileSize) \n {\n for(x3 = x; x3 <= lastX; x3 += tileSize)\n {\n occupiedArray[y3][x3] = true;\n }\n }\n \n width = numTilesX * tileSize;\n height = numTilesY * tileSize;\n this.addRect( x + (width / 2), y + (height / 2), width, height);\n \n this.wait(); // Hover over the timeline to help debug!\n } \n }\n}\n*/\n\n\n/*\nvar todoGrid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar yGridSize = todoGrid.length;\nvar xGridSize = todoGrid[0].length;\nvar x, y;\n//store all tiles which actually need to be filled\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n todoGrid[y][x] = todoGrid[y][x].length === 0;\n }\n}\n\n//determine how many tiles to fill\nvar todoAnz = 0;\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n if(todoGrid[y][x]) {\n todoAnz++;\n }\n }\n}\n\n//fill all tiles from biggest to smallest rectangle possible\nwhile(todoAnz > 0) {\n var biggestLeftX, biggestLeftY, biggestRightX, biggestRightY, tmpX, tmpY;\n var bigRect = 0;\n for(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n if(todoGrid[y][x]) {\n var width = 1, height = 1;\n while(todoGrid[y][x + width * tileSize] && x + width * tileSize + tileSize < xGridSize) {\n width++;\n }\n var higher = true;\n while(higher) {\n for(tmpX = x; tmpX < x + tileSize * width; tmpX += tileSize)\n if(!todoGrid[y + height * tileSize][tmpX] || y + height * tileSize + tileSize >= yGridSize) higher = false;\n if(higher) height++;\n }\n if(width * height > bigRect) {\n bigRect = width * height;\n biggestLeftX = x;\n biggestLeftY = y;\n biggestRightX = x + width * tileSize;\n biggestRightY = y + height * tileSize;\n }\n }\n }\n}\nfor(tmpY = biggestLeftY; tmpY < biggestRightY; tmpY += tileSize)\n for(tmpX = biggestLeftX; tmpX < biggestRightX; tmpX += tileSize)\n todoGrid[tmpY][tmpX] = false;\n this.addRect( (biggestLeftX + biggestRightX) / 2,\n (biggestLeftY + biggestRightY) / 2,\n biggestRightX - biggestLeftX,\n biggestRightY - biggestLeftY );\n this.wait(0.2);\n todoAnz -= bigRect;\n // this.say(\"Found a \"+bigRect+\" tile Rectangle, \"+todoAnz+\" tile(s) left\");\n}\n// André\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n for(var x = 0; x + tileSize < grid[0].length; ) {\n\n var occupied = grid[y][x].length > 0;\n\n if (!occupied) {\n for (var i = 0; i < this.spawnedRectangles.length; ++i) {\n var rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x && x <= rect.pos.x + rect.width / 2 \n && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n occupied = true;\n }\n }\n\n if(!occupied) {\n var x2 = x, y2 = y;\n while (x2 < grid[0].length-1 && grid[y][x2+tileSize].length===0)\n x2 += tileSize;\n\n var ok = true;\n while (y2 + tileSize < grid.length && ok) {\n var yt = y2 + tileSize; \n for (var xt = x; xt <= x2; xt += tileSize) {\n if (grid[yt][xt].length > 0) {\n ok = false;\n }\n }\n if (x > 0 && grid[yt][x - tileSize].length === 0)\n ok = false;\n if (x2 < grid[0].length-tileSize && grid[yt][x2+tileSize].length === 0)\n ok = false;\n if (ok)\n y2 += tileSize; \n }\n\n\n this.addRect(x + tileSize / 2 + (x2-x)/2, y + tileSize / 2 + (y2-y)/2, tileSize + (x2-x), tileSize + (y2-y));\n x = x2 + tileSize;\n this.wait();\n } else {\n x += tileSize;\n }\n }\n}\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar isCounting;\nvar adyacentX;\nvar startPos;\n\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n isCounting = 0;\n adyacentX = 0;\n for(var x = 0; x + tileSize < grid[0].length; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n if(isCounting === 0)\n startPos = x;\n isCounting = 1;\n adyacentX++;\n // this.say(\"Pos(\"+x+\",\"+y+\") is occupied\");\n // this.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize);\n // this.wait(); // Hover over the timeline to help debug!\n }\n else {\n // this.say(\"Pos(\"+x+\",\"+y+\") is not occupied\");\n isCounting = 0;\n if(adyacentX > 0){\n // this.say(\"writing \" + adyacentX + \"width rectangle= \" + tileSize*adyacentX);\n this.addRect((startPos + x)/2,y+tileSize / 2,tileSize*adyacentX,tileSize);\n }\n adyacentX = 0;\n }\n }\n\n}\n\nthis.say(\"Finish!\");\n*/\n\n/*\nfunction largestRectangle(grid, bottomY, leftX, width, height) {\n var coveredRows = [];\n var shortestCoveredRow = width - leftX;\n var done = false;\n for(var y = bottomY; !done && y < height; ++y) {\n var coveredRow = 0, done2 = false;\n for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n if(!grid[y][x].length)\n ++coveredRow;\n else\n done2 = true;\n }\n if(!coveredRow)\n done = true;\n else {\n coveredRows.push(coveredRow);\n shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n }\n }\n var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n var rowLength = coveredRows[rowIndex];\n if(!shortestRow)\n shortestRow = rowLength;\n area = rowLength * (rowIndex + 1);\n if(area > maxArea) {\n maxAreaRows = rowIndex +1;\n maxAreaRowLength = shortestRow;\n maxArea = area;\n }\n shortestRow = Math.min(rowLength, shortestRow);\n }\n return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n this.addRect(rect.x, rect.y, rect.width, rect.height);\n //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \", \" + grid.length + \", \" + x + \", \" + y);\n this.wait(0.1);\n for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n grid[y2][x2] = [rect];\n }\n }\n }\n }\n}\n*/" + } + }, + "submitted": false, + "submittedCodeLanguage": "javascript", + "playtime": 302, + "codeLanguage": "javascript" + }, + { + "_id": "5334901f0a0f9b286f57382c", + "team": "humans", + "code": { + "coin-generator-9000": { + "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n// this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n this.build('gem');\nelse if (Math.random() < 0.25)\n this.build(buildOrder[this.built.length % buildOrder.length])\nelse if (Math.random() < 0.5)\n this.build('coin');\n\n\n\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\n\n//this.say(human.gold);\n\n//this.say(\"Humans: \" + human.gold + \", \" + \"Ogres: \" + ogre.gold);\n\nif(ogre.gold >= 150) {\n this.say(\"Ogres win!\");\n this.setGoalState(\"goldOgres\", \"success\");\n}\n\nelse if(human.gold >= 150) {\n this.say(\"Humans win!\");\n this.setGoalState(\"goldHumans\", \"success\");\n}" + }, + "programmable-coin": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\nif (typeof this.teleportOnce === 'undefined') {\n this.teleportRandom();\n this.teleportOnce = true;\n}\n//}" + }, + "tharin": { + "chooseAction": "var t = this;\nvar e = t.getNearestEnemy();\nvar vec = new Vector(0, 0);\n\nfunction item_worth(item) {\n return item.bountyGold/Math.pow(item.distance(e) - t.distance(item), 1.5);\n}\n\nvar items = this.getItems();\nfor (var i = 0; i < items.length; i++) {\n var item = items[i];\n var direction = Vector.normalize(Vector.subtract(item.pos, this.pos));\n var weighted_dir = Vector.multiply(direction, 1000 * item_worth(item));\n vec = Vector.add(vec, weighted_dir);\n}\n\nvar action = \"move\";\nif (typeof this.used_terrify == \"undefined\") {\n var enemy = this.getNearestEnemy();\n \n if (enemy.gold >= 140 || this.distance(enemy) <= 15) {\n action = \"terrify\";\n }\n}\n\nif (action == \"move\") {\n var best_item = null;\n var best_item_value = 0;\n for (var i = 0; i < items.length; i++) {\n var item = items[i];\n var direction = Vector.subtract(item.pos, this.pos);\n \n var angle = Math.acos(vec.dot(direction) / (vec.magnitude() * direction.magnitude()))\n if (angle < Math.PI / 16 || angle > Math.PI * (31/16)) {\n if (item_worth(item) > best_item_value) {\n best_item_value = item_worth(item);\n best_item = item;\n }\n }\n }\n \n if (best_item_value > 0.05) {\n this.move(best_item.pos);\n } else {\n this.say(\"Move to \" + Vector.add(this.pos, vec).x + \" \" + Vector.add(this.pos, vec).y);\n this.move(Vector.add(this.pos, vec));\n }\n} else if (action == \"terrify\") {\n //this.terrify();\n this.used_terrify = true;\n}\n/*\n\n// This code runs once per frame. Choose where to move to grab gold!\n// First player to 150 gold wins.\n\n// This is an example of grabbing the 0th coin from the items array.\nvar items = this.getItems();\nif (items[0]) {\n this.move(items[0].pos);\n} else {\n this.moveXY(18, 36);\n}\n\n\n// You can surely pick a better coin using the methods below.\n// Click on a coin to see its API.\n*/\n" + }, + "wizard-purple": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n this.build('coin');\n// console.log(\"build coin\");\n//}" + } + }, + "levelID": "gold-rush", + "levelName": "Gold Rush", + "totalScore": 39.33094538664242, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1158, + "codeLanguage": "javascript" + }, + { + "_id": "52dea9b77e486eeb97000001", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "code": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\n//var type = 'munchkin';\nvar type = 'thrower';\nif(this.built.length % 3 === 0 && this.buildables.shaman.goldCost <= this.gold) \n type = 'shaman';\n// else if(this.built.length % 2 === 1 && this.buildables.thrower.goldCost <= this.gold)\n// type = 'thrower';\n\nif(this.gold >= this.buildables[type].goldCost) {\n //this.say('Unit #' + this.built.length + ' will be a ' + type);\n this.build(type);\n}", + "programmable-soldier": { + "chooseAction": "var i;\nif(typeof this.incoming !== 'undefined') {\n for(i = 0; i < this.incoming.length; ++i) {\n var shell = this.incoming[i];\n var t = shell.time - this.now();\n if(t < 0 || t > 1.5) continue;\n if(this.distance(shell.target) > 15) continue;\n var away = Vector.subtract(this.pos, shell.target);\n away = Vector.normalize(away);\n away = Vector.multiply(away, 15);\n away = Vector.add(this.pos, away);\n this.move(away);\n return;\n }\n}\n\nvar friends = this.getFriends();\nvar friend;\nfor(i = 0; i < friends.length; ++i) {\n friend = friends[i];\n if(friend.type !== 'arrow-tower') continue;\n if(friend.health < 15 && this.distance(friend) < 10) {\n this.attack(friend);\n return;\n }\n}\n\n\nvar enemy = this.getNearestEnemy();\nif(this.now() > 70) {\n if(enemy)\n this.attack(enemy);\n else\n this.move({x: 70, y: 70});\n return;\n}\n\nif(enemy && this.distance(enemy) < 40 && enemy.type != \"beam-tower\") {\n if(enemy.type === \"burl\" && (enemy.pos.x > 45 || enemy.pos.y > 45))\n this.say(\"Come at me, burl!\");\n else {\n this.attack(enemy);\n return;\n }\n}\nvar nearestArtillery = null;\nvar nearestArtilleryDistance = Infinity;\nfor(i = 0; i < friends.length; ++i) {\n friend = friends[i];\n if(friend.type !== \"artillery\") continue;\n var d = this.distance(friend);\n if(d < nearestArtilleryDistance) {\n nearestArtilleryDistance = d;\n nearestArtillery = friend;\n }\n}\nif(nearestArtillery && this.now() < 75) {\n var ahead = Vector.add(nearestArtillery.pos, {x: 2, y: 2});\n this.move(ahead);\n return;\n}\n\nif(friends.length > 12 || this.now() > 75) {\n if(enemy && enemy.type === 'beam-tower')\n this.attack(enemy);\n else\n this.move({x: 70, y: 70});\n}\nelse if(this.maxEnemies) {\n var besieged = null;\n var besiegedCount = 0;\n for(var tower in this.maxEnemies) {\n if(this.maxEnemies[tower] > besiegedCount) {\n besiegedCount = this.maxEnemies[tower];\n besieged = tower;\n }\n }\n if(besieged === \"W Arrow Tower\")\n this.move({x: 8, y: 32});\n else\n this.move({x: 32, y: 8});\n}\nelse if(this.buildIndex % 4)\n this.move({x: 8, y: 32});\nelse\n this.move({x: 32, y: 8});\n//testtesttest\n\n\n\n", + "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.\nif(message === \"Incoming!\") {\n if(typeof this.incoming === 'undefined') \n this.incoming = [];\n this.incoming.push(data);\n}\nelse if(data && data.enemies) {\n if(typeof this.maxEnemies === 'undefined') this.maxEnemies = {};\n this.maxEnemies[speaker.pos] = Math.max(this.maxEnemies[speaker.pos], data.enemies);\n}" + }, + "kim": { + "chooseAction": "var enemies = this.getEnemies();\nif(enemies.length)\n this.attack(enemies[0]);\nelse\n this.move({x: 71, y: 68});\n\n" + }, + "house-3": { + "chooseAction": "this.build(this.buildables.archer);\n" + }, + "human-base": { + "chooseAction": "/*if(this.built.length == 9)\n this.build('artillery');\nelse if(this.built.length == 11 && this.built[9].health > 0)\n this.build('soldier');\nelse**/ if(this.built.length === 0 || this.built.length === 1)\n this.build('archer');\nelse if((this.built.length % 6) === 5 && this.built.length != 5)\n this.build('artillery');\nelse if((this.built.length % 3) === 2)\n this.build('soldier');\nelse\n this.build('archer');\n\n\n", + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "programmable-archer": { + "chooseAction": "var items; \nif(this.buildIndex === 0) {\n items = this.getItems();\n if(items.length >= 3 && this.pos.y < 58) {\n this.move({x: 12, y: 59});\n return;\n }\n else if(items.length) {\n this.move(items[0].pos);\n return;\n }\n} \nif(this.buildIndex === 1 && !this.scouted) {\n items = this.getItems();\n if(this.pos.x > 74)\n this.scouted = true;\n else {\n this.move({x: 75, y: 8});\n return;\n }\n}\n\nvar i, d;\nif(typeof this.incoming !== 'undefined') {\n for(i = 0; i < this.incoming.length; ++i) {\n var shell = this.incoming[i];\n var t = shell.time - this.now();\n if(t < 0 || t > 1.5) continue;\n if(this.distance(shell.target) > 15) continue;\n var away = Vector.subtract(this.pos, shell.target);\n away = Vector.normalize(away);\n away = Vector.multiply(away, 15);\n away = Vector.add(this.pos, away);\n this.move(away);\n return;\n }\n}\n\nvar enemies = this.getEnemies();\nvar enemy;\nfor(i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'shaman' && this.distance(enemy) < 35) {\n var tick = Math.round(this.now() * 10);\n if(this.buildIndex < 2 && this.distance(enemy) < 30 && tick % 2)\n this.move({x: this.pos.x + 5 * Math.random(), y: Math.random() * 130});\n else\n this.attack(enemy);\n return;\n }\n if(enemy.type === 'burl' && this.distance(enemy) < 35 && enemy.health < 25) {\n this.attack(enemy);\n return;\n }\n}\n\nenemy = this.getNearestEnemy();\nif(this.now() > 70) {\n if(enemy)\n this.attack(enemy);\n else\n this.move({x: 70, y: 70});\n return;\n}\n\nif(enemy && (enemy.type != \"beam-tower\" || enemy.health < 60)) {\n if(this.distance({x: 5, y: 5}) > 10) {\n if(enemy.type === 'burl' || enemy.type === 'munchkin') {\n d = this.distance(enemy);\n if(d < 10 && this.pos.x > 32) {\n this.move({x: 28, y: 4});\n return;\n }\n else if(d < 10 && this.pos.y > 32) {\n this.move({x: 4, y: 28});\n return;\n }\n else if(d < 10 && this.pos.y < enemy.pos.y + 2 && this.pos.y > 3) {\n this.move(Vector.subtract(this.pos, {x: 2, y: 5}));\n return;\n }\n else if(d < 10 && this.pos.x < enemy.pos.x + 2 && this.pos.x > 3) {\n if(this.pos.y < 8)\n this.move({x: 5, y: 9});\n else\n this.move(Vector.subtract(this.pos, {x: 5, y: 2}));\n return;\n }\n }\n }\n if(this.distance(enemy) < 50) {\n this.attack(enemy);\n return;\n }\n}\n\nvar nearestArtillery = null;\nvar nearestArtilleryDistance = Infinity;\nvar friends = this.getFriends();\nvar friend;\nfor(i = 0; i < friends.length; ++i) {\n friend = friends[i];\n if(friend.type !== \"artillery\") continue;\n d = this.distance(friend);\n if(d < nearestArtilleryDistance) {\n nearestArtilleryDistance = d;\n nearestArtillery = friend;\n }\n}\nif(nearestArtillery && this.now() < 75) {\n var behind = Vector.subtract(nearestArtillery.pos, {x: 5, y: 5});\n this.move(behind);\n return;\n}\n\nif(friends.length > 12 || this.now() > 75) {\n if(enemy && enemy.type === 'beam-tower')\n this.attack(enemy);\n else\n this.move({x: 70, y: 70});\n}\nelse if(this.maxEnemies) {\n var besieged = null;\n var besiegedCount = 0;\n for(var tower in this.maxEnemies) {\n if(this.maxEnemies[tower] > besiegedCount) {\n besiegedCount = this.maxEnemies[tower];\n besieged = tower;\n }\n }\n if(besieged === \"W Arrow Tower\")\n this.move({x: 4, y: 28});\n else\n this.move({x: 28, y: 4});\n}\nelse if(this.buildIndex % 4)\n this.move({x: 28, y: 4});\nelse\n this.move({x: 4, y: 28});", + "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.\nif(message === \"Incoming!\") {\n if(typeof this.incoming === 'undefined') \n this.incoming = [];\n this.incoming.push(data);\n}\nelse if(data && data.enemies) {\n if(typeof this.maxEnemies === 'undefined') this.maxEnemies = {};\n this.maxEnemies[speaker.id] = Math.max(this.maxEnemies[speaker.pos], data.enemies);\n}" + }, + "programmable-artillery": { + "chooseAction": "var enemies = this.getEnemies();\nvar furthestAttackableEnemy = null;\nvar furthestAttackableDistance = 0.000;\nvar i; \nvar desperation = 0;\nfor(i = 0; i < enemies.length; ++i){\n var enemy = enemies[i];\n var distance = this.distance(enemy);\n if(this.pos.x < 40 && this.pos.y < 40 && distance < 10)\n ++desperation;\n if(distance > this.attackRange - desperation * 2) continue;\n var it = distance > furthestAttackableDistance && (enemy.type != 'burl' || enemies.length <= 2);\n if(it) {\n furthestAttackableEnemy = enemy;\n furthestAttackableDistance = distance;\n }\n}\nif(desperation > 4)\n return this.attackXY(this.pos.x, this.pos.y);\n \nif(furthestAttackableEnemy) {\n var t = furthestAttackableEnemy.pos;\n var friends = this.getFriends();\n for(i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n if(friend.type !== 'base' && (friend.type !== 'arrow-tower' || friend.health < 50)) continue;\n if(t.distance(friend.pos) < 10 - desperation) {\n this.move({x: 10, y: 70});\n return; \n }\n else if(t.distance(this.pos) < 10 - desperation ) {\n this.move({x: 20, y: 20});\n return;\n } \n }\n this.attackXY(t.x, t.y);\n this.say(\"Incoming!\", {target: furthestAttackableEnemy.pos, time: this.now() + 3.4});\n}\nelse\n this.move({x: 70.0, y: 70.0});\n", + "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "e-beam-tower": { + "chooseAction": "var enemy = this.getNearestEnemy();\nif(enemy) {\n this.attack(enemy);\n}" + }, + "s-arrow-tower": { + "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemies = this.getEnemies();\nif(!enemies.length) return;\nvar nearest = null;\nvar weakest = null;\nvar nearestDistance = 9001;\nvar weakestHealth = enemies[0].health;\nvar nearbyCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n var enemy = enemies[i];\n var d = this.distance(enemy);\n if(d > this.attackRange) continue;\n ++nearbyCount;\n if(d < nearestDistance) {\n nearestDistance = d;\n nearest = enemy;\n }\n var h = enemy.health;\n if(enemy.type === 'shaman')\n h -= 9001;\n else if(enemy.type === 'burl' && enemy.health < 30)\n h -= 90019001;\n if(h < weakestHealth) {\n weakestHealth = h;\n weakest = enemy;\n }\n}\nif(weakest) {\n this.say(\"Eat it, weak \" + weakest.id + \"!\", {enemies: nearbyCount});\n this.attack(weakest);\n}\nelse if(nearest) {\n this.say(\"Come at me, \" + nearest.id + \"!\", {enemies: nearbyCount});\n this.attack(nearest);\n}\n" + }, + "programmable-shaman": { + "chooseAction": "var friends = this.getFriends();\nif (!this.first || !this.second)\n for (var i = 0; i < friends.length; i++) {\n var f = friends[i];\n if (f.buildIndex === 2 && !this.second) {\n this.castShrink(f);\n this.second = true;\n return;\n } else if (f.buildIndex === 1 && !this.first) {\n this.castShrink(f);\n this.first = true;\n return;\n }\n }", + "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}" + }, + "n-beam-tower": { + "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \"!\");\n this.attack(enemy);\n}" + }, + "programmable-thrower": { + "chooseAction": "var enemies = this.getEnemies();\nvar items = this.getItems();\nvar nearest = this.getNearestEnemy();\nif (items.length > 0) {\n var it = this.getItems()[(this.buildIndex) % items.length];\n if(this.now > 2) { \n it = this.getNearest(items);\n } else if ( this.now() < 1 && this.buildIndex < 3 ) {\n this.wait(0.1);\n return;\n }\n this.move(it.pos);\n return;\n}\nvar tower = null;\nvar archers = [];\nvar artilleries = [];\nfor (var i = 0; i < enemies.length; i++) {\n if(enemies[i].type == \"arrow-tower\" && enemies[i].health > 0) {\n tower = enemies[i]; \n }\n else if (enemies[i].type == \"burl\" && enemies[i].health < 200) {\n this.say(\"OH LOOK!\");\n this.attack(enemies[i]);\n return;\n } else if (enemies[i].type == \"artillery\") {\n artilleries.push(enemies[i]);\n } else if( enemies[i].type == \"archer\") {\n archers.push(enemies[i]); \n }\n}\nif( tower && tower.health < 50) {\n this.attack(tower);\n return;\n}\nif(artilleries.length > 0) {\n this.attack(this.getNearest(artilleries));\n return;\n}\nif(archers.length > 3) {\n this.attack(this.getNearest(archers));\n return;\n}\nif( tower ) {\n this.attack(tower);\n return;\n}\nif (nearest && nearest.type != \"burl\") {\n this.attack(nearest);\n return;\n}\nthis.move({\n x: 18,\n y: 18\n}); ", + "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}" + }, + "programmable-munchkin": { + "chooseAction": "var enemies = this.getEnemies();\nvar items = this.getItems();\nvar nearest = this.getNearestEnemy();\nif (items.length > 0) {\n var it = this.getItems()[(this.buildIndex) % items.length];\n if(this.now > 2) { \n it = this.getNearest(items);\n } else if ( this.now() < 1 && this.buildIndex < 3 ) {\n this.wait(0.1);\n return;\n }\n this.move(it.pos);\n return;\n}\nvar tower = null;\nvar archers = [];\nvar artilleries = [];\nvar base = null;\nfor (var i = 0; i < enemies.length; i++) {\n if(enemies[i].type == \"arrow-tower\" && enemies[i].health > 0) {\n tower = enemies[i]; \n }\n else if (enemies[i].type == \"burl\" && enemies[i].health < 200) {\n this.say(\"OH LOOK!\");\n this.attack(enemies[i]);\n return;\n } else if (enemies[i].type == \"artillery\") {\n artilleries.push(enemies[i]);\n } else if( enemies[i].type == \"archer\") {\n archers.push(enemies[i]); \n } else if (enemies[i].type == \"base\") {\n base = enemies[i];\n }\n}\nvar friends = this.getFriends();\nif( friends.length > 25 ) {\n this.say(\"NYAN\");\n if(base) {\n this.attack(base);\n return;\n } else {\n this.move({x:18,y:18});\n return;\n }\n}\n\nif( tower && tower.health < 50) {\n this.attack(tower);\n return;\n}\nif(artilleries.length > 0) {\n this.attack(this.getNearest(artilleries));\n return;\n}\nif(archers.length > 3) {\n this.attack(this.getNearest(archers));\n return;\n}\nif( tower ) {\n this.attack(tower);\n return;\n}\nif (nearest && nearest.type != \"burl\") {\n this.attack(nearest);\n return;\n}\nthis.move({\n x: 18,\n y: 18\n}); ", + "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}" + }, + "ogre-base": { + "chooseAction": "var type = 'munchkin';\nif(this.built.length%7===4 && this.now() > 20) {\n type = 'thrower';\n}if(this.built.length===0) {\n type = 'shaman';\n}\n\nthis.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);", + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}" + } + }, + "totalScore": 24.004311721082228, + "team": "humans", + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "535701331bfa9bba14b5e03d", + "team": "ogres", + "levelID": "greed", + "levelName": "Greed", + "code": { + "well": { + "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" + }, + "ogre-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array. \n// Destroy the enemy base within 120 seconds! \n// Check out the Guide at the top for more info.\n\nvar base = this;\n\nvar items = this.getItems();\nvar peons = this.getByType('peon');\n\nif(peons[0]) {\n var item = peons[0].getNearest(items);\n var index = items.indexOf(item);\n var index2 = _.indexOf(items, item);\n var index3 = items.indexOf(peons[0].getNearest(items));\n} \n\nvar friendCosts = {'munchkin': 10, 'ogre': 25, 'shaman': 40, 'fangrider': 160, 'brawler': 500};\nvar enemyCosts = {'soldier': 10, 'knight': 25, 'librarian': 40, 'griffin-rider': 60, 'captain': 100, 'peasant': -1};\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nvar ourArmyWorth = 0;\nvar theirArmyWorth = 0;\nfor(var friendIndex in friends)\n ourArmyWorth += friendCosts[friends[friendIndex].type] || 0;\n \nfor(var enemyIndex in enemies) {\n var enemy = enemies[enemyIndex];\n if(this.distance(enemy) > 32) continue;\n theirArmyWorth += (enemyCosts[enemies[enemyIndex].type] || 0 ) + 1;\n} \n \nvar type = 'peon';\nvar peons = this.getByType('peon');\nvar shamans = this.getByType('shaman', friends);\nvar nFighters = friends.length - shamans.length - peons.length;\nvar minionTypes = ['brawler', 'fangrider', 'shaman', 'ogre', 'munchkin'];\nif(this.built.length && theirArmyWorth > ourArmyWorth || this.now() > 120) {\n for(var minionIndex in minionTypes) {\n type = minionTypes[minionIndex];\n if(this.gold >= friendCosts[type] && (type != 'shaman' || nFighters))\n break;\n }\n}\nvar cost = friendCosts[type];\nif(type == 'peon') {\n cost = 50 + 10 * peons.length;\n if(peons.length >= 4)\n cost = 9001;\n}\nif (this.gold >= cost)\n this.build(type);\n \nvar getBestItem = function getBestItem(items, who, near, friends, enemies) {\n var bestValue = 0;\n var bestItem = null;\n for (var i = 0; i < items.length; ++i) {\n var item = items[i];\n var d = who.pos.distanceSquared(item.pos);\n d += who.pos.distanceSquared(near) / 5;\n var others = friends.concat(enemies); // hmm, less effective?\n //var others = friends;\n for (var j = 0; j < others.length; ++j) {\n if(others[j] == who) continue;\n var other = others[j];\n if(other.team != base.team) {\n d += 10;\n }\n else if(other.distance(item) < who.distance(item)) {\n d += 40;\n }\n }\n var value = item.bountyGold / d;\n if (value > bestValue) {\n bestItem = item;\n bestValue = value;\n }\n }\n return bestItem;\n};\n\nvar items = this.getItems();\nif(!items.length) return;\nvar ww = 85;\nvar hh = 70;\n//var hyp = Math.sqrt(ww * ww + hh * hh);\nvar centers = [\n [{x: 2 * ww / 4, y: 2 * hh / 4}],\n [{x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 2 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}, {x: 2 * ww / 4, y: 2 * hh / 4}]\n];\nvar peasants = this.getByType('peasant');\nfor (var i = 0; i < peons.length; ++i) {\n var minion = peons[i];\n var layoutIndex = Math.min(peons.length, centers.length) - 1;\n var layout = centers[layoutIndex];\n var center = layout[i % layout.length];\n var item = getBestItem(items, minion, center, peons, peasants);\n this.command(minion, 'move', item.pos);\n}\n\n//this.say(\"Your investors overpaid! \" + ourArmyWorth + \" vs. \" + theirArmyWorth);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': Mythically expensive super unit.\n// See the buildables documentation below for costs and the guide for more info.e" + }, + "human-base": { + "chooseAction": ".......;" + } + }, + "totalScore": 36.7927193835314, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 12893, + "codeLanguage": "javascript" + }, + { + "_id": "5356fc2e1bfa9bba14b5e039", + "team": "humans", + "levelID": "greed", + "levelName": "Greed", + "code": { + "human-base": { + "chooseAction": "var minionTypes = ['peasant', 'soldier', 'peasant', 'librarian', 'soldier', 'knight', 'librarian', 'soldier', 'knight', 'librarian', 'knight', 'knight', 'librarian', 'soldier', 'knight', 'librarian', 'knight'];\nvar type = minionTypes[this.built.length % minionTypes.length];\nif (this.gold >= this.buildables[type].goldCost)\n this.build(type);\n\n\n// this.x = _.where(this.getEnemies(), { 'type': 'base' });\n// var b = _.first(this.x, function(x) { return x !== base });\n// _.forOwn(b, function(num, key) {\n// delete b[key];\n// });\n\nif(!this.orderItems) this.orderItems = function orderItems(itemz, who, enemy) {\n var bestItems = [];\n for (var i = 0; i < itemz.length; ++i) {\n var item = itemz[i];\n if(enemy && (itemz.length > 15 && item.bountyGold <= 1)) continue; // Leave as traps\n var distance = who.pos.distance(item.pos);\n var enemyDistance = 0;\n if (enemy)\n enemyDistance = enemy.pos.distance(item.pos) / 2;\n var value = item.bountyGold / (distance + enemyDistance);\n bestItems.push({value: value, item: item});\n }\n bestItems.sort(function(a, b) { return b.value - a.value; });\n return bestItems;\n}; \n\nvar allItems = this.getItems();\nif(!allItems.length) return;\nvar peons = this.getByType('peon');\nvar peasants = this.getByType('peasant'); \nvar pozzz = this.pos;\n//this.say(\"There are \" + peasants.length + \" peasants and \" + peons.length + \" peons vying for \" + allItems.length + \" items!\");\nfor (var i = 0; i < peasants.length; ++i) {\n var peasant = peasants[i];\n var peon = peasant.getNearest(peons);\n var enemyItems = peon ? this.orderItems(allItems, peon) : [];\n if(!enemyItems.length) {\n var item = this.orderItems(allItems, peasant)[0];\n if(item)\n this.command(peasant, 'move', item.pos);\n continue;\n }\n var enemyItem = enemyItems[0].item;\n if (peon.pos.distance(enemyItem.pos) <= peasant.pos.distance(enemyItem.pos)) {\n var myItems = this.orderItems(allItems, peasant, peon);\n for(var j = 0; j < myItems.length; ++j) {\n var myItem = myItems[j].item;\n if(j == myItems.length - 1 || peasant.pos.distance(myItem.pos) < peon.pos.distance(myItem.pos)) {\n this.command(peasant, 'move', myItem.pos);\n break;\n }\n }\n }\n else {\n this.command(peasant, 'move', enemyItem.pos);\n this.say(\"Not so fast on that \" + enemyItem.id + ', ' + peon.id);\n }\n}\n\nfunction fooo() { \n \n \n}\n\n\n//};" + }, + "well": { + "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" + } + }, + "totalScore": 31.55513937890014, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 14758, + "codeLanguage": "javascript" + }, + { + "_id": "52fd5bf7e3c53130231726e1", + "team": "ogres", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": true, + "totalScore": 54.324748499022, + "code": { + "human-base": { + "hear": "...", + "chooseAction": "..." + }, + "programmable-archer": { + "hear": "...", + "chooseAction": "..." + }, + "s-arrow-tower": { + "chooseAction": "..." + }, + "programmable-soldier": { + "hear": "...", + "chooseAction": "..." + }, + "programmable-artillery": { + "hear": "...", + "chooseAction": "..." + }, + "programmable-shaman": { + "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n this.castShrink(this.shouldShrink.pop());\n return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n this.castSlow(enemy);\n return;\n }\n else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n this.castShrink(enemy);\n return;\n }\n}\nfor (i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if (this.distance(enemy) > 30) continue;\n if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n this.castShrink(enemy);\n return;\n }\n if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n return;\n }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n this.attack(enemy);\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}\n", + "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n if(!this.shouldShrink)\n this.shouldShrink = [];\n this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here." + }, + "n-beam-tower": { + "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \"!\");\n this.attack(enemy);\n}" + }, + "programmable-thrower": { + "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n\n this.move({x: 10, y: 10});\n}\n\n", + "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "programmable-munchkin": { + "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n items = this.getItems();\n if(items.length) {\n this.move(items[0].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nif(this.buildIndex === 2) {\n items = this.getItems();\n if(items.length) {\n this.move(items[items.length - 1].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n var d = this.distance(enemy);\n if(enemy.type == 'soldier' && enemy.health > 15) continue;\n if(enemy.type == 'burl' && enemy.health > 30) continue;\n if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n if(d < nearestJuicyTargetDistance) {\n nearestJuicyTarget = enemy;\n nearestJuicyTargetDistance = d;\n }\n}\nif(nearestJuicyTargetDistance < 15) {\n this.attack(nearestJuicyTarget);\n return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}", + "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "ogre-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n type = 'shaman';\nelse if(this.built.length % 6 === 1)\n type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n", + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 107, + "codeLanguage": "javascript" + }, + { + "_id": "5317ad4909098828ed071f4d", + "team": "humans", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 38.19039674380126, + "code": { + "programmable-librarian": { + "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nif (this.canCast('slow', enemy)) {\n // Slow the enemy, or chase if out of range (30m).\n this.castSlow(enemy);\n if (this.distance(enemy) <= 50)\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}\nvar base = this.getFriends()[0];\nvar d = base.distance(enemy);\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n" + }, + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\nhero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + }, + "hushbaum": { + "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n if (!enemy.hasEffect('slow')) {\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 70, y: 30});\n}\n" + }, + "tharin": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n" + }, + "tharin-1": { + "chooseAction": "..." + }, + "programmable-tharin": { + "chooseAction": "/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n If they fully base race us, we actually do want to produce archers since they DPS faster\n The effective DPS on soldiers is better if they attack us\n but worse if they straight race us\n\n //not sure if this is good but...\n if they're attacking our base with a small number of units\n we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n} \nif (!this.getCooldown('warcry') && friends.length > 5) {\n this.warcry();\n} \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n this.shield();\n}\nelse {\n this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 9634, + "codeLanguage": "javascript" + }, + { + "_id": "53361c80948ad7a777a10d9c", + "team": "ogres", + "levelID": "gold-rush", + "levelName": "Gold Rush", + "code": { + "coin-generator-9000": { + "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n// this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n this.build('gem');\nelse if (Math.random() < 0.25)\n this.build(buildOrder[this.built.length % buildOrder.length]);\nelse if (Math.random() < 0.5)\n this.build('coin');\n\nif(this.finishedGame) return;\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\nif(ogre.gold >= 150) {\n this.say(\"Ogres win!\");\n this.setGoalState(\"goldOgres\", \"success\");\n this.finishedGame = true;\n}\nelse if(human.gold >= 150) {\n this.say(\"Humans win!\");\n this.setGoalState(\"goldHumans\", \"success\");\n this.finishedGame = true;\n}" + }, + "mak-fod": { + "chooseAction": "var items = this.getItems();\nvar enemy = this.getNearestEnemy();\n\nvar c = new Vector(60, 40);\n//this.say(Math.round(c.x) + \", \" + Math.round(c.y));\nvar bestItem = null;\nvar bestValue = 0;\nvar canJump = !this.getCooldown('jump');\nvar i, item, d1, d2, d3, value;\nfor (i = 0; i < items.length; ++i) {\n item = items[i];\n d1 = this.distance(item) * (canJump ? 0.5 : 1);\n d2 = c.distance(item.pos);\n value = item.bountyGold / (d1 + d2 / 5);\n if (value > bestValue) {\n bestItem = item;\n bestValue = value;\n }\n} \n\nMath.random(); Math.random(); Math.random();\nvar secondBestItem = null;\nvar secondBestValue = 0;\nfor (i = 0; i < items.length; ++i) {\n if (item == bestItem) continue;\n item = items[i];\n d1 = this.distance(item);\n d2 = c.distance(item.pos);\n d3 = item.pos.distance(bestItem);\n value = item.bountyGold / (d1 + d2 / 5 + d3);\n if (value > secondBestValue) {\n secondBestItem = item;\n secondBestValue = value;\n }\n}\n\nif (!canJump && secondBestItem && this.distance(secondBestItem) < this.distance(bestItem))\n bestItem = secondBestItem; // Pick it up on the way.\nif (bestItem) {\n if(canJump && this.distance(bestItem) > 30)\n this.jumpTo(bestItem);\n else\n this.move(bestItem.pos);\n}" + } + }, + "totalScore": 40.77678387026546, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1014, + "codeLanguage": "javascript" + }, + { + "_id": "531920069f44be00001a7aef", + "team": "ogres", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 26.50666470188054, + "code": { + "human-base": { + "chooseAction": "..." + }, + "programmable-tharin": { + "chooseAction": "..." + }, + "programmable-librarian": { + "chooseAction": "..." + }, + "ogre-base": { + "chooseAction": "if(!this.builtHero) {\n //var hero = 'ironjaw'; // An unstoppable, jumping melee hero.\n var hero = 'yugargen'; // A shrinking, growing, poisonous spellcaster.\n this.builtHero = this.build(hero);\n return;\n}\n\nvar enemies = this.getEnemies();\nvar buildOrder = null;\nvar nearest = null;\nvar nearestX = 0;\nvar enemy;\nvar inCommand = this.built[0].health <= 0 || this.built[0].action == 'move';\nvar hasHero = false;\nvar archerCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type == 'librarian') {\n buildOrder = ['thrower', 'munchkin'];\n this.say(\"Destroy \" + enemy.id, {target: enemy});\n hasHero = true;\n break;\n }\n if(enemy.type == 'knight') {\n buildOrder = ['thrower', 'thrower', 'thrower', 'thrower', 'munchkin', 'thrower', 'thrower'];\n if(enemy.action != 'shield' && (enemy.pos.x > 40 || enemy.health < 130)) {\n this.say(\"Slay \" + enemy.id, {target: enemy});\n hasHero = true;\n }\n }\n if(enemy.type == 'archer')\n ++archerCount;\n if(enemy.pos.x > nearestX && (enemy.type != 'knight' || enemy.action != 'shield')) {\n nearest = enemy;\n nearestX = enemy.pos.x;\n }\n}\nif(nearest && enemy != nearest && inCommand && hasHero) {\n this.say(\"I guess let's fight kill \" + nearest.id, {target: nearest});\n}\nif(!buildOrder)\n buildOrder = ['munchkin', 'thrower', 'munchkin'];\nif(archerCount > 1)\n buildOrder = ['munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\nthis.build(type);\n" + }, + "programmable-shaman": { + "chooseAction": "if(typeof this.minHealth === 'undefined')\n this.minHealth = 120;\nif(this.health < this.minHealth && this.canCast('grow', this)) {\n this.castGrow(this);\n this.minHealth = this.health;\n return;\n}\n\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy;\nvar hasHero = false;\nvar archerCount = 0;\nfor (var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'archer')\n ++archerCount;\n}\nfor (i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.pos.x < 11) continue;\n if(enemy.action === 'shield' || this.tharinShields) {\n this.tharinShields = true;\n break;\n }\n if(enemy.type == 'knight' || enemy.type == 'librarian') {\n hasHero = true;\n //var someDistance = enemy.distance(this);\n }\n /*\n if(this.now() < 2.2 && enemy.type == 'knight' && enemy.pos.x > 30 && this.canCast('grow', this) && !this.canCast('shrink', enemy)) {\n this.cast('grow', this);\n this.say(\"Slay him!\", {target: enemy});\n return;\n }\n */\n if(this.canCast('shrink', enemy) && (enemy.type == 'knight' || (enemy.type == 'librarian' && this.distance(enemy) < 45)) && enemy.action != 'move') {\n if(this.now() < 1)\n this.move({x: 66, y: 22});\n else\n this.castShrink(enemy);\n if(this.now() < 5 && enemy.pos.x < 32)\n this.say(\"Move to hiding!\", {targetPos: {x: 76, y: 39}});\n else\n this.say(\"Murder the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n return;\n }\n if(this.canCast('poison-cloud', enemy) && (enemy.type == 'knight' || enemy.type == 'librarian') && (enemy.pos.x > 31 || this.now() > 10)) {\n this.castPoisonCloud(enemy); \n if(this.now() < 5 && enemy.pos.x < 32)\n this.say(\"Move to hiding!\", {targetPos: {x: 76, y: 39}});\n else if(enemy.pos.x > 40 || enemy.health < 130)\n this.say(\"Murder the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n return;\n }\n}\n\nvar furthestFriend = null;\nvar furthestFriendX = 9001;\nvar friends = this.getFriends();\nfor (i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n if(friend.pos.x < furthestFriendX) {\n furthestFriend = friend;\n furthestFriendX = friend.pos.x;\n }\n}\n\nfor (i = 0; i < enemies.length; ++i) {\n if(hasHero && !this.tharinShields) continue;\n if(archerCount > 1) continue;\n enemy = enemies[i]; \n if(this.canCast('shrink', enemy) && enemy.type == 'soldier' && enemy.health < enemy.maxHealth && enemy.health > 25 && this.distance(enemy) < 50 && furthestFriendX - enemy.pos.x < 20) {\n this.castShrink(enemy);\n this.say(\"Slay the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n return;\n }\n}\n\nif(furthestFriend && furthestFriend.health < furthestFriend.maxHealth && furthestFriend.health > 15 && this.canCast('grow', furthestFriend) && furthestFriendX < 55) {\n this.castGrow(furthestFriend);\n return;\n}\nvar weakestArcher = null;\nfor (i = 0; i < enemies.length; ++i) {\n enemy = enemies[i]; \n if(enemy.type == 'archer' && this.distance(enemy) < 50 && (!weakestArcher || enemy.health < weakestArcher.health)) {\n this.attack(enemy);\n if(!hasHero)\n this.say('Lovingly kill ' + enemy.id, {target: enemy});\n return;\n }\n}\nif(this.now() < 1) {\n this.move({x: 66, y: 22});\n return;\n}\nenemy = this.getNearest(enemies);\nthis.attack(enemy);\n\n" + }, + "programmable-brawler": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif(!enemy) return;\n\n\n\nif(this.now() < 12.00) {\n //if(this.now() > 5 && this.now() < 8)\n // this.say(\"Move to\", {targetPos: {x: 76, y: 48}});\n //else if(this.now() < 5)\n this.say(\"Defend!\", {targetPos: {x: 60, y: 33}});\n //this.say(\"Defend!\");\n\n if(this.distance({x:enemy.pos.x, y:enemy.pos.y}) < 6)\n this.attack(enemy);\n else\n this.move({x: 65, y: 32});\n return;\n}\n\n\n\nthis.say(\"Attack!\");\nif(!this.getCooldown('stomp')) {\n this.say(\"BaaaDOOOSH!!!\");\n this.stomp();\n return;\n}\nif(!this.getCooldown('throw') && enemy.type != 'soldier' && this.pos.x < 48) {\n this.throw(enemy);\n return;\n}\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(this.distance(enemy) > 30) continue;\n if (enemy.type === 'librarian' || enemy.type === 'tharin' || enemy.type === 'archer') {\n if(!this.getCooldown('jump')) {\n var diff = Vector.subtract(enemy.pos, this.pos);\n diff = Vector.multiply(Vector.normalize(diff), 30);\n var to = Vector.add(this.pos, diff);\n this.jumpTo(to);\n this.say(\"Obliterate \" + enemy.id, {target: enemy});\n }\n else if(!this.getCooldown('stomp')) {\n this.say(\"BaDOOSH\");\n this.stomp();\n }\n else {\n this.attack(enemy);\n }\n return;\n }\n}\n\nenemy = this.getNearest(enemies);\nif (enemy && this.distance(enemy) < 20) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 1786, + "codeLanguage": "javascript" + } + ] + '': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"} + +employersResponse = [ + { + "_id": "52af5b805c813fc5b9000006", + "levelID": "gridmancer", + "levelName": "Gridmancer", + "code": { + "captain-anya": { + "plan": "// Fill the empty space with the minimum number of rectangles.\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar rects = {};\n\nfunction coordString(x, y) { return x+','+y; }\nfunction fourRectsHere(x, y) { return rects[coordString(x-tileSize,y)] && rects[coordString(x,y-tileSize)] && rects[coordString(x-tileSize,y-tileSize)] && rects[coordString(x,y)]; }\n\nfor(var y = 0; y < grid.length; y += tileSize) {\n for(var x = 0; x < grid[0].length; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n var xcord = x + tileSize / 2;\n var ycord = y + tileSize / 2;\n this.addRect(xcord, ycord, tileSize, tileSize);\n rects[coordString(xcord,ycord)] = true;\n var coord = coordString(xcord,ycord);\n // this.say(coord);\n if (fourRectsHere(xcord,ycord)) {\n delete rects[coordString(xcord,ycord)];\n delete rects[coordString(xcord-tileSize, ycord)];\n delete rects[coordString(xcord-tileSize, ycord-tileSize)];\n delete rects[coordString(xcord, ycord-tileSize)];\n this.removeRect(xcord, ycord);\n this.removeRect(xcord - tileSize, ycord);\n this.removeRect(xcord, ycord - tileSize);\n this.removeRect(xcord - tileSize, ycord - tileSize);\n this.addRect(x, y, tileSize*2, tileSize*2);\n }\n this.wait(0.1);\n }\n }\n}\n" + }, + "thoktar": { + "plan": "# Fill the empty space with the minimum number of rectangles.\n# (Rectangles should not overlap each other or walls.)\n# The grid size is 1 meter, but the smallest wall/floor tile is 4 meters.\n# Check the blue guide button at the top for more info.\n# Make sure to sign up on the home page to save your code.\n\ngrid = self.getNavGrid().grid\ntileSize = 4\nfor y in range(0,grid.length,tileSize):\n for x in range(0,grid[0].length,tileSize):\n occupied = grid[y][x].length > 0\n if not occupied:\n self.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize)\n self.wait() # Hover over the timeline to help debug!\n\n\n" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 138, + "codeLanguage": "python" + }, + { + "_id": "53026594cd9f9595b818d651", + "team": "me", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": false, + "code": { + "programmable-artillery": { + "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'munchkin') {\n targetEnemy = enemy;\n break;\n }\n}\n\nif(!targetEnemy)\n targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n this.move({x: 70, y: 70});", + "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "programmable-soldier": { + "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are low damage, high health melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n this.attack(enemy);\nelse {\n this.move({x: 70, y: 70});\n}", + "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "s-arrow-tower": { + "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \".\");\n this.attack(enemy);\n}" + }, + "programmable-archer": { + "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n this.attack(enemy);\n}\nelse\n this.move({x: 70, y: 70});", + "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n type = 'artillery';\nelse if(this.built.length % 3 === 1)\n type = 'archer';\n\n// if(this.gold >= this.buildables[type].goldCost) {\n //this.say('Unit #' + this.built.length + ' will be a ' + type);\n this.build(type);\n// }", + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "5317530cc269d400000543c7", + "submitted": false, + "code": { + "muul": { + "chooseAction": "..." + }, + "nazgareth": { + "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + }, + "ironjaw": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n if(!this.getCooldown('jump')) {\n this.jumpTo(enemy.pos);\n this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 10, y: 30});\n}" + }, + "programmable-shaman": { + "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + }, + "programmable-thrower": { + "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" + }, + "programmable-munchkin": { + "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" + }, + "ogre-base": { + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide at the top for more info.\n\nif(!this.builtHero) {\n // Choose your hero!\n // var heroType = 'brawler';\n var heroType = 'shaman';\n this.builtHero = this.build(heroType);\n return;\n}\n\nvar buildOrder = ['munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + }, + "poult": { + "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + }, + "aoliantak": { + "chooseAction": "..." + }, + "programmable-brawler": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n if(!this.getCooldown('jump')) {\n this.jumpTo(enemy.pos);\n this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 10, y: 30});\n}" + } + }, + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "5358429413f1278605f03ab8", + "team": "ogres", + "levelID": "greed", + "levelName": "Greed", + "code": { + "ogre-base": { + "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peon');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n var peon = peons[peonIndex];\n var item = peon.getNearest(items);\n if (item)\n base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n type = 'peon';\nelse\n type = 'ogre';\nif (base.gold >= base.buildables[type].goldCost)\n base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info." + }, + "well": { + "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" + } + }, + "totalScore": 16.724090931727677, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 3837, + "codeLanguage": "javascript" + }, + { + "_id": "53177f6da508f6e7b3463fef", + "team": "humans", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 11.782554190268042, + "code": { + "hushbaum-1": { + "chooseAction": "..." + }, + "librarian": { + "chooseAction": "..." + }, + "tharin-1": { + "chooseAction": "var friends = this.getFriends();\nvar nearest = this.getNearest(friends);\nif(this.distance(nearest) > 5) {\n this.move(nearest.pos);\n}\nelse {\n this.warcry();\n}" + }, + "hushbaum": { + "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n if (!enemy.hasEffect('slow')) {\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 70, y: 30});\n}\n" + }, + "anya": { + "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy)\n this.attack(enemy);" + }, + "tharin": { + "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n" + }, + "programmable-librarian": { + "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});" + }, + "programmable-tharin": { + "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;" + }, + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'archer', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 1, + "codeLanguage": "javascript" + }, + { + "_id": "5318b6aa7aeef7843bba3357", + "team": "ogres", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 34.28623946920249, + "code": { + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\nhero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar type;\nif (this.built.length > 50) {\n type = this.built.length & 1 ? 'archer' : 'soldier';\n} else {\n type = 'soldier';\n}\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + }, + "programmable-tharin": { + "chooseAction": "var enemies = this.getEnemies();\nvar target = enemies[0];\n\nif (this.now() < 0.2) {\n this.attack(target);\n this.say(\"attack\", {target: target});\n return;\n}\n\nthis.say(\"attack\", {target: target});\nthis.attack(target);\nif (this.pos.x > 40 && !this.getCooldown('terrify')) {\n this.terrify();\n return;\n} else if (!this.getCooldown('warcry')) {\n this.warcry();\n}\nthis.say(\"attack\", {target: target});" + }, + "programmable-librarian": { + "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});" + }, + "programmable-shaman": { + "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// and three spells: 'shrink', 'grow', and 'poison-cloud'.\n// Shrink: target has 2/3 health, 1.5x speed for 5s.\n// Grow: target has double health, half speed for 5s.\n// Once per match, she can cast poison cloud, which does\n// 5 poison dps for 10s to enemies in a 10m radius.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(this.canCast('shrink', enemy)) this.castShrink(enemy);\n// if(this.canCast('grow', friend)) this.castGrow(friend);\n//if(this.canCast('poison-cloud', enemy)) this.castPoisonCloud(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40}); " + }, + "programmable-brawler": { + "chooseAction": "// The Brawler is a huge melee hero with mighty mass.\n// this.throw() hurls an enemy behind him.\n// this.jumpTo() leaps to a target within 20m every 10s.\n// this.stomp() knocks everyone away, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(!this.getCooldown('jump')) this.jumpTo(enemy.pos);\n// if(!this.getCooldown('stomp')) return this.stomp();\n// if(!this.getCooldown('throw')) this.throw(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;" + }, + "ironjaw": { + "chooseAction": "// var enemies = this.getEnemies();\n// var enemy = this.getNearest(enemies);\n// if (enemy) {\n// if(!this.getCooldown('jump')) {\n// this.jumpTo(enemy.pos);\n// this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n// this.attack(enemy);\n// }\n// }\n// else {\n// this.move({x: 10, y: 30});\n// }" + }, + "nazgareth": { + "chooseAction": "// // Shamans are spellcasters with a weak magic attack\n// // plus two useful spells: 'regen' and 'shrink'.\n\n// var enemy = this.getNearestEnemy();\n// if (!enemy)\n// this.move({x: 10, y: 25});\n// else if (!enemy.hasEffect('shrink')) {\n// this.castShrink(enemy);\n// if(this.distance(enemy) <= 30)\n// this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n// this.attack(enemy);\n// }" + }, + "ogre-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// Choose your hero! You can only build one hero.\nvar hero;\n// hero = 'ironjaw'; // A leaping juggernaut hero, type 'brawler'.\nhero = 'yugargen'; // A devious spellcaster hero, type 'shaman'.\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Munchkins are weak melee units with 1.25s build cooldown.\n// Throwers are fragile, deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['munchkin', 'munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" + }, + "muul": { + "chooseAction": "..." + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "52fd11c8e5c2b9000060bd48", + "team": "ogres", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": true, + "totalScore": -10.697956636178176, + "code": { + "ogre-base": { + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\n// var type = 'munchkin';\n// if(this.built.length % 5 === 3)\n type = 'shaman';\n// else if(this.built.length % 3 === 1)\n// type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n" + }, + "programmable-munchkin": { + "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" + }, + "programmable-thrower": { + "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" + }, + "n-beam-tower": { + "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \"!\");\n this.attack(enemy);\n}" + }, + "programmable-shaman": { + "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "53570b7a1bfa9bba14b5e045", + "team": "humans", + "levelID": "greed", + "levelName": "Greed", + "code": { + "well": { + "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" + }, + "human-base": { + "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peasant');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n var peon = peons[peonIndex];\n var item = peon.getNearest(items);\n if (item)\n base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n type = 'peasant';\nelse\n type = 'soldier';\nif (base.gold >= base.buildables[type].goldCost)\n base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info." + } + }, + "submitted": true, + "totalScore": 29.46867296924995, + "submittedCodeLanguage": "javascript", + "playtime": 6295, + "codeLanguage": "javascript" + }, + { + "_id": "52fd11adae7dc8000099b788", + "team": "humans", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": true, + "totalScore": 14.50139221733582, + "code": { + "programmable-artillery": { + "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'munchkin') {\n targetEnemy = enemy;\n break;\n }\n}\n\nif(!targetEnemy)\n targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n this.move({x: 70, y: 70});", + "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "programmable-soldier": { + "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are basic, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n this.attack(enemy);\nelse {\n var targetPos = {x: 70, y: 70};\n if(this.now() < 10)\n targetPos = {x: 40, y: 40};\n this.move(targetPos);\n}", + "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "programmable-archer": { + "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nif(this.lastEnemy && !this.lastEnemy.dead) {\n this.attack(this.lastEnemy);\n return;\n}\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n this.attack(enemy);\n if(this.distance(enemy) < this.attackRange) {\n this.lastEnemy = enemy;\n }\n}\nelse\n this.move({x: 70, y: 70});", + "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "human-base": { + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n type = 'artillery';\nelse if(this.built.length % 3 === 1)\n type = 'archer';\n\n\nif(this.gold >= this.buildables[type].goldCost) {\n //this.say('Unit #' + this.built.length + ' will be a ' + type);\n this.build(type);\n}", + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + }, + "s-arrow-tower": { + "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \".\");\n this.attack(enemy);\n}" + } + }, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + } +] + +module.exports = -> + me.isAdmin = -> false + me.set('permissions', ['employer']) + v = new ProfileView({}, 'joe') + jasmine.Ajax.requests.mostRecent() + for url, responseBody of responses + requests = jasmine.Ajax.requests.filter(url) + if not requests.length + console.error "could not find response for <#{url}>", responses + continue + request = requests[0] + console.log 'responding for', url + request.response({status: 200, responseText: JSON.stringify(responseBody)}) +# v.$el = v.$el.find('.main-content-area') + v From 6f09e95d68802e8909e6d7df719b73009f554bfc Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:22:52 -0700 Subject: [PATCH 25/58] Removed background from job profile view. --- app/styles/base.sass | 10 +++++----- app/templates/base.jade | 2 +- app/views/account/profile_view.coffee | 6 ++++-- app/views/kinds/RootView.coffee | 7 +++++++ test/demo/views/user/JobProfileView.demo.coffee | 4 ---- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/styles/base.sass b/app/styles/base.sass index eae0d473b..49921064d 100644 --- a/app/styles/base.sass +++ b/app/styles/base.sass @@ -23,14 +23,14 @@ h1 h2 h3 h4 padding: 14px 12px 5px 12px @include box-sizing(border-box) -#outer-content-wrapper +#outer-content-wrapper.show-background background: #8cc63f url(/images/pages/base/repeat-tile.png) top center -#intermediate-content-wrapper - background: url(/images/pages/base/sky_repeater.png) repeat-x + #intermediate-content-wrapper + background: url(/images/pages/base/sky_repeater.png) repeat-x -#inner-content-wrapper - background: url(/images/pages/base/background_texture.png) top center no-repeat + #inner-content-wrapper + background: url(/images/pages/base/background_texture.png) top center no-repeat #front-summary-points-left width: 250px diff --git a/app/templates/base.jade b/app/templates/base.jade index 01a67687c..6c18d420c 100644 --- a/app/templates/base.jade +++ b/app/templates/base.jade @@ -49,7 +49,7 @@ body a.header-font(href='/community', data-i18n="nav.community") Community block outer_content - #outer-content-wrapper + #outer-content-wrapper(class=showBackground ? 'show-background' : '') #intermediate-content-wrapper #inner-content-wrapper .main-content-area diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee index 213b89a97..bccb1c7d0 100644 --- a/app/views/account/profile_view.coffee +++ b/app/views/account/profile_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/account/profile' User = require 'models/User' LevelSession = require 'models/LevelSession' @@ -25,9 +25,11 @@ adminContacts = [ {id: '52a57252a89409700d0000d9', name: 'Ignore'} ] -module.exports = class ProfileView extends View +module.exports = class ProfileView extends RootView id: 'profile-view' template: template + showBackground: false + subscriptions: 'linkedin-loaded': 'onLinkedInLoaded' diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee index aac5dc64f..858c9fb48 100644 --- a/app/views/kinds/RootView.coffee +++ b/app/views/kinds/RootView.coffee @@ -17,6 +17,8 @@ filterKeyboardEvents = (allowedEvents, func) -> return func(splat...) module.exports = class RootView extends CocoView + showBackground: true + events: 'click #logout-button': 'logoutAccount' 'change .language-dropdown': 'onLanguageChanged' @@ -112,6 +114,11 @@ module.exports = class RootView extends CocoView @renderScrollbar() #@$('.antiscroll-wrap').antiscroll() # not yet, buggy + getRenderData: -> + c = super() + c.showBackground = @showBackground + c + afterRender: -> super(arguments...) @chooseTab(location.hash.replace('#', '')) if location.hash diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee index 71e26022d..b48c4dbc7 100644 --- a/test/demo/views/user/JobProfileView.demo.coffee +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -3,8 +3,6 @@ ProfileView = require 'views/account/profile_view' responses = '/db/user/joe/nameToID':'512ef4805a67a8c507000001' '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"} - '/db/user/5162fab9c92b4c751e000274/track/view_candidate': {"result":"success"} - '/db/user/512ef4805a67a8c507000001/remark': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"} '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ { "_id": "53179b49b483edfcdb7ef13e", @@ -331,7 +329,6 @@ responses = "codeLanguage": "javascript" } ] - '': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"} employersResponse = [ { @@ -621,7 +618,6 @@ module.exports = -> console.error "could not find response for <#{url}>", responses continue request = requests[0] - console.log 'responding for', url request.response({status: 200, responseText: JSON.stringify(responseBody)}) # v.$el = v.$el.find('.main-content-area') v From e4d4c973dae3af3d24aea977569010961fd8c5ef Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Thu, 17 Jul 2014 09:28:34 -0700 Subject: [PATCH 26/58] Minor fixes to email system --- server/routes/mail.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 0f648178e..5569428f5 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -42,7 +42,7 @@ candidateUpdateProfileTask = -> lockDurationMs = 2 * 60 * 1000 currentDate = new Date() timeRanges = [] - for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']] timeRanges.push start: generateWeekOffset currentDate, weekPair[0] end: generateWeekOffset currentDate, weekPair[1] @@ -252,7 +252,7 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> if employer.emails?.employerNotes?.enabled is false - return sentEmailFilterCallback true + return cb true findParameters = "user": employer._id "mailTask": @mailTaskName From 590626d5f8ecebfceeb6e14f0ac22211e80a0180 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:30:27 -0700 Subject: [PATCH 27/58] Centered social link icons. --- app/styles/account/profile.sass | 3 +- .../views/user/JobProfileView.demo.coffee | 245 +++++++++++++++++- 2 files changed, 246 insertions(+), 2 deletions(-) diff --git a/app/styles/account/profile.sass b/app/styles/account/profile.sass index 05a06f6ee..a661ea611 100644 --- a/app/styles/account/profile.sass +++ b/app/styles/account/profile.sass @@ -127,13 +127,14 @@ text-align: center ul.links + text-align: center li.has-icon display: inline-block img margin: 0 0 10px 0 li.has-icon:not(:nth-child(5)) img - margin: 0 10px 10px 0 + margin: 0 5px 10px 5px #contact-candidate margin-top: 20px diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee index b48c4dbc7..2aabea003 100644 --- a/test/demo/views/user/JobProfileView.demo.coffee +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -2,7 +2,250 @@ ProfileView = require 'views/account/profile_view' responses = '/db/user/joe/nameToID':'512ef4805a67a8c507000001' - '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"} + + + '/db/user/512ef4805a67a8c507000001': { + "_id": "512ef4805a67a8c507000001", + "__v": 47, + "email": "livelily@gmail.com", + "emailSubscriptions": [ + "announcement", + "notification", + "developer", + "level_creator", + "tester", + "article_editor", + "translator", + "support" + ], + "facebookID": "4301215", + "firstName": "Nick", + "gender": "male", + "lastName": "Winter", + "name": "Nick!", + "photoURL": "db/user/512ef4805a67a8c507000001/nick_wizard.png", + "volume": 0, + "wizardColor1": 0.4, + "testGroupNumber": 217, + "mailChimp": { + "leid": "70264209", + "euid": "c4418e2abd", + "email": "livelily@gmail.com" + }, + "hourOfCode": true, + "hourOfCodeComplete": true, + "signedCLA": "Fri Jan 03 2014 14:40:18 GMT-0800 (PST)", + "wizard": { + "colorConfig": { + "boots": { + "lightness": 0.1647058823529412, + "saturation": 0.023809523809523805, + "hue": 0 + }, + "spell": { + "hue": 0.7490196078431373, + "saturation": 0.4106280193236715, + "lightness": 0.5941176470588235 + }, + "cloud": { + "lightness": 0.14, + "saturation": 1, + "hue": 0 + }, + "clothes": { + "lightness": 0.1411764705882353, + "saturation": 0, + "hue": 0 + }, + "trim": { + "hue": 0.5, + "saturation": 0.009900990099009936, + "lightness": 0.19803921568627453 + } + } + }, + "aceConfig": { + "liveCompletion": true, + "indentGuides": true, + "invisibles": true, + "keyBindings": "emacs", + "behaviors": true, + "language": "javascript" + }, + "lastLevel": "drink-me", + "gplusID": "110703832132860599877", + "jobProfile": { + "photoURL": "db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg", + "links": [ +# { +# "name": "Twitter", +# "link": "https://twitter.com/nwinter" +# }, +# { +# "name": "Facebook", +# "link": "https://www.facebook.com/nwinter" +# }, + { + "name": "LinkedIn", + "link": "https://www.linkedin.com/in/nwinter" + }, + { + "name": "Blog", + "link": "http://blog.nickwinter.net/" + }, + { + "name": "Personal Site", + "link": "http://www.nickwinter.net/" + }, + { + "name": "GitHub", + "link": "https://github.com/nwinter" + }, + { + "name": "G+", + "link": "https://plus.google.com/u/0/+NickWinter" + } + ], + "projects": [ + { + "name": "The Motivation Hacker", + "description": "I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.", + "picture": "db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg", + "link": "http://www.nickwinter.net/motivation-hacker" + }, + { + "name": "Quantified Mind", + "description": "Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.", + "picture": "db/user/512ef4805a67a8c507000001/screenshot.png", + "link": "http://www.quantified-mind.com/" + }, + { + "link": "https://github.com/nwinter/telepath-logger", + "name": "Telepath", + "description": "A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).", + "picture": "db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067" + } + ], + "education": [ + { + "school": "Oberlin College", + "degree": "BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS", + "duration": "Aug 2004 - May 2008", + "description": "Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it." + } + ], + "work": [ + { + "employer": "CodeCombat", + "role": "Cofounder", + "duration": "Jan 2013 - present", + "description": "Programming a programming game for learning programming to be a programming programmer of programmatic programs." + }, + { + "employer": "Skritter", + "role": "Cofounder", + "duration": "May 2008 - present", + "description": "I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email." + } + ], + "visa": "Authorized to work in the US", + "longDescription": "I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.", + "shortDescription": "Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.", + "experience": 6, + "skills": [ + "python", + "coffeescript", + "node", + "ios", + "objective-c", + "javascript", + "app-engine", + "mongodb", + "web dev", + "django", + "backbone", + "chinese", + "qs", + "writing" + ], + "country": "USA", + "city": "San Francisco", + "active": false, + "lookingFor": "Full-time", + "name": "Nick Winter", + "updated": "2014-07-12T01:48:42.980Z", + "jobTitle": "Mutant Code Gorilla" + }, + "jobProfileApproved": false, + "emails": { + "anyNotes": { + "enabled": true + }, + "generalNews": { + "enabled": true + }, + "archmageNews": { + "enabled": true + }, + "artisanNews": { + "enabled": true + }, + "adventurerNews": { + "enabled": true + }, + "scribeNews": { + "enabled": true + }, + "diplomatNews": { + "enabled": true + }, + "ambassadorNews": { + "enabled": true + } + }, + "activity": { + "viewed_by_employer": { + "last": "2014-06-19T20:21:43.747Z", + "count": 6, + "first": "2014-06-12T01:37:38.278Z" + }, + "view_candidate": { + "first": "2014-06-10T19:59:30.773Z", + "count": 661, + "last": "2014-07-11T02:14:40.131Z" + }, + "login": { + "first": "2014-06-10T21:55:08.968Z", + "count": 22, + "last": "2014-07-16T16:32:31.661Z" + }, + "contacted_by_employer": { + "first": "2014-06-19T20:24:51.870Z", + "count": 1, + "last": "2014-06-19T20:24:51.870Z" + } + }, + "slug": "nick", + "jobProfileNotes": "Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.", + "simulatedFor": 2363, + "simulatedBy": 103674, + "preferredLanguage": "en-US", + "anonymous": false, + "permissions": [ + "admin" + ], + "autocastDelay": 90019001, + "music": false, + "dateCreated": "2013-02-28T06:09:04.743Z" + }, + + + + + + + + '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ { "_id": "53179b49b483edfcdb7ef13e", From 0561235da2b224d5fc510592b34974b89ae51681 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Thu, 17 Jul 2014 09:50:18 -0700 Subject: [PATCH 28/58] Have no emails send to employers who haven't logged in --- server/routes/mail.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 5569428f5..60b1bbaed 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -253,6 +253,8 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> if employer.emails?.employerNotes?.enabled is false return cb true + if not employer.signedEmployerAgreement and not employer.activity?.login? + return cb true findParameters = "user": employer._id "mailTask": @mailTaskName From a9d664b8ecfa775687be1e1db1957af6cf941e4d Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Thu, 17 Jul 2014 13:16:17 -0700 Subject: [PATCH 29/58] Restored legacy candidates view --- app/styles/admin/candidates.sass | 74 +++++++++ app/templates/admin.jade | 2 + app/templates/admin/candidates.jade | 110 +++++++++++++ app/views/admin/candidates_view.coffee | 207 +++++++++++++++++++++++++ server/routes/mail.coffee | 2 +- 5 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 app/styles/admin/candidates.sass create mode 100644 app/templates/admin/candidates.jade create mode 100644 app/views/admin/candidates_view.coffee diff --git a/app/styles/admin/candidates.sass b/app/styles/admin/candidates.sass new file mode 100644 index 000000000..1a34e9f12 --- /dev/null +++ b/app/styles/admin/candidates.sass @@ -0,0 +1,74 @@ +#admin-candidates-view + + h1, h2, h3 + font: Arial + + .see-candidates-header + margin: 30px + text-align: center + + #see-candidates + cursor: pointer + + .employer_icon + width: 125px + float: left + margin: 0px 15px 15px 0px + + .information_row + height: 150px + padding-right: 15px + + #leftside + width: 500px + float: left + + #rightside + width: 500px + float: left + + .tablesorter + //img + // display: none + + .tablesorter-header + cursor: pointer + &:hover + color: black + + &:first-child + // Make sure that "Developer #56" doesn't wrap onto second row + min-width: 110px + + .tablesorter-headerAsc + background-color: #cfc + + .tablesorter-headerDesc + background-color: #ccf + + tr + cursor: pointer + + tr.expired + opacity: 0.5 + + code + background-color: rgb(220, 220, 220) + color: #555 + margin: 2px 0 + display: inline-block + text-transform: lowercase + + td:nth-child(3) select + min-width: 100px + td:nth-child(6) select + min-width: 50px + td:nth-child(7) select + min-width: 100px + +#employers-view, #profile-view.viewed-by-employer + #outer-content-wrapper, #intermediate-content-wrapper, #inner-content-wrapper + background: #949494 + + .main-content-area + background-color: #EAEAEA \ No newline at end of file diff --git a/app/templates/admin.jade b/app/templates/admin.jade index 11ee67ee8..5d583f703 100644 --- a/app/templates/admin.jade +++ b/app/templates/admin.jade @@ -25,6 +25,8 @@ block content a(href="/admin/level_sessions", data-i18n="admin.av_entities_active_instances_url") Active Instances li a(href="/admin/employer_list", data-i18n="admin.av_entities_employer_list_url") Employer List + li + a(href="/admin/candidates") Candidate List h4(data-i18n="admin.av_other_sub_title") Other diff --git a/app/templates/admin/candidates.jade b/app/templates/admin/candidates.jade new file mode 100644 index 000000000..0a2d85f96 --- /dev/null +++ b/app/templates/admin/candidates.jade @@ -0,0 +1,110 @@ +extends /templates/base +block content + if !me.isAdmin() + h1 Admins Only + if me.isAdmin() + h1(data-i18n="employers.want_to_hire_our_players") Hire CodeCombat Players + if !isEmployer && !me.isAdmin() + div#info_wrapper + div#leftside + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon1.png") + h2(data-i18n="employers.what") What is CodeCombat? + p(data-i18n="employers.what_blurb") CodeCombat is a multiplayer browser programming game. Players write code to control their forces in battle against other developers. We support JavaScript, Python, Lua, Clojure, CoffeeScript, and Io. + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon3.png") + h2(data-i18n="employers.who") Who Are the Players? + p(data-i18n="employers.who_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems. + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon5.png") + h2(data-i18n="employers.cost") Who Are the Players? + p(data-i18n="employers.cost_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems. + div#rightside + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon2.png") + h2(data-i18n="employers.how") How Much Do we Charge? + p(data-i18n="employers.how_blurb") We charge 15% of first year's salary and offer a 100% money back guarantee for 90 days. We don't charge for candidates who are already actively being interviewed at your company. + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon4.png") + h2(data-i18n="employers.why") Why Hire Through Us? + p + span(data-i18n="employers.why_blurb_1") We will save you time. Every CodeCombateer we feaure is + strong(data-i18n="employers.why_blurb_2") looking for work + span(data-i18n="employers.why_blurb_3") , has + strong(data-i18n="employers.why_blurb_4") demonstrated top notch technical skills + span(data-i18n="employers.why_blurb_5") , and has been + strong(data-i18n="employers.why_blurb_6") personally screened by us + span(data-i18n="employers.why_blurb_7") . Stop screening and start hiring. + div.information_row + img(class="employer_icon" src="/images/pages/employer/employer_icon6.png") + h2(data-i18n="employers.response") What's the Response Rate? + p(data-i18n="employers.response_blurb") Almost every developer you contact on CodeCombat will respond to inquires whether or not they want to interivew. If you would like help finding a candidate for your role, we can make recommendations. + if candidates.length + ul.nav.nav-pills + li.active + a(href="#featured-candidates", data-toggle="tab") + span(data-i18n="employers.featured_developers") Featured Developers + | (#{featuredCandidates.length}) + if otherCandidates.length + li + a(href="#other-candidates", data-toggle="tab") + span(data-i18n="employers.other_developers") Other Developers + | (#{otherCandidates.length}) + if me.isAdmin() && inactiveCandidates.length + li + a(href="#inactive-candidates", data-toggle="tab") + span(data-i18n="employers.inactive_developers") Inactive Developers + | (#{inactiveCandidates.length}) + div.tab-content + for area, tabIndex in [{id: "featured-candidates", candidates: featuredCandidates}, {id: "other-candidates", candidates: otherCandidates}, {id: "inactive-candidates", candidates: inactiveCandidates}] + div(class="tab-pane well" + (tabIndex ? "" : " active"), id=area.id) + table.table.table-condensed.table-hover.table-responsive.tablesorter + thead + tr + th(data-i18n="general.name") Name + th(data-i18n="employers.candidate_location") Location + th(data-i18n="employers.candidate_looking_for") Looking For + th(data-i18n="employers.candidate_role") Role + th(data-i18n="employers.candidate_top_skills") Top Skills + th(data-i18n="employers.candidate_years_experience") Yrs Exp + th(data-i18n="employers.candidate_last_updated") Last Updated + if me.isAdmin() + th(data-i18n="employers.candidate_who") Who + if me.isAdmin() && area.id == 'inactive-candidates' + th ✓? + tbody + for candidate, index in area.candidates + - var profile = candidate.get('jobProfile'); + - var authorized = candidate.id; // If we have the id, then we are authorized. + - var profileAge = (new Date() - new Date(profile.updated)) / 86400 / 1000; + - var expired = profileAge > 2 * 30.4; + tr(data-candidate-id=candidate.id, id=candidate.id, class=expired ? "expired" : "") + td + if authorized + img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, height=50) + if profile.name + p= profile.name + else if me.isAdmin() + p (#{candidate.get('name')}) + else + img(src="/images/pages/contribute/archmage.png", alt="", title="Sign up as an employer to see our candidates", width=50) + p Developer ##{index + 1 + (area.id == 'featured-candidates' ? 0 : featuredCandidates.length)} + if profile.country == 'USA' + td= profile.city + else + td= profile.country + td= profile.lookingFor + td= profile.jobTitle + td + each skill in profile.skills + code= skill + span + td= profile.experience + td(data-profile-age=profileAge)= moment(profile.updated).fromNow() + if me.isAdmin() + td= remarks[candidate.id] ? remarks[candidate.id].get('contactName') : '' + if me.isAdmin() && area.id == 'inactive-candidates' + if candidate.get('jobProfileApproved') + td ✓ + else + td ✗ \ No newline at end of file diff --git a/app/views/admin/candidates_view.coffee b/app/views/admin/candidates_view.coffee new file mode 100644 index 000000000..2946b161d --- /dev/null +++ b/app/views/admin/candidates_view.coffee @@ -0,0 +1,207 @@ +View = require 'views/kinds/RootView' +template = require 'templates/admin/candidates' +app = require 'application' +User = require 'models/User' +UserRemark = require 'models/UserRemark' +{me} = require 'lib/auth' +CocoCollection = require 'collections/CocoCollection' +EmployerSignupView = require 'views/modal/employer_signup_modal' + +class CandidatesCollection extends CocoCollection + url: '/db/user/x/candidates' + model: User + +class UserRemarksCollection extends CocoCollection + url: '/db/user.remark?project=contact,contactName,user' + model: UserRemark + +module.exports = class EmployersView extends View + id: "admin-candidates-view" + template: template + + events: + 'click tbody tr': 'onCandidateClicked' + + constructor: (options) -> + super options + @getCandidates() + + afterRender: -> + super() + @sortTable() if @candidates.models.length + + afterInsert: -> + super() + _.delay @checkForEmployerSignupHash, 500 + + getRenderData: -> + ctx = super() + ctx.isEmployer = @isEmployer() + ctx.candidates = _.sortBy @candidates.models, (c) -> c.get('jobProfile').updated + ctx.activeCandidates = _.filter ctx.candidates, (c) -> c.get('jobProfile').active + ctx.inactiveCandidates = _.reject ctx.candidates, (c) -> c.get('jobProfile').active + ctx.featuredCandidates = _.filter ctx.activeCandidates, (c) -> c.get('jobProfileApproved') + ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved') + ctx.remarks = {} + ctx.remarks[remark.get('user')] = remark for remark in @remarks.models + ctx.moment = moment + ctx._ = _ + ctx + + isEmployer: -> + userPermissions = me.get('permissions') ? [] + _.contains userPermissions, "employer" + + getCandidates: -> + @candidates = new CandidatesCollection() + @candidates.fetch() + @remarks = new UserRemarksCollection() + @remarks.fetch() + # Re-render when we have fetched them, but don't wait and show a progress bar while loading. + @listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling + @listenToOnce @remarks, 'all', @renderCandidatesAndSetupScrolling + + renderCandidatesAndSetupScrolling: => + @render() + $(".nano").nanoScroller() + if window.history?.state?.lastViewedCandidateID + $(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)}) + else if window.location.hash.length is 25 + $(".nano").nanoScroller({scrollTo:$(window.location.hash)}) + + checkForEmployerSignupHash: => + if window.location.hash is "#employerSignupLoggingIn" and not ("employer" in me.get("permissions")) + @openModalView application.router.getView("modal/employer_signup","_modal") + window.location.hash = "" + + sortTable: -> + # http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html + $.extend $.tablesorter.themes.bootstrap, + # these classes are added to the table. To see other table classes available, + # look here: http://twitter.github.com/bootstrap/base-css.html#tables + table: "table table-bordered" + caption: "caption" + header: "bootstrap-header" # give the header a gradient background + footerRow: "" + footerCells: "" + icons: "" # add "icon-white" to make them white; this icon class is added to the <i> in the header + sortNone: "bootstrap-icon-unsorted" + sortAsc: "icon-chevron-up" # glyphicon glyphicon-chevron-up" # we are still using v2 icons + sortDesc: "icon-chevron-down" # glyphicon-chevron-down" # we are still using v2 icons + active: "" # applied when column is sorted + hover: "" # use custom css here - bootstrap class may not override it + filterRow: "" # filter row class + even: "" # odd row zebra striping + odd: "" # even row zebra striping + + + # e = exact text from cell + # n = normalized value returned by the column parser + # f = search filter input value + # i = column index + # $r = ??? + filterSelectExactMatch = (e, n, f, i, $r) -> e is f + + # call the tablesorter plugin and apply the uitheme widget + @$el.find(".tablesorter").tablesorter + theme: "bootstrap" + widthFixed: true + headerTemplate: "{content} {icon}" + textSorter: + 6: (a, b, direction, column, table) -> + days = [] + for s in [a, b] + n = parseInt s + n = 0 unless _.isNumber n + n = 1 if /^a/.test s + for [duration, factor] in [ + [/second/i, 1 / (86400 * 1000)] + [/minute/i, 1 / 1440] + [/hour/i, 1 / 24] + [/week/i, 7] + [/month/i, 30.42] + [/year/i, 365.2425] + ] + if duration.test s + n *= factor + break + if /^in /i.test s + n *= -1 + days.push n + days[0] - days[1] + sortList: if @isEmployer() or me.isAdmin() then [[6, 0]] else [[0, 1]] + # widget code contained in the jquery.tablesorter.widgets.js file + # use the zebra stripe widget if you plan on hiding any rows (filter widget) + widgets: ["uitheme", "zebra", "filter"] + widgetOptions: + # using the default zebra striping class name, so it actually isn't included in the theme variable above + # this is ONLY needed for bootstrap theming if you are using the filter widget, because rows are hidden + zebra: ["even", "odd"] + + # extra css class applied to the table row containing the filters & the inputs within that row + filter_cssFilter: "" + + # If there are child rows in the table (rows with class name from "cssChildRow" option) + # and this option is true and a match is found anywhere in the child row, then it will make that row + # visible; default is false + filter_childRows: false + + # if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately + # below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus + filter_hideFilters: false + + # Set this option to false to make the searches case sensitive + filter_ignoreCase: true + + # jQuery selector string of an element used to reset the filters + filter_reset: ".reset" + + # Use the $.tablesorter.storage utility to save the most recent filters + filter_saveFilters: true + + # Delay in milliseconds before the filter widget starts searching; This option prevents searching for + # every character while typing and should make searching large tables faster. + filter_searchDelay: 150 + + # Set this option to true to use the filter to find text from the start of the column + # So typing in "a" will find "albert" but not "frank", both have a's; default is false + filter_startsWith: false + + filter_functions: + 2: + "Full-time": filterSelectExactMatch + "Part-time": filterSelectExactMatch + "Contracting": filterSelectExactMatch + "Remote": filterSelectExactMatch + "Internship": filterSelectExactMatch + 5: + "0-1": (e, n, f, i, $r) -> n <= 1 + "2-5": (e, n, f, i, $r) -> 2 <= n <= 5 + "6+": (e, n, f, i, $r) -> 6 <= n + 6: + "Last day": (e, n, f, i, $r) -> + days = parseFloat $($r.find('td')[i]).data('profile-age') + days <= 1 + "Last week": (e, n, f, i, $r) -> + days = parseFloat $($r.find('td')[i]).data('profile-age') + days <= 7 + "Last 4 weeks": (e, n, f, i, $r) -> + days = parseFloat $($r.find('td')[i]).data('profile-age') + days <= 28 + 8: + "✓": filterSelectExactMatch + "✗": filterSelectExactMatch + + onCandidateClicked: (e) -> + id = $(e.target).closest('tr').data('candidate-id') + if id + if window.history + oldState = _.cloneDeep window.history.state ? {} + oldState["lastViewedCandidateID"] = id + window.history.replaceState(oldState,"") + else + window.location.hash = id + url = "/account/profile/#{id}" + window.open url,"_blank" + else + @openModalView new EmployerSignupView \ No newline at end of file diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 60b1bbaed..26a5e8ed0 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -327,7 +327,7 @@ employerMatchingCandidateNotificationTask = -> ### ### End Employer Matching Candidate Notification Email ### ### Ladder Update Email ### - +### Employer ignore ### DEBUGGING = false LADDER_PREGAME_INTERVAL = 2 * 3600 * 1000 # Send emails two hours before players last submitted. getTimeFromDaysAgo = (now, daysAgo) -> From 6b028513fdf3c3ba6146485c37dc3995c558240f Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 15:50:29 -0700 Subject: [PATCH 30/58] Fixed issues with level previews and localStorage model loading. Disabled break animations on code error for now. Stopped multiple ThangType load on multiple missiles. Stopped trying to connect to Redis on local production setup. --- app/lib/surface/CocoSprite.coffee | 4 +- app/lib/surface/Surface.coffee | 5 ++- app/views/editor/level/edit.coffee | 2 +- app/views/play/level_view.coffee | 5 ++- server/routes/mail.coffee | 72 +++++++++++++++--------------- 5 files changed, 45 insertions(+), 43 deletions(-) diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee index 3bc8e7330..b05fe99db 100644 --- a/app/lib/surface/CocoSprite.coffee +++ b/app/lib/surface/CocoSprite.coffee @@ -82,7 +82,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass if @thangType.isFullyLoaded() @setupSprite() else - @thangType.fetch() + @thangType.fetch() unless @thangType.loading @listenToOnce(@thangType, 'sync', @setupSprite) setupSprite: -> @@ -442,7 +442,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass console.warn 'Cannot show action', action, 'for', @thangType.get('name'), 'because it DNE' unless @warnedFor[action] @warnedFor[action] = true return if @action is 'idle' then null else 'idle' - action = 'break' if @actions.break? and @thang?.erroredOut + #action = 'break' if @actions.break? and @thang?.erroredOut # This makes it looks like it's dead when it's not: bad in Brawlwood. action = 'die' if @actions.die? and thang?.health? and thang.health <= 0 @actions[action] diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index f435f8110..bd6cf7df1 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -115,7 +115,8 @@ module.exports = Surface = class Surface extends CocoClass setWorld: (@world) -> @worldLoaded = true - @world.getFrame(Math.min(@getCurrentFrame(), @world.totalFrames - 1)).restoreState() unless @options.choosing + lastFrame = Math.min(@getCurrentFrame(), @world.totalFrames - 1) + @world.getFrame(lastFrame).restoreState() unless @options.choosing @spriteBoss.world = @world @showLevel() @@ -241,7 +242,7 @@ module.exports = Surface = class Surface extends CocoClass @onFrameChanged() getCurrentFrame: -> - return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1)) + return Math.max(0, Math.min(Math.floor(@currentFrame), @world.frames.length - 1)) getProgress: -> @currentFrame / @world.totalFrames diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 18bc8edf5..7e893d748 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -40,7 +40,7 @@ module.exports = class EditorLevelView extends View constructor: (options, @levelID) -> super options @supermodel.shouldSaveBackups = (model) -> - model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem'] + model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem', 'ThangType'] @levelLoader = new LevelLoader supermodel: @supermodel, levelID: @levelID, headless: true, editorMode: true @level = @levelLoader.level @files = new DocumentFiles(@levelLoader.level) diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index c15fe7c6e..3527df5e5 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -84,8 +84,9 @@ module.exports = class PlayLevelView extends View @saveScreenshot = _.throttle @saveScreenshot, 30000 if @isEditorPreview - # wait to see if it's just given to us through setLevel - f = => @load() unless @levelLoader + @supermodel.shouldSaveBackups = (model) -> # Make sure to load possibly changed things from localStorage. + model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem', 'ThangType'] + f = => @load() unless @levelLoader # Wait to see if it's just given to us through setLevel. setTimeout f, 100 else @load() diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 60b1bbaed..887de3cf5 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -8,15 +8,15 @@ LevelSession = require '../levels/sessions/LevelSession' Level = require '../levels/Level' log = require 'winston' sendwithus = require '../sendwithus' -if config.isProduction +if config.isProduction and config.redis.host isnt 'localhost' lockManager = require '../commons/LockManager' - + module.exports.setup = (app) -> app.all config.mail.mailchimpWebhook, handleMailchimpWebHook app.get '/mail/cron/ladder-update', handleLadderUpdate if lockManager setupScheduledEmails() - + setupScheduledEmails = -> testForLockManager() mailTasks = [ @@ -31,15 +31,15 @@ setupScheduledEmails = -> ] for mailTask in mailTasks - setInterval mailTask.taskFunction, mailTask.frequencyMs - + setInterval mailTask.taskFunction, mailTask.frequencyMs + testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" - + ### Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" - lockDurationMs = 2 * 60 * 1000 + lockDurationMs = 2 * 60 * 1000 currentDate = new Date() timeRanges = [] for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']] @@ -66,12 +66,12 @@ emailTimeRange = (timeRange, emailTimeRangeCallback) -> "mailTaskName": @mailTaskName async.waterfall [ findAllCandidatesWithinTimeRange.bind(waterfallContext) - (unfilteredCandidates, cb) -> + (unfilteredCandidates, cb) -> async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), cb.bind(null, null) (filteredCandidates, cb) -> async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb ], emailTimeRangeCallback - + findAllCandidatesWithinTimeRange = (cb) -> findParameters = "jobProfile.updated": @@ -80,7 +80,7 @@ findAllCandidatesWithinTimeRange = (cb) -> "jobProfileApproved": true selection = "_id email jobProfile.name jobProfile.updated emails" #make sure to check for anyNotes too. User.find(findParameters).select(selection).lean().exec cb - + candidateFilter = (candidate, sentEmailFilterCallback) -> if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false return sentEmailFilterCallback true @@ -102,7 +102,7 @@ findEmployersSignedUpAfterDate = (dateObject, cb) -> employerAt: {$exists: true} permissions: "employer" User.count countParameters, cb - + sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) => if err? @@ -136,7 +136,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" - lockDurationMs = 2 * 60 * 1000 + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) -> @@ -162,31 +162,31 @@ emailInternalCandidateUpdateReminder = (internalCandidateUpdateReminderCallback) (filteredCandidates, cb) -> async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb ], internalCandidateUpdateReminderCallback - + findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) -> - findParameters = + findParameters = "jobProfile.updated": $lte: @currentTime.toISOString() $gt: @beginningOfUTCDay.toISOString() - "jobProfileApproved": false + "jobProfileApproved": false User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb - + candidatesUpdatedTodayFilter = (candidate, cb) -> findParameters = "user": candidate._id "mailTask": @mailTaskName - "metadata.beginningOfUTCDay": @beginningOfUTCDay + "metadata.beginningOfUTCDay": @beginningOfUTCDay MailSent.find(findParameters).lean().exec (err, sentMail) -> if err? log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" cb true else cb Boolean(sentMail.length) - + sendInternalCandidateUpdateReminder = (candidate, cb) -> context = email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE" - recipient: + recipient: address: "team@codecombat.com" name: "The CodeCombat Team" email_data: @@ -197,7 +197,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> user: candidate._id metadata: beginningOfUTCDay: @beginningOfUTCDay - + MailSent.create newSentMail, (err) -> if err? then return cb err sendwithus.api.send context, (err, result) -> @@ -208,7 +208,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> ### Employer New Candidates Available Email ### employerNewCandidatesAvailableTask = -> mailTaskName = "employerNewCandidatesAvailableTask" - lockDurationMs = 2 * 60 * 1000 + lockDurationMs = 2 * 60 * 1000 lockManager.setLock mailTaskName, lockDurationMs, (err) -> if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) -> @@ -221,10 +221,10 @@ employerNewCandidatesAvailableTask = -> emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallback) -> currentTime = new Date() - asyncContext = + asyncContext = "currentTime": currentTime "mailTaskName": @mailTaskName - + async.waterfall [ findAllEmployers makeEmployerNamesEasilyAccessible @@ -233,15 +233,15 @@ emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallba (employersToEmail, cb) -> async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb ], emailEmployerNewCandidatesAvailableCallback - + findAllEmployers = (cb) -> - findParameters = + findParameters = "employerAt": - $exists: true + $exists: true permissions: "employer" selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated emails" User.find(findParameters).select(selection).lean().exec cb - + makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> for employer, index in allEmployers if employer.signedEmployerAgreement?.data?.firstName @@ -249,17 +249,17 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) -> delete employer.signedEmployerAgreement allEmployers[index] = employer cb null, allEmployers - + employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> if employer.emails?.employerNotes?.enabled is false return cb true if not employer.signedEmployerAgreement and not employer.activity?.login? return cb true - findParameters = + findParameters = "user": employer._id "mailTask": @mailTaskName "sent": - $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) + $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) MailSent.find(findParameters).lean().exec (err, sentMail) -> if err? log.error "Error finding mail sent for task #{@mailTaskName} and employer #employer._id}!" @@ -268,17 +268,17 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) -> cb Boolean(sentMail.length) sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> - lastLoginDate = employer.activity?.login?.last ? employer.dateCreated + lastLoginDate = employer.activity?.login?.last ? employer.dateCreated countParameters = "jobProfileApproved": true $or: [ - jobProfileApprovedDate: + jobProfileApprovedDate: $gt: lastLoginDate.toISOString() , jobProfileApprovedDate: $exists: false "jobProfile.updated": - $gt: lastLoginDate.toISOString() + $gt: lastLoginDate.toISOString() ] User.count countParameters, (err, numberOfCandidatesSinceLogin) => if err? then return cb err @@ -315,8 +315,8 @@ newRecruitLeaderboardEmailTask = -> lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) -> ### ### End New Recruit Leaderboard Email ### - -### Employer Matching Candidate Notification Email ### + +### Employer Matching Candidate Notification Email ### ### employerMatchingCandidateNotificationTask = -> # tem_mYsepTfWQ265noKfZJcbBH @@ -344,7 +344,7 @@ isRequestFromDesignatedCronHandler = (req, res) -> return true - + handleLadderUpdate = (req, res) -> log.info('Going to see about sending ladder update emails.') requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res From 4818a81854eb38a9bf1e119a0a8c604b0edf024c Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:22:06 -0700 Subject: [PATCH 31/58] Added setProjection so CocoModels can more easily get subsets of data. --- app/models/CocoModel.coffee | 15 +++++++++++---- test/app/models/CocoModel.spec.coffee | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 045843306..5da19cab3 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -13,8 +13,10 @@ class CocoModel extends Backbone.Model getMe: -> @me or @me = require('lib/auth').me - initialize: -> - super() + initialize: (attributes, options) -> + super(arguments...) + options ?= {} + @setProjection options.project if not @constructor.className console.error("#{@} needs a className set.") @addSchemaDefaults() @@ -22,6 +24,8 @@ class CocoModel extends Backbone.Model @on 'error', @onError, @ @on 'add', @onLoaded, @ @saveBackup = _.debounce(@saveBackup, 500) + + setProjection: (@project) -> type: -> @constructor.className @@ -116,8 +120,11 @@ class CocoModel extends Backbone.Model console.debug 'Patching', @get('name') or @, keys @save(attrs, options) - fetch: -> - @jqxhr = super(arguments...) + fetch: (options) -> + options ?= {} + options.data ?= {} + options.data.project = @project.join(',') if @project + @jqxhr = super(options) @loading = true @jqxhr diff --git a/test/app/models/CocoModel.spec.coffee b/test/app/models/CocoModel.spec.coffee index 67e019c9a..7f2529466 100644 --- a/test/app/models/CocoModel.spec.coffee +++ b/test/app/models/CocoModel.spec.coffee @@ -14,6 +14,14 @@ class BlandClass extends CocoModel urlRoot: '/db/bland' describe 'CocoModel', -> + describe 'setProjection', -> + it 'takes an array of properties to project and adds them as a query parameter', -> + b = new BlandClass({}) + b.setProjection ['number', 'object'] + b.fetch() + request = jasmine.Ajax.requests.mostRecent() + expect(decodeURIComponent(request.url).indexOf('project=number,object')).toBeGreaterThan(-1) + describe 'save', -> it 'saves to db/<urlRoot>', -> From 1b999a2efea3642d93c65ef9c6a5a8d3e751d49e Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:28:52 -0700 Subject: [PATCH 32/58] Extended getLatestVersion for Handler to also be able to accept project parameters. --- server/commons/Handler.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index a796b705e..9dfca705b 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -232,7 +232,11 @@ module.exports = class Handler query['version.minor'] = minorVersion unless _.isNaN(minorVersion) sort = { 'version.major': -1, 'version.minor': -1 } args = [query] - args.push PROJECT if req.query.project + if req.query.project + projection = {} + fields = if req.query.project is 'true' then _.keys(PROJECT) else req.query.project.split(',') + projection[field] = 1 for field in fields + args.push projection @modelClass.findOne(args...).sort(sort).exec (err, doc) => return @sendNotFoundError(res) unless doc? return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc) From 51e63ddbc3ec06f2e021f385a3757b71a6ed4f2e Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:29:26 -0700 Subject: [PATCH 33/58] Fixed some DemoView issues, mainly clicking links from one demo to another. --- app/views/DemoView.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/DemoView.coffee b/app/views/DemoView.coffee index a3b65c781..d18190162 100644 --- a/app/views/DemoView.coffee +++ b/app/views/DemoView.coffee @@ -35,6 +35,7 @@ module.exports = DemoView = class DemoView extends CocoView @loadDemoingLibs() unless DemoView.loaded loadDemoingLibs: -> + DemoView.loaded = true @queue = new createjs.LoadQueue() @queue.on('complete', @scriptsLoaded, @) window.jasmine = {} # so that mock-ajax properly loads. It expects jasmine to be loaded @@ -81,8 +82,14 @@ module.exports = DemoView = class DemoView extends CocoView view = demoFunc() return unless view @$el.find('#demo-area').empty().append(view.$el) + view.afterInsert() # TODO, maybe handle root views differently than modal views differently than everything else? getAllDemoFiles: -> allFiles = window.require.list() (f for f in allFiles when f.indexOf('.demo') > -1) + + destroy: -> + # hack to get jasmine tests to properly run again on clicking links, and make sure if you + # leave this page (say, back to the main site) that test stuff doesn't follow you. + document.location.reload() From 45a8278e7ebbc8c8bb3dd1f6a68b1df0a462c8ac Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:30:56 -0700 Subject: [PATCH 34/58] Work on the job profile view, initial work on the code modal. --- app/schemas/models/level.coffee | 1 + app/schemas/models/level_session.coffee | 2 +- .../common/level_session_code_view.sass | 19 + .../account/job_profile_code_modal.jade | 13 + app/templates/account/profile.jade | 15 +- app/templates/common/level_session_code.jade | 13 + app/views/account/JobProfileCodeModal.coffee | 19 + app/views/account/profile_view.coffee | 8 + app/views/common/LevelSessionCodeView.coffee | 46 ++ server/users/user_handler.coffee | 2 +- .../common/LevelSessionCodeView.demo.coffee | 65 ++ .../views/user/JobProfileView.demo.coffee | 558 +++++++----------- 12 files changed, 422 insertions(+), 339 deletions(-) create mode 100644 app/styles/common/level_session_code_view.sass create mode 100644 app/templates/account/job_profile_code_modal.jade create mode 100644 app/templates/common/level_session_code.jade create mode 100644 app/views/account/JobProfileCodeModal.coffee create mode 100644 app/views/common/LevelSessionCodeView.coffee create mode 100644 test/demo/views/common/LevelSessionCodeView.demo.coffee diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee index eba42f599..31ce3f3f9 100644 --- a/app/schemas/models/level.coffee +++ b/app/schemas/models/level.coffee @@ -230,6 +230,7 @@ _.extend LevelSchema.properties, title: 'Next Level', description: 'Reference to the next level players will play after beating this one.' } + employerDescription: { type:'string' } scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema # TODO: uniqueness should be based on 'original', not whole thing diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee index f4f629914..92ff0f5ba 100644 --- a/app/schemas/models/level_session.coffee +++ b/app/schemas/models/level_session.coffee @@ -13,7 +13,7 @@ LevelSessionPlayerSchema = c.object changes: type: 'Number' -LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion']}, +LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion'], links: [{rel: 'db', href: '/db/level/{(original)}/version/{(majorVersion)}'}]}, original: c.objectId({}) majorVersion: type: 'integer' diff --git a/app/styles/common/level_session_code_view.sass b/app/styles/common/level_session_code_view.sass new file mode 100644 index 000000000..2e5ae518b --- /dev/null +++ b/app/styles/common/level_session_code_view.sass @@ -0,0 +1,19 @@ +.level-session-code-view + #level-icon + width: 100px + margin-right: 10px + display: inline-block + float: left + + #level-meta-data + margin-left: 120px + + #session-code + clear: both + + h3 + font-family: Arial + + .code + height: 600px + border: 2px solid black \ No newline at end of file diff --git a/app/templates/account/job_profile_code_modal.jade b/app/templates/account/job_profile_code_modal.jade new file mode 100644 index 000000000..6fb40e492 --- /dev/null +++ b/app/templates/account/job_profile_code_modal.jade @@ -0,0 +1,13 @@ +extends /templates/modal/modal_base + +block modal-header-content + .modal-header + h3 Applicant Code + +block modal-body-content + .modal-body + .level-session-code-view + +block modal-footer + .modal-footer + button(data-dismiss="modal", data-i18n="modal.close").btn Close diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade index 11c0d6956..3f71b8b34 100644 --- a/app/templates/account/profile.jade +++ b/app/templates/account/profile.jade @@ -181,13 +181,14 @@ block content ul.sessions each session in sessions li - - var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id); - a(href=sessionLink) - span= session.levelName - if session.team - span #{session.team} - if session.codeLanguage != 'javascript' - span - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} + span.session-link(data-session-id=session._id)= session.levelName + //- var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id); + //a(href=sessionLink) + // span= session.levelName + // if session.team + // span #{session.team} + //if session.codeLanguage != 'javascript' + // span - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} .middle-column.full-height-column .sub-column diff --git a/app/templates/common/level_session_code.jade b/app/templates/common/level_session_code.jade new file mode 100644 index 000000000..eb6f6a867 --- /dev/null +++ b/app/templates/common/level_session_code.jade @@ -0,0 +1,13 @@ +div#session-info + img(src='/file/'+levelIcon alt='levelIcon')#level-icon + div#level-meta-data + strong= levelName + p!= levelDescription + +div#session-code + for spell in levelSpells + .panel.panel-success + .panel-heading + h3= spell.name + .panel-body + .code= spell.code \ No newline at end of file diff --git a/app/views/account/JobProfileCodeModal.coffee b/app/views/account/JobProfileCodeModal.coffee new file mode 100644 index 000000000..d8545bd43 --- /dev/null +++ b/app/views/account/JobProfileCodeModal.coffee @@ -0,0 +1,19 @@ +ModalView = require 'views/kinds/ModalView' +template = require 'templates/account/job_profile_code_modal' +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +console.log 'template', template + +module.exports = class JobProfileCodeModal extends ModalView + id: 'job_profile_code_modal' + template: template + + constructor: (options) -> + super(arguments...) + @session = options.session + + afterRender: -> + super() + return unless @session.loaded + codeView = new LevelSessionCodeView({session:@session}) + @insertSubView(codeView) + \ No newline at end of file diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee index bccb1c7d0..3d3b0b823 100644 --- a/app/views/account/profile_view.coffee +++ b/app/views/account/profile_view.coffee @@ -9,6 +9,7 @@ JobProfileView = require 'views/account/job_profile_view' UserRemark = require 'models/UserRemark' forms = require 'lib/forms' ModelModal = require 'views/modal/model_modal' +JobProfileCodeModal = require './JobProfileCodeModal' class LevelSessionsCollection extends CocoCollection url: -> "/db/user/#{@userID}/level.sessions/employer" @@ -51,6 +52,7 @@ module.exports = class ProfileView extends RootView 'keyup .editable-profile .editable-array input': 'onEditArray' 'click .editable-profile a': 'onClickLinkWhileEditing' 'change #admin-contact': 'onAdminContactChanged' + 'click .session-link': 'onSessionLinkPressed' constructor: (options, @userID) -> @userID ?= me.id @@ -586,3 +588,9 @@ module.exports = class ProfileView extends RootView {name: t('account_profile.next_photo'), weight: 2, container: '#profile-photo-container', fn: modified 'photoURL'} {name: t('account_profile.next_active'), weight: 1, fn: modified 'active'} ] + + onSessionLinkPressed: (e) -> + sessionID = $(e.target).data('session-id') + session = _.find @sessions.models, (session) -> session.id is sessionID + modal = new JobProfileCodeModal({session:session}) + @openModalView modal \ No newline at end of file diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee new file mode 100644 index 000000000..9a38166fb --- /dev/null +++ b/app/views/common/LevelSessionCodeView.coffee @@ -0,0 +1,46 @@ +CocoView = require 'views/kinds/CocoView' +template = require 'templates/common/level_session_code' + +Level = require 'models/Level' +LevelSession = require 'models/LevelSession' + +module.exports = class LevelSessionCodeView extends CocoView + className: 'level-session-code-view' + template: template + modalWidthPercent: 80 + plain: true + + constructor: (options) -> + super(options) + @session = options.session + @level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level) + @level.setProjection ['employerDescription', 'name', 'icon'] + @supermodel.loadModel @level, 'level' + + getRenderData: -> + c = super() + c.levelIcon = @level.get('icon') + c.levelName = @level.get('name') + c.levelDescription = marked(@level.get('employerDescription') or '') + c.levelSpells = @organizeCode() + c + + afterRender: -> + super() + @$el.find('.code').each (index, codeEl) -> + editor = ace.edit codeEl + editor.setReadOnly true + aceSession = editor.getSession() + aceSession.setMode 'ace/mode/javascript' + + organizeCode: -> + team = @session.get('team') or 'humans' + teamSpells = @session.get('teamSpells')[team] or [] + filteredSpells = [] + for spell in teamSpells + code = @session.getSourceFor(spell) + filteredSpells.push { + code: code + name: spell.split('/')[1] + } + filteredSpells \ No newline at end of file diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 275807ad7..fbd13ec19 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -233,7 +233,7 @@ UserHandler = class UserHandler extends Handler getLevelSessionsForEmployer: (req, res, userID) -> return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions')) query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']} - projection = 'levelName levelID team playtime codeLanguage submitted code totalScore' + projection = 'levelName levelID team playtime codeLanguage submitted code totalScore teamSpells level' LevelSession.find(query).select(projection).exec (err, documents) => return @sendDatabaseError(res, err) if err documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents) diff --git a/test/demo/views/common/LevelSessionCodeView.demo.coffee b/test/demo/views/common/LevelSessionCodeView.demo.coffee new file mode 100644 index 000000000..938bec582 --- /dev/null +++ b/test/demo/views/common/LevelSessionCodeView.demo.coffee @@ -0,0 +1,65 @@ +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +LevelSession = require 'models/LevelSession' + +levelSessionData = { + "_id": "5334901f0a0f9b286f57382c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "team": "humans", + "code": { + "coin-generator-9000": { + "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n// this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n this.build('gem');\nelse if (Math.random() < 0.25)\n this.build(buildOrder[this.built.length % buildOrder.length])\nelse if (Math.random() < 0.5)\n this.build('coin');\n\n\n\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\n\n//this.say(human.gold);\n\n//this.say(\"Humans: \" + human.gold + \", \" + \"Ogres: \" + ogre.gold);\n\nif(ogre.gold >= 150) {\n this.say(\"Ogres win!\");\n this.setGoalState(\"goldOgres\", \"success\");\n}\n\nelse if(human.gold >= 150) {\n this.say(\"Humans win!\");\n this.setGoalState(\"goldHumans\", \"success\");\n}" + }, + "programmable-coin": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\nif (typeof this.teleportOnce === 'undefined') {\n this.teleportRandom();\n this.teleportOnce = true;\n}\n//}" + }, + "tharin": { + "chooseAction": "var t = this;\nvar e = t.getNearestEnemy();\nvar vec = new Vector(0, 0);\n\nfunction item_worth(item) {\n return item.bountyGold/Math.pow(item.distance(e) - t.distance(item), 1.5);\n}\n\nvar items = this.getItems();\nfor (var i = 0; i < items.length; i++) {\n var item = items[i];\n var direction = Vector.normalize(Vector.subtract(item.pos, this.pos));\n var weighted_dir = Vector.multiply(direction, 1000 * item_worth(item));\n vec = Vector.add(vec, weighted_dir);\n}\n\nvar action = \"move\";\nif (typeof this.used_terrify == \"undefined\") {\n var enemy = this.getNearestEnemy();\n \n if (enemy.gold >= 140 || this.distance(enemy) <= 15) {\n action = \"terrify\";\n }\n}\n\nif (action == \"move\") {\n var best_item = null;\n var best_item_value = 0;\n for (var i = 0; i < items.length; i++) {\n var item = items[i];\n var direction = Vector.subtract(item.pos, this.pos);\n \n var angle = Math.acos(vec.dot(direction) / (vec.magnitude() * direction.magnitude()))\n if (angle < Math.PI / 16 || angle > Math.PI * (31/16)) {\n if (item_worth(item) > best_item_value) {\n best_item_value = item_worth(item);\n best_item = item;\n }\n }\n }\n \n if (best_item_value > 0.05) {\n this.move(best_item.pos);\n } else {\n this.say(\"Move to \" + Vector.add(this.pos, vec).x + \" \" + Vector.add(this.pos, vec).y);\n this.move(Vector.add(this.pos, vec));\n }\n} else if (action == \"terrify\") {\n //this.terrify();\n this.used_terrify = true;\n}\n/*\n\n// This code runs once per frame. Choose where to move to grab gold!\n// First player to 150 gold wins.\n\n// This is an example of grabbing the 0th coin from the items array.\nvar items = this.getItems();\nif (items[0]) {\n this.move(items[0].pos);\n} else {\n this.moveXY(18, 36);\n}\n\n\n// You can surely pick a better coin using the methods below.\n// Click on a coin to see its API.\n*/\n" + }, + "wizard-purple": { + "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n this.build('coin');\n// console.log(\"build coin\");\n//}" + } + }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "levelID": "gold-rush", + "levelName": "Gold Rush", + "totalScore": 39.23691444835561, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1158, + "codeLanguage": "javascript" +} + +levelData = { + "_id": "53c71962587cd615bf404919", + "name": "Dungeon Arena", + "icon": "db/level/53173f76c269d400000543c2/11_dungeon.png", + "description": "This level is indescribably flarmy!", + "employerDescription": "A DotA-like level where players:\n* Take control of a hero with special abilities\n* Choose which sorts of troops to build.\n* Have limited control over their troops." + "version": { + "minor": 0, + "major": 0, + "isLatestMajor": true, + "isLatestMinor": true + } +} + +module.exports = -> + session = new LevelSession(levelSessionData) + v = new LevelSessionCodeView({session:session}) + request = jasmine.Ajax.requests.mostRecent() + request.response({status: 200, responseText: JSON.stringify(levelData)}) + console.log 'okay should be fine' + v diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee index 2aabea003..b3a8e1b03 100644 --- a/test/demo/views/user/JobProfileView.demo.coffee +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -3,7 +3,6 @@ ProfileView = require 'views/account/profile_view' responses = '/db/user/joe/nameToID':'512ef4805a67a8c507000001' - '/db/user/512ef4805a67a8c507000001': { "_id": "512ef4805a67a8c507000001", "__v": 47, @@ -239,16 +238,13 @@ responses = "dateCreated": "2013-02-28T06:09:04.743Z" }, - - - - - - - '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ { "_id": "53179b49b483edfcdb7ef13e", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, "code": { "human-base": { "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" @@ -270,6 +266,18 @@ responses = } }, "submitted": false, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, "levelID": "dungeon-arena", "levelName": "Dungeon Arena", "submittedCodeLanguage": "javascript", @@ -278,6 +286,10 @@ responses = }, { "_id": "53336ee91506ed33756f73e5", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, "code": { "tharin": { "chooseAction": "this.say(\"Say, who's in charge around here?\"); // Should fill in some default source" @@ -289,6 +301,13 @@ responses = "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n this.build('coin');\n// console.log(\"build coin\");\n//}" } }, + "teamSpells": { + "humans": [ + "programmable-coin/chooseAction", + "tharin/chooseAction", + "wizard-purple/chooseAction" + ] + }, "levelID": "gold-rush", "levelName": "Resource gathering multiplayer", "submittedCodeLanguage": "javascript", @@ -297,6 +316,10 @@ responses = }, { "_id": "52ae32cbef42c52f1300000d", + "level": { + "original": "52ae2460ef42c52f13000008", + "majorVersion": 0 + }, "levelID": "gridmancer", "levelName": "Gridmancer", "code": { @@ -307,6 +330,11 @@ responses = "plan": "var grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar canOverlap = false;\nvar i, rect;\nthis.doWait = function() {\n this.wait(1);\n this.say(\"hi\");\n this.wait(1);\n this.say(\"there\");\n this.wait(1);\n};\nthis.doWait();\nfor (var y = 0; y + tileSize < grid.length; y += tileSize) {\n for (var x = 0; x + tileSize < grid[0].length;) {\n // check if wall\n var occupied = grid[y][x].length > 0;\n // check if already covered by another rect\n if (!occupied) {\n for (i = 0; i < this.spawnedRectangles.length; ++i) {\n rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x && x < rect.pos.x + rect.width / 2 && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n occupied = true;\n }\n }\n if (!occupied) {\n var x2 = x,\n y2 = y;\n // expand to the right until we find a wall\n while (x2 < grid[0].length - 1 && grid[y][x2 + tileSize].length === 0)\n x2 += tileSize;\n // expand current horizontal rectangle vertically until wall\n var ok = true;\n while (y2 + tileSize < grid.length && ok) {\n var yt = y2 + tileSize;\n // check each cell\n for (var xt = x; xt <= x2; xt += tileSize) {\n if (grid[yt][xt].length > 0) {\n ok = false;\n }\n }\n if (!canOverlap) {\n // check if tile to the left is non-wall\n if (x > 0 && grid[yt][x - tileSize].length === 0) {\n // check if already has a rect\n var covered = false;\n for (i = 0; i < this.spawnedRectangles.length; ++i) {\n rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x - tileSize &&\n x - tileSize < rect.pos.x + rect.width / 2 &&\n rect.pos.y - rect.height / 2 < yt &&\n rect.pos.y + rect.height / 2 > yt)\n covered = true;\n }\n // if no wall and no rect leave open to avoid future overlap\n if (!covered)\n ok = false;\n }\n }\n // advance\n if (ok)\n y2 += tileSize;\n }\n // done\n this.addRect(x + tileSize / 2 + (x2 - x) / 2, y + tileSize / 2 + (y2 - y) / 2,\n tileSize + (x2 - x), tileSize + (y2 - y));\n x = x2 + tileSize;\n this.wait();\n } else {\n x += tileSize;\n }\n }\n}\n\n/*\nvar tileSize = 4;\n\nvar grid;\nvar occupied, occupiedArray;\nvar numTilesX, numTilesY;\nvar x, y, y2, x2, x3, y3, lastX, lastY;\nvar width, height;\n\ngrid = this.getNavGrid().grid;\noccupiedArray = [];\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n occupiedArray[y] = [];\n for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n {\n occupiedArray[y][x] = (grid[y][x].length > 0);\n }\n}\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n {\n if(!occupiedArray[y][x])\n {\n //Check width of rectangle\n lastX = x;\n y2 = y;\n numTilesX = 0;\n var okay = true;\n for(x2 = x; okay &&x2 + tileSize < grid[y].length; x2 += tileSize)\n {\n if(occupiedArray[y2][x2])\n {\n okay = false;\n //x2 = grid[y].length;\n }\n else\n {\n lastX = x2;\n numTilesX++;\n }\n }\n\n // Check height of rectangle\n lastY = y;\n x2 = x;\n numTilesY = 0;\n okay = true;\n for(y2 = y; okay && y2 + tileSize < grid.length; y2 += tileSize)\n {\n var okay2 = true;\n for(x3 = x; okay2 && x3 <= lastX; x3 += tileSize)\n {\n occupied = occupiedArray[y2][x3];\n if(occupied)\n {\n okay2 = false;\n //x3 = grid[y].length;\n }\n }\n if(occupied)\n {\n okay = false;\n //y2 = grid.length;\n }\n else\n {\n lastY = y2;\n numTilesY++;\n }\n }\n\n for(y3 = y; y3 <= lastY; y3 += tileSize) \n {\n for(x3 = x; x3 <= lastX; x3 += tileSize)\n {\n occupiedArray[y3][x3] = true;\n }\n }\n \n width = numTilesX * tileSize;\n height = numTilesY * tileSize;\n this.addRect( x + (width / 2), y + (height / 2), width, height);\n \n this.wait(); // Hover over the timeline to help debug!\n } \n }\n}\n*/\n\n\n/*\nvar todoGrid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar yGridSize = todoGrid.length;\nvar xGridSize = todoGrid[0].length;\nvar x, y;\n//store all tiles which actually need to be filled\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n todoGrid[y][x] = todoGrid[y][x].length === 0;\n }\n}\n\n//determine how many tiles to fill\nvar todoAnz = 0;\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n if(todoGrid[y][x]) {\n todoAnz++;\n }\n }\n}\n\n//fill all tiles from biggest to smallest rectangle possible\nwhile(todoAnz > 0) {\n var biggestLeftX, biggestLeftY, biggestRightX, biggestRightY, tmpX, tmpY;\n var bigRect = 0;\n for(y = 0; y + tileSize < yGridSize; y += tileSize) {\n for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n if(todoGrid[y][x]) {\n var width = 1, height = 1;\n while(todoGrid[y][x + width * tileSize] && x + width * tileSize + tileSize < xGridSize) {\n width++;\n }\n var higher = true;\n while(higher) {\n for(tmpX = x; tmpX < x + tileSize * width; tmpX += tileSize)\n if(!todoGrid[y + height * tileSize][tmpX] || y + height * tileSize + tileSize >= yGridSize) higher = false;\n if(higher) height++;\n }\n if(width * height > bigRect) {\n bigRect = width * height;\n biggestLeftX = x;\n biggestLeftY = y;\n biggestRightX = x + width * tileSize;\n biggestRightY = y + height * tileSize;\n }\n }\n }\n}\nfor(tmpY = biggestLeftY; tmpY < biggestRightY; tmpY += tileSize)\n for(tmpX = biggestLeftX; tmpX < biggestRightX; tmpX += tileSize)\n todoGrid[tmpY][tmpX] = false;\n this.addRect( (biggestLeftX + biggestRightX) / 2,\n (biggestLeftY + biggestRightY) / 2,\n biggestRightX - biggestLeftX,\n biggestRightY - biggestLeftY );\n this.wait(0.2);\n todoAnz -= bigRect;\n // this.say(\"Found a \"+bigRect+\" tile Rectangle, \"+todoAnz+\" tile(s) left\");\n}\n// André\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n for(var x = 0; x + tileSize < grid[0].length; ) {\n\n var occupied = grid[y][x].length > 0;\n\n if (!occupied) {\n for (var i = 0; i < this.spawnedRectangles.length; ++i) {\n var rect = this.spawnedRectangles[i];\n if (rect.pos.x - rect.width / 2 <= x && x <= rect.pos.x + rect.width / 2 \n && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n occupied = true;\n }\n }\n\n if(!occupied) {\n var x2 = x, y2 = y;\n while (x2 < grid[0].length-1 && grid[y][x2+tileSize].length===0)\n x2 += tileSize;\n\n var ok = true;\n while (y2 + tileSize < grid.length && ok) {\n var yt = y2 + tileSize; \n for (var xt = x; xt <= x2; xt += tileSize) {\n if (grid[yt][xt].length > 0) {\n ok = false;\n }\n }\n if (x > 0 && grid[yt][x - tileSize].length === 0)\n ok = false;\n if (x2 < grid[0].length-tileSize && grid[yt][x2+tileSize].length === 0)\n ok = false;\n if (ok)\n y2 += tileSize; \n }\n\n\n this.addRect(x + tileSize / 2 + (x2-x)/2, y + tileSize / 2 + (y2-y)/2, tileSize + (x2-x), tileSize + (y2-y));\n x = x2 + tileSize;\n this.wait();\n } else {\n x += tileSize;\n }\n }\n}\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar isCounting;\nvar adyacentX;\nvar startPos;\n\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n isCounting = 0;\n adyacentX = 0;\n for(var x = 0; x + tileSize < grid[0].length; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n if(isCounting === 0)\n startPos = x;\n isCounting = 1;\n adyacentX++;\n // this.say(\"Pos(\"+x+\",\"+y+\") is occupied\");\n // this.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize);\n // this.wait(); // Hover over the timeline to help debug!\n }\n else {\n // this.say(\"Pos(\"+x+\",\"+y+\") is not occupied\");\n isCounting = 0;\n if(adyacentX > 0){\n // this.say(\"writing \" + adyacentX + \"width rectangle= \" + tileSize*adyacentX);\n this.addRect((startPos + x)/2,y+tileSize / 2,tileSize*adyacentX,tileSize);\n }\n adyacentX = 0;\n }\n }\n\n}\n\nthis.say(\"Finish!\");\n*/\n\n/*\nfunction largestRectangle(grid, bottomY, leftX, width, height) {\n var coveredRows = [];\n var shortestCoveredRow = width - leftX;\n var done = false;\n for(var y = bottomY; !done && y < height; ++y) {\n var coveredRow = 0, done2 = false;\n for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n if(!grid[y][x].length)\n ++coveredRow;\n else\n done2 = true;\n }\n if(!coveredRow)\n done = true;\n else {\n coveredRows.push(coveredRow);\n shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n }\n }\n var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n var rowLength = coveredRows[rowIndex];\n if(!shortestRow)\n shortestRow = rowLength;\n area = rowLength * (rowIndex + 1);\n if(area > maxArea) {\n maxAreaRows = rowIndex +1;\n maxAreaRowLength = shortestRow;\n maxArea = area;\n }\n shortestRow = Math.min(rowLength, shortestRow);\n }\n return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n this.addRect(rect.x, rect.y, rect.width, rect.height);\n //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \", \" + grid.length + \", \" + x + \", \" + y);\n this.wait(0.1);\n for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n grid[y2][x2] = [rect];\n }\n }\n }\n }\n}\n*/" } }, + "teamSpells": { + "humans": [ + "thoktar" + ] + }, "submitted": false, "submittedCodeLanguage": "javascript", "playtime": 302, @@ -314,6 +342,10 @@ responses = }, { "_id": "5334901f0a0f9b286f57382c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, "team": "humans", "code": { "coin-generator-9000": { @@ -329,9 +361,20 @@ responses = "chooseAction": "//this.say(\"Say, who's in charge around here?\"); // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n this.build('coin');\n// console.log(\"build coin\");\n//}" } }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, "levelID": "gold-rush", "levelName": "Gold Rush", - "totalScore": 39.33094538664242, + "totalScore": 39.23691444835561, "submitted": true, "submittedCodeLanguage": "javascript", "playtime": 1158, @@ -339,6 +382,10 @@ responses = }, { "_id": "52dea9b77e486eeb97000001", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, "levelID": "brawlwood", "levelName": "Brawlwood", "code": { @@ -391,7 +438,31 @@ responses = "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}" } }, - "totalScore": 24.004311721082228, + "totalScore": 24.138610165979667, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, "team": "humans", "submitted": true, "submittedCodeLanguage": "javascript", @@ -400,6 +471,10 @@ responses = }, { "_id": "535701331bfa9bba14b5e03d", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, "team": "ogres", "levelID": "greed", "levelName": "Greed", @@ -411,10 +486,21 @@ responses = "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array. \n// Destroy the enemy base within 120 seconds! \n// Check out the Guide at the top for more info.\n\nvar base = this;\n\nvar items = this.getItems();\nvar peons = this.getByType('peon');\n\nif(peons[0]) {\n var item = peons[0].getNearest(items);\n var index = items.indexOf(item);\n var index2 = _.indexOf(items, item);\n var index3 = items.indexOf(peons[0].getNearest(items));\n} \n\nvar friendCosts = {'munchkin': 10, 'ogre': 25, 'shaman': 40, 'fangrider': 160, 'brawler': 500};\nvar enemyCosts = {'soldier': 10, 'knight': 25, 'librarian': 40, 'griffin-rider': 60, 'captain': 100, 'peasant': -1};\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nvar ourArmyWorth = 0;\nvar theirArmyWorth = 0;\nfor(var friendIndex in friends)\n ourArmyWorth += friendCosts[friends[friendIndex].type] || 0;\n \nfor(var enemyIndex in enemies) {\n var enemy = enemies[enemyIndex];\n if(this.distance(enemy) > 32) continue;\n theirArmyWorth += (enemyCosts[enemies[enemyIndex].type] || 0 ) + 1;\n} \n \nvar type = 'peon';\nvar peons = this.getByType('peon');\nvar shamans = this.getByType('shaman', friends);\nvar nFighters = friends.length - shamans.length - peons.length;\nvar minionTypes = ['brawler', 'fangrider', 'shaman', 'ogre', 'munchkin'];\nif(this.built.length && theirArmyWorth > ourArmyWorth || this.now() > 120) {\n for(var minionIndex in minionTypes) {\n type = minionTypes[minionIndex];\n if(this.gold >= friendCosts[type] && (type != 'shaman' || nFighters))\n break;\n }\n}\nvar cost = friendCosts[type];\nif(type == 'peon') {\n cost = 50 + 10 * peons.length;\n if(peons.length >= 4)\n cost = 9001;\n}\nif (this.gold >= cost)\n this.build(type);\n \nvar getBestItem = function getBestItem(items, who, near, friends, enemies) {\n var bestValue = 0;\n var bestItem = null;\n for (var i = 0; i < items.length; ++i) {\n var item = items[i];\n var d = who.pos.distanceSquared(item.pos);\n d += who.pos.distanceSquared(near) / 5;\n var others = friends.concat(enemies); // hmm, less effective?\n //var others = friends;\n for (var j = 0; j < others.length; ++j) {\n if(others[j] == who) continue;\n var other = others[j];\n if(other.team != base.team) {\n d += 10;\n }\n else if(other.distance(item) < who.distance(item)) {\n d += 40;\n }\n }\n var value = item.bountyGold / d;\n if (value > bestValue) {\n bestItem = item;\n bestValue = value;\n }\n }\n return bestItem;\n};\n\nvar items = this.getItems();\nif(!items.length) return;\nvar ww = 85;\nvar hh = 70;\n//var hyp = Math.sqrt(ww * ww + hh * hh);\nvar centers = [\n [{x: 2 * ww / 4, y: 2 * hh / 4}],\n [{x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 2 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}],\n [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}, {x: 2 * ww / 4, y: 2 * hh / 4}]\n];\nvar peasants = this.getByType('peasant');\nfor (var i = 0; i < peons.length; ++i) {\n var minion = peons[i];\n var layoutIndex = Math.min(peons.length, centers.length) - 1;\n var layout = centers[layoutIndex];\n var center = layout[i % layout.length];\n var item = getBestItem(items, minion, center, peons, peasants);\n this.command(minion, 'move', item.pos);\n}\n\n//this.say(\"Your investors overpaid! \" + ourArmyWorth + \" vs. \" + theirArmyWorth);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': Mythically expensive super unit.\n// See the buildables documentation below for costs and the guide for more info.e" }, "human-base": { - "chooseAction": ".......;" + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var alliedTypes, enemyTypes, tmp, maxkey, filterType, filterNotType, lerp, clamp, remove, removeIndex, valueFighter, valuateFighters, computeMinDistances, computeEnemyMult, computeAttractionSquared, computeSpringAssignments, items, friends, enemies, enemyBase, enemyGold, peasants, peons, assignments, i, as, createRegressionFunc, estimateVariance, estimateHighLow, militaryFriends, friendlySoldiers, militaryEnemies, nearestEnemy, PREDICTOR_HISTORY_LENGTH, PREDICTOR_SAMPLE_INTERVAL, PREDICTOR_LOOKAHEAD_TIME, enemyTotalWorth, ourMilitaryStrength, enemyMilitaryStrength, ourStrength, enemyStrength, enemyStrengthForecast, highLowE, futureEnemyBonus, doNothingState, collectState, pokeState, stockpileState, decideMilitaryToBuild, attackState, defendState, states, type, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp64, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185, tmp186, tmp187, tmp190, tmp191, tmp192, tmp229, tmp230, tmp231, tmp248, tmp249, tmp250, tmp263, tmp264, tmp265, tmp290, tmp291, tmp292, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 749, row: 30, col: 0}, {ofs: 1054, row: 43, col: 1}]); maxkey = function (f, arr) {\n var winner, winScore, i, elem, score, tmp371, tmp372, tmp373, tmp374, tmp375, tmp376, tmp377, tmp378, tmp379, tmp380, tmp381, tmp382, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392; f = _aether.createAPIClone(_aether, f); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 779, row: 31, col: 4}, {ofs: 797, row: 31, col: 22}]); winner = null; _aether.logStatement([{ofs: 779, row: 31, col: 4}, {ofs: 797, row: 31, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 818, row: 32, col: 20}, {ofs: 823, row: 32, col: 25}]); tmp371 = 10000; _aether.logStatement([{ofs: 818, row: 32, col: 20}, {ofs: 823, row: 32, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 802, row: 32, col: 4}, {ofs: 824, row: 32, col: 26}]); winScore = -tmp371; _aether.logStatement([{ofs: 802, row: 32, col: 4}, {ofs: 824, row: 32, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 834, row: 33, col: 9}, {ofs: 843, row: 33, col: 18}]); i = 0; _aether.logStatement([{ofs: 834, row: 33, col: 9}, {ofs: 843, row: 33, col: 18}], _aether._userInfo, false);\n tmp373 = i;\n tmp375 = arr;\n tmp376 = 'length';\n _aether.logStatementStart([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}]); tmp374 = tmp375[tmp376]; _aether.logStatement([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}]); tmp372 = tmp373 < tmp374; _aether.logStatement([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n tmp383: {\n while (tmp372) {\n tmp384: {\n tmp385 = arr;\n tmp386 = i;\n _aether.logStatementStart([{ofs: 876, row: 34, col: 8}, {ofs: 894, row: 34, col: 26}]); elem = tmp385[tmp386]; _aether.logStatement([{ofs: 876, row: 34, col: 8}, {ofs: 894, row: 34, col: 26}], _aether._userInfo, false);\n tmp387 = f;\n tmp388 = elem;\n _aether.logStatementStart([{ofs: 903, row: 35, col: 8}, {ofs: 923, row: 35, col: 28}]); score = _aether.createAPIClone(_aether, tmp387(_aether.restoreAPIClone(_aether, tmp388))); _aether.logStatement([{ofs: 903, row: 35, col: 8}, {ofs: 923, row: 35, col: 28}], _aether._userInfo, false);\n tmp390 = score;\n tmp391 = winScore;\n _aether.logStatementStart([{ofs: 936, row: 36, col: 12}, {ofs: 952, row: 36, col: 28}]); tmp389 = tmp390 > tmp391; _aether.logStatement([{ofs: 936, row: 36, col: 12}, {ofs: 952, row: 36, col: 28}], _aether._userInfo, false);\n if (tmp389) {\n winner = elem;\n winScore = score;\n } else {\n ;\n }\n }\n tmp381 = i;\n tmp382 = 1;\n i = tmp381 + tmp382;\n tmp377 = i;\n tmp379 = arr;\n tmp380 = 'length';\n _aether.logStatementStart([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}]); tmp378 = tmp379[tmp380]; _aether.logStatement([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}]); tmp372 = tmp377 < tmp378; _aether.logStatement([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n }\n }\n tmp392 = winner;\n return _aether.restoreAPIClone(_aether, tmp392);\n }; _aether.logStatement([{ofs: 749, row: 30, col: 0}, {ofs: 1054, row: 43, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1122, row: 46, col: 0}, {ofs: 1225, row: 48, col: 1}]); filterType = function (type, arr) {\n var tmp393, tmp394, tmp395, tmp396, tmp397; type = _aether.createAPIClone(_aether, type); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp394 = arr;\n tmp395 = 'filter';\n _aether.logStatementStart([{ofs: 1177, row: 47, col: 22}, {ofs: 1216, row: 47, col: 61}]); tmp396 = function (x) {\n var tmp398, tmp399, tmp400, tmp401, tmp402; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp401 = x;\n tmp402 = 'type';\n _aether.logStatementStart([{ofs: 1198, row: 47, col: 43}, {ofs: 1204, row: 47, col: 49}]); tmp399 = tmp401[tmp402]; _aether.logStatement([{ofs: 1198, row: 47, col: 43}, {ofs: 1204, row: 47, col: 49}], _aether._userInfo, false);\n tmp400 = type;\n _aether.logStatementStart([{ofs: 1198, row: 47, col: 43}, {ofs: 1213, row: 47, col: 58}]); tmp398 = tmp399 === tmp400; _aether.logStatement([{ofs: 1198, row: 47, col: 43}, {ofs: 1213, row: 47, col: 58}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp398);\n }; _aether.logStatement([{ofs: 1177, row: 47, col: 22}, {ofs: 1216, row: 47, col: 61}], _aether._userInfo, false);\n tmp397 = arr;\n _aether.logStatementStart([{ofs: 1166, row: 47, col: 11}, {ofs: 1222, row: 47, col: 67}]); tmp393 = _aether.createAPIClone(_aether, tmp394[tmp395](_aether.restoreAPIClone(_aether, tmp396), _aether.restoreAPIClone(_aether, tmp397))); _aether.logStatement([{ofs: 1166, row: 47, col: 11}, {ofs: 1222, row: 47, col: 67}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp393);\n }; _aether.logStatement([{ofs: 1122, row: 46, col: 0}, {ofs: 1225, row: 48, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1291, row: 51, col: 0}, {ofs: 1397, row: 53, col: 1}]); filterNotType = function (type, arr) {\n var tmp403, tmp404, tmp405, tmp406, tmp407; type = _aether.createAPIClone(_aether, type); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp404 = arr;\n tmp405 = 'filter';\n _aether.logStatementStart([{ofs: 1349, row: 52, col: 22}, {ofs: 1388, row: 52, col: 61}]); tmp406 = function (x) {\n var tmp408, tmp409, tmp410, tmp411, tmp412; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp411 = x;\n tmp412 = 'type';\n _aether.logStatementStart([{ofs: 1370, row: 52, col: 43}, {ofs: 1376, row: 52, col: 49}]); tmp409 = tmp411[tmp412]; _aether.logStatement([{ofs: 1370, row: 52, col: 43}, {ofs: 1376, row: 52, col: 49}], _aether._userInfo, false);\n tmp410 = type;\n _aether.logStatementStart([{ofs: 1370, row: 52, col: 43}, {ofs: 1385, row: 52, col: 58}]); tmp408 = tmp409 !== tmp410; _aether.logStatement([{ofs: 1370, row: 52, col: 43}, {ofs: 1385, row: 52, col: 58}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp408);\n }; _aether.logStatement([{ofs: 1349, row: 52, col: 22}, {ofs: 1388, row: 52, col: 61}], _aether._userInfo, false);\n tmp407 = arr;\n _aether.logStatementStart([{ofs: 1338, row: 52, col: 11}, {ofs: 1394, row: 52, col: 67}]); tmp403 = _aether.createAPIClone(_aether, tmp404[tmp405](_aether.restoreAPIClone(_aether, tmp406), _aether.restoreAPIClone(_aether, tmp407))); _aether.logStatement([{ofs: 1338, row: 52, col: 11}, {ofs: 1394, row: 52, col: 67}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp403);\n }; _aether.logStatement([{ofs: 1291, row: 51, col: 0}, {ofs: 1397, row: 53, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1532, row: 57, col: 0}, {ofs: 1610, row: 59, col: 1}]); lerp = function (start, end, frac) {\n var tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419; start = _aether.createAPIClone(_aether, start); end = _aether.createAPIClone(_aether, end); frac = _aether.createAPIClone(_aether, frac); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp414 = start;\n tmp418 = end;\n tmp419 = start;\n _aether.logStatementStart([{ofs: 1587, row: 58, col: 21}, {ofs: 1598, row: 58, col: 32}]); tmp416 = tmp418 - tmp419; _aether.logStatement([{ofs: 1587, row: 58, col: 21}, {ofs: 1598, row: 58, col: 32}], _aether._userInfo, false);\n tmp417 = frac;\n _aether.logStatementStart([{ofs: 1586, row: 58, col: 20}, {ofs: 1606, row: 58, col: 40}]); tmp415 = tmp416 * tmp417; _aether.logStatement([{ofs: 1586, row: 58, col: 20}, {ofs: 1606, row: 58, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1577, row: 58, col: 11}, {ofs: 1607, row: 58, col: 41}]); tmp413 = tmp414 + tmp415; _aether.logStatement([{ofs: 1577, row: 58, col: 11}, {ofs: 1607, row: 58, col: 41}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp413);\n }; _aether.logStatement([{ofs: 1532, row: 57, col: 0}, {ofs: 1610, row: 59, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1612, row: 61, col: 0}, {ofs: 1693, row: 63, col: 1}]); clamp = function (val, low, high) {\n var tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427, tmp428, tmp429, tmp430; val = _aether.createAPIClone(_aether, val); low = _aether.createAPIClone(_aether, low); high = _aether.createAPIClone(_aether, high); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp423 = 'Math';\n tmp421 = __global[tmp423];\n tmp422 = 'max';\n tmp428 = 'Math';\n tmp426 = __global[tmp428];\n tmp427 = 'min';\n tmp429 = val;\n tmp430 = high;\n _aether.logStatementStart([{ofs: 1665, row: 62, col: 20}, {ofs: 1684, row: 62, col: 39}]); tmp424 = _aether.createAPIClone(_aether, tmp426[tmp427](_aether.restoreAPIClone(_aether, tmp429), _aether.restoreAPIClone(_aether, tmp430))); _aether.logStatement([{ofs: 1665, row: 62, col: 20}, {ofs: 1684, row: 62, col: 39}], _aether._userInfo, false);\n tmp425 = low;\n _aether.logStatementStart([{ofs: 1656, row: 62, col: 11}, {ofs: 1690, row: 62, col: 45}]); tmp420 = _aether.createAPIClone(_aether, tmp421[tmp422](_aether.restoreAPIClone(_aether, tmp424), _aether.restoreAPIClone(_aether, tmp425))); _aether.logStatement([{ofs: 1656, row: 62, col: 11}, {ofs: 1690, row: 62, col: 45}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp420);\n }; _aether.logStatement([{ofs: 1612, row: 61, col: 0}, {ofs: 1693, row: 63, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1751, row: 66, col: 0}, {ofs: 1829, row: 68, col: 1}]); remove = function (elem, arr) {\n var tmp431, tmp432, tmp433, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440; elem = _aether.createAPIClone(_aether, elem); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp434 = arr;\n tmp435 = 'splice';\n tmp438 = arr;\n tmp439 = 'indexOf';\n tmp440 = elem;\n _aether.logStatementStart([{ofs: 1802, row: 67, col: 22}, {ofs: 1819, row: 67, col: 39}]); tmp436 = _aether.createAPIClone(_aether, tmp438[tmp439](_aether.restoreAPIClone(_aether, tmp440))); _aether.logStatement([{ofs: 1802, row: 67, col: 22}, {ofs: 1819, row: 67, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1821, row: 67, col: 41}, {ofs: 1822, row: 67, col: 42}]); tmp437 = 1; _aether.logStatement([{ofs: 1821, row: 67, col: 41}, {ofs: 1822, row: 67, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1791, row: 67, col: 11}, {ofs: 1823, row: 67, col: 43}]); tmp432 = _aether.createAPIClone(_aether, tmp434[tmp435](_aether.restoreAPIClone(_aether, tmp436), _aether.restoreAPIClone(_aether, tmp437))); _aether.logStatement([{ofs: 1791, row: 67, col: 11}, {ofs: 1823, row: 67, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1824, row: 67, col: 44}, {ofs: 1825, row: 67, col: 45}]); tmp433 = 0; _aether.logStatement([{ofs: 1824, row: 67, col: 44}, {ofs: 1825, row: 67, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1791, row: 67, col: 11}, {ofs: 1826, row: 67, col: 46}]); tmp431 = tmp432[tmp433]; _aether.logStatement([{ofs: 1791, row: 67, col: 11}, {ofs: 1826, row: 67, col: 46}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp431);\n }; _aether.logStatement([{ofs: 1751, row: 66, col: 0}, {ofs: 1829, row: 68, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1900, row: 71, col: 0}, {ofs: 1964, row: 73, col: 1}]); removeIndex = function (i, arr) {\n var tmp441, tmp442, tmp443, tmp444, tmp445, tmp446, tmp447; i = _aether.createAPIClone(_aether, i); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp444 = arr;\n tmp445 = 'splice';\n tmp446 = i;\n _aether.logStatementStart([{ofs: 1956, row: 72, col: 25}, {ofs: 1957, row: 72, col: 26}]); tmp447 = 1; _aether.logStatement([{ofs: 1956, row: 72, col: 25}, {ofs: 1957, row: 72, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1942, row: 72, col: 11}, {ofs: 1958, row: 72, col: 27}]); tmp442 = _aether.createAPIClone(_aether, tmp444[tmp445](_aether.restoreAPIClone(_aether, tmp446), _aether.restoreAPIClone(_aether, tmp447))); _aether.logStatement([{ofs: 1942, row: 72, col: 11}, {ofs: 1958, row: 72, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1959, row: 72, col: 28}, {ofs: 1960, row: 72, col: 29}]); tmp443 = 0; _aether.logStatement([{ofs: 1959, row: 72, col: 28}, {ofs: 1960, row: 72, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1942, row: 72, col: 11}, {ofs: 1961, row: 72, col: 30}]); tmp441 = tmp442[tmp443]; _aether.logStatement([{ofs: 1942, row: 72, col: 11}, {ofs: 1961, row: 72, col: 30}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp441);\n }; _aether.logStatement([{ofs: 1900, row: 71, col: 0}, {ofs: 1964, row: 73, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2109, row: 78, col: 0}, {ofs: 2639, row: 101, col: 1}]); valueFighter = function (type) {\n var tmp448, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485, tmp486, tmp487, tmp488; type = _aether.createAPIClone(_aether, type); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp448 = type;\n tmp449: {\n _aether.logStatementStart([{ofs: 2172, row: 80, col: 13}, {ofs: 2182, row: 80, col: 23}]); tmp486 = 'munchkin'; _aether.logStatement([{ofs: 2172, row: 80, col: 13}, {ofs: 2182, row: 80, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp487 = tmp448 === tmp486; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp487) {\n _aether.logStatementStart([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}]); tmp488 = 10; _aether.logStatement([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp488);\n } else {\n _aether.logStatementStart([{ofs: 2197, row: 81, col: 13}, {ofs: 2206, row: 81, col: 22}]); tmp483 = 'soldier'; _aether.logStatement([{ofs: 2197, row: 81, col: 13}, {ofs: 2206, row: 81, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp484 = tmp448 === tmp483; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp484) {\n _aether.logStatementStart([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}]); tmp485 = 10; _aether.logStatement([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp485);\n } else {\n _aether.logStatementStart([{ofs: 2244, row: 83, col: 13}, {ofs: 2252, row: 83, col: 21}]); tmp480 = 'knight'; _aether.logStatement([{ofs: 2244, row: 83, col: 13}, {ofs: 2252, row: 83, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp481 = tmp448 === tmp480; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp481) {\n _aether.logStatementStart([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}]); tmp482 = 25; _aether.logStatement([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp482);\n } else {\n _aether.logStatementStart([{ofs: 2267, row: 84, col: 13}, {ofs: 2273, row: 84, col: 19}]); tmp477 = 'ogre'; _aether.logStatement([{ofs: 2267, row: 84, col: 13}, {ofs: 2273, row: 84, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp478 = tmp448 === tmp477; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp478) {\n _aether.logStatementStart([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}]); tmp479 = 25; _aether.logStatement([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp479);\n } else {\n _aether.logStatementStart([{ofs: 2311, row: 86, col: 13}, {ofs: 2322, row: 86, col: 24}]); tmp474 = 'librarian'; _aether.logStatement([{ofs: 2311, row: 86, col: 13}, {ofs: 2322, row: 86, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp475 = tmp448 === tmp474; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp475) {\n _aether.logStatementStart([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}]); tmp476 = 40; _aether.logStatement([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp476);\n } else {\n _aether.logStatementStart([{ofs: 2337, row: 87, col: 13}, {ofs: 2345, row: 87, col: 21}]); tmp471 = 'shaman'; _aether.logStatement([{ofs: 2337, row: 87, col: 13}, {ofs: 2345, row: 87, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp472 = tmp448 === tmp471; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp472) {\n _aether.logStatementStart([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}]); tmp473 = 40; _aether.logStatement([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp473);\n } else {\n _aether.logStatementStart([{ofs: 2383, row: 89, col: 13}, {ofs: 2398, row: 89, col: 28}]); tmp468 = 'griffin-rider'; _aether.logStatement([{ofs: 2383, row: 89, col: 13}, {ofs: 2398, row: 89, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp469 = tmp448 === tmp468; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp469) {\n _aether.logStatementStart([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}]); tmp470 = 60; _aether.logStatement([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp470);\n } else {\n _aether.logStatementStart([{ofs: 2413, row: 90, col: 13}, {ofs: 2424, row: 90, col: 24}]); tmp465 = 'fangrider'; _aether.logStatement([{ofs: 2413, row: 90, col: 13}, {ofs: 2424, row: 90, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp466 = tmp448 === tmp465; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp466) {\n _aether.logStatementStart([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}]); tmp467 = 60; _aether.logStatement([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp467);\n } else {\n _aether.logStatementStart([{ofs: 2462, row: 92, col: 13}, {ofs: 2471, row: 92, col: 22}]); tmp462 = 'captain'; _aether.logStatement([{ofs: 2462, row: 92, col: 13}, {ofs: 2471, row: 92, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp463 = tmp448 === tmp462; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp463) {\n _aether.logStatementStart([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}]); tmp464 = 100; _aether.logStatement([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp464);\n } else {\n _aether.logStatementStart([{ofs: 2486, row: 93, col: 13}, {ofs: 2495, row: 93, col: 22}]); tmp459 = 'brawler'; _aether.logStatement([{ofs: 2486, row: 93, col: 13}, {ofs: 2495, row: 93, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp460 = tmp448 === tmp459; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp460) {\n _aether.logStatementStart([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}]); tmp461 = 100; _aether.logStatement([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp461);\n } else {\n _aether.logStatementStart([{ofs: 2534, row: 95, col: 13}, {ofs: 2540, row: 95, col: 19}]); tmp456 = 'base'; _aether.logStatement([{ofs: 2534, row: 95, col: 13}, {ofs: 2540, row: 95, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp457 = tmp448 === tmp456; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp457) {\n _aether.logStatementStart([{ofs: 2561, row: 96, col: 19}, {ofs: 2562, row: 96, col: 20}]); tmp458 = 0; _aether.logStatement([{ofs: 2561, row: 96, col: 19}, {ofs: 2562, row: 96, col: 20}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp458);\n } else {\n _aether.logStatementStart([{ofs: 2577, row: 97, col: 13}, {ofs: 2586, row: 97, col: 22}]); tmp453 = 'peasant'; _aether.logStatement([{ofs: 2577, row: 97, col: 13}, {ofs: 2586, row: 97, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp454 = tmp448 === tmp453; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp454) {\n _aether.logStatementStart([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}]); tmp455 = 50; _aether.logStatement([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp455);\n } else {\n _aether.logStatementStart([{ofs: 2601, row: 98, col: 13}, {ofs: 2607, row: 98, col: 19}]); tmp450 = 'peon'; _aether.logStatement([{ofs: 2601, row: 98, col: 13}, {ofs: 2607, row: 98, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp451 = tmp448 === tmp450; _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n if (tmp451) {\n _aether.logStatementStart([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}]); tmp452 = 50; _aether.logStatement([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp452);\n } else {\n ;\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n return;\n }; _aether.logStatement([{ofs: 2109, row: 78, col: 0}, {ofs: 2639, row: 101, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2715, row: 104, col: 0}, {ofs: 2909, row: 111, col: 1}]); valuateFighters = function (fighters) {\n var score, i, len, tmp489, tmp490, tmp491, tmp492, tmp493, tmp494, tmp495, tmp496, tmp497, tmp500, tmp501, tmp502, tmp503, tmp504, tmp505, tmp506, tmp507, tmp508, tmp509; fighters = _aether.createAPIClone(_aether, fighters); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 2756, row: 105, col: 4}, {ofs: 2770, row: 105, col: 18}]); score = 0; _aether.logStatement([{ofs: 2756, row: 105, col: 4}, {ofs: 2770, row: 105, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}]); i = 0; _aether.logStatement([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}], _aether._userInfo, false);\n tmp489 = fighters;\n tmp490 = 'length';\n _aether.logStatementStart([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}]); len = tmp489[tmp490]; _aether.logStatement([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}], _aether._userInfo, false);\n tmp492 = i;\n tmp493 = len;\n _aether.logStatementStart([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}]); tmp491 = tmp492 < tmp493; _aether.logStatement([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}], _aether._userInfo, false);\n tmp498: {\n while (tmp491) {\n tmp499: {\n tmp501 = valueFighter;\n tmp505 = fighters;\n tmp506 = i;\n _aether.logStatementStart([{ofs: 2860, row: 107, col: 30}, {ofs: 2871, row: 107, col: 41}]); tmp503 = tmp505[tmp506]; _aether.logStatement([{ofs: 2860, row: 107, col: 30}, {ofs: 2871, row: 107, col: 41}], _aether._userInfo, false);\n tmp504 = 'type';\n _aether.logStatementStart([{ofs: 2860, row: 107, col: 30}, {ofs: 2876, row: 107, col: 46}]); tmp502 = tmp503[tmp504]; _aether.logStatement([{ofs: 2860, row: 107, col: 30}, {ofs: 2876, row: 107, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2838, row: 107, col: 8}, {ofs: 2878, row: 107, col: 48}]); tmp500 = _aether.createAPIClone(_aether, tmp501(_aether.restoreAPIClone(_aether, tmp502))); _aether.logStatement([{ofs: 2838, row: 107, col: 8}, {ofs: 2878, row: 107, col: 48}], _aether._userInfo, false);\n tmp507 = score;\n tmp508 = tmp500;\n score = tmp507 + tmp508;\n }\n tmp496 = i;\n tmp497 = 1;\n i = tmp496 + tmp497;\n tmp494 = i;\n tmp495 = len;\n _aether.logStatementStart([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}]); tmp491 = tmp494 < tmp495; _aether.logStatement([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}], _aether._userInfo, false);\n }\n }\n tmp509 = score;\n return _aether.restoreAPIClone(_aether, tmp509);\n }; _aether.logStatement([{ofs: 2715, row: 104, col: 0}, {ofs: 2909, row: 111, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2993, row: 115, col: 0}, {ofs: 3452, row: 132, col: 1}]); computeMinDistances = function (peasants, coins) {\n var dict, i, len, coin, winScore, j, pLen, dist, tmp510, tmp511, tmp512, tmp513, tmp514, tmp515, tmp516, tmp517, tmp518, tmp521, tmp522, tmp523, tmp524, tmp525, tmp526, tmp527, tmp528, tmp529, tmp530, tmp531, tmp534, tmp535, tmp536, tmp537, tmp538, tmp539, tmp540, tmp541, tmp542, tmp543, tmp544, tmp545, tmp546, tmp547, tmp548, tmp549, tmp550, tmp551; peasants = _aether.createAPIClone(_aether, peasants); coins = _aether.createAPIClone(_aether, coins); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 3045, row: 116, col: 4}, {ofs: 3059, row: 116, col: 18}]); dict = {}; _aether.logStatement([{ofs: 3045, row: 116, col: 4}, {ofs: 3059, row: 116, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}]); i = 0; _aether.logStatement([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}], _aether._userInfo, false);\n tmp510 = coins;\n tmp511 = 'length';\n _aether.logStatementStart([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}]); len = tmp510[tmp511]; _aether.logStatement([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}], _aether._userInfo, false);\n tmp513 = i;\n tmp514 = len;\n _aether.logStatementStart([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}]); tmp512 = tmp513 < tmp514; _aether.logStatement([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}], _aether._userInfo, false);\n tmp519: {\n while (tmp512) {\n tmp520: {\n tmp521 = coins;\n tmp522 = i;\n _aether.logStatementStart([{ofs: 3125, row: 119, col: 8}, {ofs: 3145, row: 119, col: 28}]); coin = tmp521[tmp522]; _aether.logStatement([{ofs: 3125, row: 119, col: 8}, {ofs: 3145, row: 119, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3154, row: 120, col: 8}, {ofs: 3175, row: 120, col: 29}]); winScore = 10000; _aether.logStatement([{ofs: 3154, row: 120, col: 8}, {ofs: 3175, row: 120, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}]); j = 0; _aether.logStatement([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}], _aether._userInfo, false);\n tmp523 = peasants;\n tmp524 = 'length';\n _aether.logStatementStart([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}]); pLen = tmp523[tmp524]; _aether.logStatement([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}], _aether._userInfo, false);\n tmp526 = j;\n tmp527 = pLen;\n _aether.logStatementStart([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}]); tmp525 = tmp526 < tmp527; _aether.logStatement([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}], _aether._userInfo, false);\n tmp532: {\n while (tmp525) {\n tmp533: {\n tmp536 = coin;\n tmp537 = 'pos';\n _aether.logStatementStart([{ofs: 3264, row: 122, col: 23}, {ofs: 3272, row: 122, col: 31}]); tmp534 = tmp536[tmp537]; _aether.logStatement([{ofs: 3264, row: 122, col: 23}, {ofs: 3272, row: 122, col: 31}], _aether._userInfo, false);\n tmp535 = 'distance';\n tmp541 = peasants;\n tmp542 = j;\n _aether.logStatementStart([{ofs: 3282, row: 122, col: 41}, {ofs: 3293, row: 122, col: 52}]); tmp539 = tmp541[tmp542]; _aether.logStatement([{ofs: 3282, row: 122, col: 41}, {ofs: 3293, row: 122, col: 52}], _aether._userInfo, false);\n tmp540 = 'pos';\n _aether.logStatementStart([{ofs: 3282, row: 122, col: 41}, {ofs: 3297, row: 122, col: 56}]); tmp538 = tmp539[tmp540]; _aether.logStatement([{ofs: 3282, row: 122, col: 41}, {ofs: 3297, row: 122, col: 56}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3253, row: 122, col: 12}, {ofs: 3299, row: 122, col: 58}]); dist = _aether.createAPIClone(_aether, tmp534[tmp535](_aether.restoreAPIClone(_aether, tmp538))); _aether.logStatement([{ofs: 3253, row: 122, col: 12}, {ofs: 3299, row: 122, col: 58}], _aether._userInfo, false);\n tmp544 = dist;\n tmp545 = winScore;\n _aether.logStatementStart([{ofs: 3316, row: 123, col: 16}, {ofs: 3331, row: 123, col: 31}]); tmp543 = tmp544 < tmp545; _aether.logStatement([{ofs: 3316, row: 123, col: 16}, {ofs: 3331, row: 123, col: 31}], _aether._userInfo, false);\n if (tmp543) {\n winScore = dist;\n } else {\n ;\n }\n }\n tmp530 = j;\n tmp531 = 1;\n j = tmp530 + tmp531;\n tmp528 = j;\n tmp529 = pLen;\n _aether.logStatementStart([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}]); tmp525 = tmp528 < tmp529; _aether.logStatement([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}], _aether._userInfo, false);\n }\n }\n tmp546 = dict;\n tmp548 = coin;\n tmp549 = 'id';\n _aether.logStatementStart([{ofs: 3406, row: 128, col: 13}, {ofs: 3413, row: 128, col: 20}]); tmp547 = tmp548[tmp549]; _aether.logStatement([{ofs: 3406, row: 128, col: 13}, {ofs: 3413, row: 128, col: 20}], _aether._userInfo, false);\n tmp550 = winScore;\n _aether.logStatementStart([{ofs: 3401, row: 128, col: 8}, {ofs: 3425, row: 128, col: 32}]); tmp546[tmp547] = tmp550; _aether.logStatement([{ofs: 3401, row: 128, col: 8}, {ofs: 3425, row: 128, col: 32}], _aether._userInfo, false);\n }\n tmp517 = i;\n tmp518 = 1;\n i = tmp517 + tmp518;\n tmp515 = i;\n tmp516 = len;\n _aether.logStatementStart([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}]); tmp512 = tmp515 < tmp516; _aether.logStatement([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}], _aether._userInfo, false);\n }\n }\n tmp551 = dict;\n return _aether.restoreAPIClone(_aether, tmp551);\n }; _aether.logStatement([{ofs: 2993, row: 115, col: 0}, {ofs: 3452, row: 132, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3454, row: 134, col: 0}, {ofs: 3675, row: 141, col: 1}]); computeEnemyMult = function (ourDistance, enemyDistance) {\n var enemyDistFrac, tmp552, tmp553, tmp554, tmp555, tmp556, tmp557, tmp558, tmp559, tmp560; ourDistance = _aether.createAPIClone(_aether, ourDistance); enemyDistance = _aether.createAPIClone(_aether, enemyDistance); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp554 = ourDistance;\n tmp555 = enemyDistance;\n _aether.logStatementStart([{ofs: 3535, row: 135, col: 25}, {ofs: 3562, row: 135, col: 52}]); tmp552 = tmp554 + tmp555; _aether.logStatement([{ofs: 3535, row: 135, col: 25}, {ofs: 3562, row: 135, col: 52}], _aether._userInfo, false);\n tmp553 = enemyDistance;\n _aether.logStatementStart([{ofs: 3514, row: 135, col: 4}, {ofs: 3580, row: 135, col: 70}]); enemyDistFrac = tmp552 / tmp553; _aether.logStatement([{ofs: 3514, row: 135, col: 4}, {ofs: 3580, row: 135, col: 70}], _aether._userInfo, false);\n tmp557 = enemyDistFrac;\n _aether.logStatementStart([{ofs: 3605, row: 136, col: 24}, {ofs: 3617, row: 136, col: 36}]); tmp558 = 2.2222222222; _aether.logStatement([{ofs: 3605, row: 136, col: 24}, {ofs: 3617, row: 136, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3589, row: 136, col: 8}, {ofs: 3617, row: 136, col: 36}]); tmp556 = tmp557 > tmp558; _aether.logStatement([{ofs: 3589, row: 136, col: 8}, {ofs: 3617, row: 136, col: 36}], _aether._userInfo, false);\n if (tmp556) {\n _aether.logStatementStart([{ofs: 3636, row: 137, col: 15}, {ofs: 3639, row: 137, col: 18}]); tmp559 = 0.5; _aether.logStatement([{ofs: 3636, row: 137, col: 15}, {ofs: 3639, row: 137, col: 18}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp559);\n } else {\n ;\n }\n tmp560 = enemyDistFrac;\n return _aether.restoreAPIClone(_aether, tmp560);\n }; _aether.logStatement([{ofs: 3454, row: 134, col: 0}, {ofs: 3675, row: 141, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3677, row: 143, col: 0}, {ofs: 3988, row: 148, col: 1}]); computeAttractionSquared = function (itemPos, attractorPos, attractorMass) {\n var distance, strength, direction, tmp561, tmp562, tmp563, tmp564, tmp565, tmp566, tmp567, tmp568, tmp569, tmp570, tmp571, tmp572, tmp573, tmp574, tmp575, tmp576, tmp577, tmp578, tmp579, tmp580, tmp581, tmp582; itemPos = _aether.createAPIClone(_aether, itemPos); attractorPos = _aether.createAPIClone(_aether, attractorPos); attractorMass = _aether.createAPIClone(_aether, attractorMass); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp561 = itemPos;\n tmp562 = 'distance';\n tmp563 = attractorPos;\n _aether.logStatementStart([{ofs: 3755, row: 144, col: 4}, {ofs: 3801, row: 144, col: 50}]); distance = _aether.createAPIClone(_aether, tmp561[tmp562](_aether.restoreAPIClone(_aether, tmp563))); _aether.logStatement([{ofs: 3755, row: 144, col: 4}, {ofs: 3801, row: 144, col: 50}], _aether._userInfo, false);\n tmp564 = attractorMass;\n tmp566 = distance;\n tmp567 = distance;\n _aether.logStatementStart([{ofs: 3838, row: 145, col: 36}, {ofs: 3857, row: 145, col: 55}]); tmp565 = tmp566 * tmp567; _aether.logStatement([{ofs: 3838, row: 145, col: 36}, {ofs: 3857, row: 145, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3806, row: 145, col: 4}, {ofs: 3859, row: 145, col: 57}]); strength = tmp564 / tmp565; _aether.logStatement([{ofs: 3806, row: 145, col: 4}, {ofs: 3859, row: 145, col: 57}], _aether._userInfo, false);\n tmp570 = 'Vector';\n tmp568 = __global[tmp570];\n tmp569 = 'normalize';\n tmp574 = 'Vector';\n tmp572 = __global[tmp574];\n tmp573 = 'subtract';\n tmp575 = attractorPos;\n tmp576 = itemPos;\n _aether.logStatementStart([{ofs: 3897, row: 146, col: 37}, {ofs: 3935, row: 146, col: 75}]); tmp571 = _aether.createAPIClone(_aether, tmp572[tmp573](_aether.restoreAPIClone(_aether, tmp575), _aether.restoreAPIClone(_aether, tmp576))); _aether.logStatement([{ofs: 3897, row: 146, col: 37}, {ofs: 3935, row: 146, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3864, row: 146, col: 4}, {ofs: 3937, row: 146, col: 77}]); direction = _aether.createAPIClone(_aether, tmp568[tmp569](_aether.restoreAPIClone(_aether, tmp571))); _aether.logStatement([{ofs: 3864, row: 146, col: 4}, {ofs: 3937, row: 146, col: 77}], _aether._userInfo, false);\n tmp580 = 'Vector';\n tmp578 = __global[tmp580];\n tmp579 = 'multiply';\n tmp581 = direction;\n tmp582 = strength;\n _aether.logStatementStart([{ofs: 3949, row: 147, col: 11}, {ofs: 3985, row: 147, col: 47}]); tmp577 = _aether.createAPIClone(_aether, tmp578[tmp579](_aether.restoreAPIClone(_aether, tmp581), _aether.restoreAPIClone(_aether, tmp582))); _aether.logStatement([{ofs: 3949, row: 147, col: 11}, {ofs: 3985, row: 147, col: 47}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp577);\n }; _aether.logStatement([{ofs: 3677, row: 143, col: 0}, {ofs: 3988, row: 148, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3990, row: 150, col: 0}, {ofs: 6161, row: 202, col: 1}]); computeSpringAssignments = function (friends, enemies, coins, computeAttraction) {\n var WALL_ATTRACTION, FRIEND_ATTRACTION, DIRECTION_CASTAHEAD, ARENA_WIDTH, ARENA_HEIGHT, limits, assignments, i, fLen, friend, friendPos, force, j, cLen, coin, coinPos, dist, enemyDist, strength, direction, k, newPos, tmp583, tmp584, tmp585, tmp586, tmp587, tmp588, tmp589, tmp590, tmp591, tmp592, tmp593, tmp594, tmp595, tmp596, tmp599, tmp600, tmp601, tmp602, tmp603, tmp604, tmp605, tmp606, tmp607, tmp608, tmp609, tmp610, tmp611, tmp612, tmp613, tmp614, tmp615, tmp618, tmp619, tmp620, tmp621, tmp622, tmp623, tmp624, tmp625, tmp626, tmp627, tmp628, tmp629, tmp630, tmp631, tmp632, tmp633, tmp634, tmp635, tmp636, tmp637, tmp638, tmp639, tmp640, tmp641, tmp642, tmp643, tmp644, tmp645, tmp646, tmp647, tmp648, tmp649, tmp650, tmp651, tmp652, tmp653, tmp654, tmp655, tmp656, tmp657, tmp658, tmp659, tmp660, tmp661, tmp662, tmp663, tmp664, tmp665, tmp668, tmp669, tmp670, tmp671, tmp672, tmp673, tmp674, tmp675, tmp676, tmp677, tmp678, tmp679, tmp680, tmp681, tmp682, tmp683, tmp684, tmp685, tmp686, tmp687, tmp688, tmp689, tmp690, tmp691, tmp692, tmp693, tmp694, tmp695, tmp696, tmp697, tmp698, tmp699, tmp700, tmp701, tmp702, tmp703, tmp704, tmp705, tmp706, tmp707, tmp708, tmp709, tmp710, tmp711, tmp712, tmp713, tmp714, tmp715, tmp716, tmp717, tmp718, tmp719, tmp720, tmp721, tmp722, tmp723, tmp724, tmp725, tmp726, tmp727, tmp728, tmp729, tmp730, tmp731, tmp732, tmp733, tmp734, tmp735, tmp736, tmp737, tmp738, tmp739, tmp740, tmp741, tmp742, tmp743, tmp744, tmp745, tmp746, tmp747, tmp748, tmp749, tmp750, tmp751, tmp752, tmp753, tmp754, tmp755, tmp756, tmp757, tmp758, tmp759, tmp760, tmp761, tmp762, tmp763, tmp764, tmp765, tmp766, tmp767, tmp768, tmp769, tmp770, tmp771, tmp772, tmp773, tmp774, tmp775, tmp776, tmp777, tmp778, tmp779, tmp780, tmp781, tmp782, tmp783, tmp784, tmp785, tmp786, tmp787, tmp788, tmp789, tmp790, tmp791, tmp792, tmp793, tmp794, tmp795, tmp796, tmp797, tmp798; friends = _aether.createAPIClone(_aether, friends); enemies = _aether.createAPIClone(_aether, enemies); coins = _aether.createAPIClone(_aether, coins); computeAttraction = _aether.createAPIClone(_aether, computeAttraction); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 4097, row: 151, col: 27}, {ofs: 4098, row: 151, col: 28}]); tmp583 = 1; _aether.logStatement([{ofs: 4097, row: 151, col: 27}, {ofs: 4098, row: 151, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4074, row: 151, col: 4}, {ofs: 4099, row: 151, col: 29}]); WALL_ATTRACTION = -tmp583; _aether.logStatement([{ofs: 4074, row: 151, col: 4}, {ofs: 4099, row: 151, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4129, row: 152, col: 29}, {ofs: 4130, row: 152, col: 30}]); tmp584 = 5; _aether.logStatement([{ofs: 4129, row: 152, col: 29}, {ofs: 4130, row: 152, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4104, row: 152, col: 4}, {ofs: 4131, row: 152, col: 31}]); FRIEND_ATTRACTION = -tmp584; _aether.logStatement([{ofs: 4104, row: 152, col: 4}, {ofs: 4131, row: 152, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4137, row: 154, col: 4}, {ofs: 4165, row: 154, col: 32}]); DIRECTION_CASTAHEAD = 6; _aether.logStatement([{ofs: 4137, row: 154, col: 4}, {ofs: 4165, row: 154, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4175, row: 156, col: 4}, {ofs: 4196, row: 156, col: 25}]); ARENA_WIDTH = 85; _aether.logStatement([{ofs: 4175, row: 156, col: 4}, {ofs: 4196, row: 156, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4201, row: 157, col: 4}, {ofs: 4223, row: 157, col: 26}]); ARENA_HEIGHT = 70; _aether.logStatement([{ofs: 4201, row: 157, col: 4}, {ofs: 4223, row: 157, col: 26}], _aether._userInfo, false);\n tmp585 = computeMinDistances;\n tmp586 = enemies;\n tmp587 = coins;\n _aether.logStatementStart([{ofs: 4233, row: 159, col: 4}, {ofs: 4282, row: 159, col: 53}]); limits = _aether.createAPIClone(_aether, tmp585(_aether.restoreAPIClone(_aether, tmp586), _aether.restoreAPIClone(_aether, tmp587))); _aether.logStatement([{ofs: 4233, row: 159, col: 4}, {ofs: 4282, row: 159, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4292, row: 161, col: 4}, {ofs: 4313, row: 161, col: 25}]); assignments = []; _aether.logStatement([{ofs: 4292, row: 161, col: 4}, {ofs: 4313, row: 161, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}]); i = 0; _aether.logStatement([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}], _aether._userInfo, false);\n tmp588 = friends;\n tmp589 = 'length';\n _aether.logStatementStart([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}]); fLen = tmp588[tmp589]; _aether.logStatement([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}], _aether._userInfo, false);\n tmp591 = i;\n tmp592 = fLen;\n _aether.logStatementStart([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}]); tmp590 = tmp591 < tmp592; _aether.logStatement([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}], _aether._userInfo, false);\n tmp597: {\n while (tmp590) {\n tmp598: {\n tmp599 = friends;\n tmp600 = i;\n _aether.logStatementStart([{ofs: 4387, row: 164, col: 8}, {ofs: 4411, row: 164, col: 32}]); friend = tmp599[tmp600]; _aether.logStatement([{ofs: 4387, row: 164, col: 8}, {ofs: 4411, row: 164, col: 32}], _aether._userInfo, false);\n tmp601 = friend;\n tmp602 = 'pos';\n _aether.logStatementStart([{ofs: 4420, row: 165, col: 8}, {ofs: 4447, row: 165, col: 35}]); friendPos = tmp601[tmp602]; _aether.logStatement([{ofs: 4420, row: 165, col: 8}, {ofs: 4447, row: 165, col: 35}], _aether._userInfo, false);\n tmp604 = 'Vector';\n tmp603 = __global[tmp604];\n _aether.logStatementStart([{ofs: 4488, row: 167, col: 31}, {ofs: 4489, row: 167, col: 32}]); tmp605 = 0; _aether.logStatement([{ofs: 4488, row: 167, col: 31}, {ofs: 4489, row: 167, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4491, row: 167, col: 34}, {ofs: 4492, row: 167, col: 35}]); tmp606 = 0; _aether.logStatement([{ofs: 4491, row: 167, col: 34}, {ofs: 4492, row: 167, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4465, row: 167, col: 8}, {ofs: 4494, row: 167, col: 37}]); force = new tmp603(tmp605, tmp606); _aether.logStatement([{ofs: 4465, row: 167, col: 8}, {ofs: 4494, row: 167, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}]); j = 0; _aether.logStatement([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}], _aether._userInfo, false);\n tmp607 = coins;\n tmp608 = 'length';\n _aether.logStatementStart([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}]); cLen = tmp607[tmp608]; _aether.logStatement([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}], _aether._userInfo, false);\n tmp610 = j;\n tmp611 = cLen;\n _aether.logStatementStart([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}]); tmp609 = tmp610 < tmp611; _aether.logStatement([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}], _aether._userInfo, false);\n tmp616: {\n while (tmp609) {\n tmp617: {\n tmp618 = coins;\n tmp619 = j;\n _aether.logStatementStart([{ofs: 4578, row: 170, col: 12}, {ofs: 4598, row: 170, col: 32}]); coin = tmp618[tmp619]; _aether.logStatement([{ofs: 4578, row: 170, col: 12}, {ofs: 4598, row: 170, col: 32}], _aether._userInfo, false);\n tmp620 = coin;\n tmp621 = 'pos';\n _aether.logStatementStart([{ofs: 4611, row: 171, col: 12}, {ofs: 4634, row: 171, col: 35}]); coinPos = tmp620[tmp621]; _aether.logStatement([{ofs: 4611, row: 171, col: 12}, {ofs: 4634, row: 171, col: 35}], _aether._userInfo, false);\n tmp622 = friendPos;\n tmp623 = 'distance';\n tmp624 = coinPos;\n _aether.logStatementStart([{ofs: 4647, row: 172, col: 12}, {ofs: 4686, row: 172, col: 51}]); dist = _aether.createAPIClone(_aether, tmp622[tmp623](_aether.restoreAPIClone(_aether, tmp624))); _aether.logStatement([{ofs: 4647, row: 172, col: 12}, {ofs: 4686, row: 172, col: 51}], _aether._userInfo, false);\n tmp625 = limits;\n tmp627 = coin;\n tmp628 = 'id';\n _aether.logStatementStart([{ofs: 4722, row: 173, col: 35}, {ofs: 4729, row: 173, col: 42}]); tmp626 = tmp627[tmp628]; _aether.logStatement([{ofs: 4722, row: 173, col: 35}, {ofs: 4729, row: 173, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4699, row: 173, col: 12}, {ofs: 4731, row: 173, col: 44}]); enemyDist = tmp625[tmp626]; _aether.logStatement([{ofs: 4699, row: 173, col: 12}, {ofs: 4731, row: 173, col: 44}], _aether._userInfo, false);\n tmp633 = coin;\n tmp634 = 'bountyGold';\n _aether.logStatementStart([{ofs: 4760, row: 174, col: 28}, {ofs: 4775, row: 174, col: 43}]); tmp631 = tmp633[tmp634]; _aether.logStatement([{ofs: 4760, row: 174, col: 28}, {ofs: 4775, row: 174, col: 43}], _aether._userInfo, false);\n tmp635 = computeEnemyMult;\n tmp636 = dist;\n tmp637 = enemyDist;\n _aether.logStatementStart([{ofs: 4778, row: 174, col: 46}, {ofs: 4811, row: 174, col: 79}]); tmp632 = _aether.createAPIClone(_aether, tmp635(_aether.restoreAPIClone(_aether, tmp636), _aether.restoreAPIClone(_aether, tmp637))); _aether.logStatement([{ofs: 4778, row: 174, col: 46}, {ofs: 4811, row: 174, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4760, row: 174, col: 28}, {ofs: 4811, row: 174, col: 79}]); tmp629 = tmp631 * tmp632; _aether.logStatement([{ofs: 4760, row: 174, col: 28}, {ofs: 4811, row: 174, col: 79}], _aether._userInfo, false);\n tmp638 = dist;\n tmp639 = dist;\n _aether.logStatementStart([{ofs: 4816, row: 174, col: 84}, {ofs: 4827, row: 174, col: 95}]); tmp630 = tmp638 * tmp639; _aether.logStatement([{ofs: 4816, row: 174, col: 84}, {ofs: 4827, row: 174, col: 95}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4744, row: 174, col: 12}, {ofs: 4829, row: 174, col: 97}]); strength = tmp629 / tmp630; _aether.logStatement([{ofs: 4744, row: 174, col: 12}, {ofs: 4829, row: 174, col: 97}], _aether._userInfo, false);\n tmp642 = 'Vector';\n tmp640 = __global[tmp642];\n tmp641 = 'normalize';\n tmp646 = 'Vector';\n tmp644 = __global[tmp646];\n tmp645 = 'subtract';\n tmp647 = coinPos;\n tmp648 = friendPos;\n _aether.logStatementStart([{ofs: 4875, row: 175, col: 45}, {ofs: 4910, row: 175, col: 80}]); tmp643 = _aether.createAPIClone(_aether, tmp644[tmp645](_aether.restoreAPIClone(_aether, tmp647), _aether.restoreAPIClone(_aether, tmp648))); _aether.logStatement([{ofs: 4875, row: 175, col: 45}, {ofs: 4910, row: 175, col: 80}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4842, row: 175, col: 12}, {ofs: 4912, row: 175, col: 82}]); direction = _aether.createAPIClone(_aether, tmp640[tmp641](_aether.restoreAPIClone(_aether, tmp643))); _aether.logStatement([{ofs: 4842, row: 175, col: 12}, {ofs: 4912, row: 175, col: 82}], _aether._userInfo, false);\n tmp651 = 'Vector';\n tmp649 = __global[tmp651];\n tmp650 = 'add';\n tmp652 = force;\n tmp656 = 'Vector';\n tmp654 = __global[tmp656];\n tmp655 = 'multiply';\n tmp657 = direction;\n tmp658 = strength;\n _aether.logStatementStart([{ofs: 4951, row: 176, col: 38}, {ofs: 4987, row: 176, col: 74}]); tmp653 = _aether.createAPIClone(_aether, tmp654[tmp655](_aether.restoreAPIClone(_aether, tmp657), _aether.restoreAPIClone(_aether, tmp658))); _aether.logStatement([{ofs: 4951, row: 176, col: 38}, {ofs: 4987, row: 176, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4925, row: 176, col: 12}, {ofs: 4989, row: 176, col: 76}]); force = _aether.createAPIClone(_aether, tmp649[tmp650](_aether.restoreAPIClone(_aether, tmp652), _aether.restoreAPIClone(_aether, tmp653))); _aether.logStatement([{ofs: 4925, row: 176, col: 12}, {ofs: 4989, row: 176, col: 76}], _aether._userInfo, false);\n }\n tmp614 = j;\n tmp615 = 1;\n j = tmp614 + tmp615;\n tmp612 = j;\n tmp613 = cLen;\n _aether.logStatementStart([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}]); tmp609 = tmp612 < tmp613; _aether.logStatement([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}], _aether._userInfo, false);\n }\n }\n _aether.logStatementStart([{ofs: 5022, row: 179, col: 13}, {ofs: 5031, row: 179, col: 22}]); k = 0; _aether.logStatement([{ofs: 5022, row: 179, col: 13}, {ofs: 5031, row: 179, col: 22}], _aether._userInfo, false);\n tmp660 = k;\n tmp661 = fLen;\n _aether.logStatementStart([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}]); tmp659 = tmp660 < tmp661; _aether.logStatement([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}], _aether._userInfo, false);\n tmp666: {\n while (tmp659) {\n tmp667: {\n tmp669 = k;\n tmp670 = i;\n _aether.logStatementStart([{ofs: 5066, row: 180, col: 16}, {ofs: 5073, row: 180, col: 23}]); tmp668 = tmp669 === tmp670; _aether.logStatement([{ofs: 5066, row: 180, col: 16}, {ofs: 5073, row: 180, col: 23}], _aether._userInfo, false);\n if (tmp668) {\n break tmp667;\n } else {\n ;\n }\n tmp673 = 'Vector';\n tmp671 = __global[tmp673];\n tmp672 = 'add';\n tmp674 = force;\n tmp676 = computeAttraction;\n tmp677 = friendPos;\n tmp682 = friends;\n tmp683 = k;\n _aether.logStatementStart([{ofs: 5197, row: 184, col: 67}, {ofs: 5207, row: 184, col: 77}]); tmp680 = tmp682[tmp683]; _aether.logStatement([{ofs: 5197, row: 184, col: 67}, {ofs: 5207, row: 184, col: 77}], _aether._userInfo, false);\n tmp681 = 'pos';\n _aether.logStatementStart([{ofs: 5197, row: 184, col: 67}, {ofs: 5211, row: 184, col: 81}]); tmp678 = tmp680[tmp681]; _aether.logStatement([{ofs: 5197, row: 184, col: 67}, {ofs: 5211, row: 184, col: 81}], _aether._userInfo, false);\n tmp679 = FRIEND_ATTRACTION;\n _aether.logStatementStart([{ofs: 5168, row: 184, col: 38}, {ofs: 5231, row: 184, col: 101}]); tmp675 = _aether.createAPIClone(_aether, tmp676(_aether.restoreAPIClone(_aether, tmp677), _aether.restoreAPIClone(_aether, tmp678), _aether.restoreAPIClone(_aether, tmp679))); _aether.logStatement([{ofs: 5168, row: 184, col: 38}, {ofs: 5231, row: 184, col: 101}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5142, row: 184, col: 12}, {ofs: 5233, row: 184, col: 103}]); force = _aether.createAPIClone(_aether, tmp671[tmp672](_aether.restoreAPIClone(_aether, tmp674), _aether.restoreAPIClone(_aether, tmp675))); _aether.logStatement([{ofs: 5142, row: 184, col: 12}, {ofs: 5233, row: 184, col: 103}], _aether._userInfo, false);\n }\n tmp664 = k;\n tmp665 = 1;\n k = tmp664 + tmp665;\n tmp662 = k;\n tmp663 = fLen;\n _aether.logStatementStart([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}]); tmp659 = tmp662 < tmp663; _aether.logStatement([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}], _aether._userInfo, false);\n }\n }\n tmp686 = 'Vector';\n tmp684 = __global[tmp686];\n tmp685 = 'add';\n tmp687 = force;\n tmp689 = computeAttraction;\n tmp690 = friendPos;\n tmp694 = 'Vector';\n tmp693 = __global[tmp694];\n _aether.logStatementStart([{ofs: 5354, row: 188, col: 75}, {ofs: 5357, row: 188, col: 78}]); tmp697 = 0.1; _aether.logStatement([{ofs: 5354, row: 188, col: 75}, {ofs: 5357, row: 188, col: 78}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5353, row: 188, col: 74}, {ofs: 5357, row: 188, col: 78}]); tmp695 = -tmp697; _aether.logStatement([{ofs: 5353, row: 188, col: 74}, {ofs: 5357, row: 188, col: 78}], _aether._userInfo, false);\n tmp698 = friendPos;\n tmp699 = 'y';\n _aether.logStatementStart([{ofs: 5359, row: 188, col: 80}, {ofs: 5370, row: 188, col: 91}]); tmp696 = tmp698[tmp699]; _aether.logStatement([{ofs: 5359, row: 188, col: 80}, {ofs: 5370, row: 188, col: 91}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5342, row: 188, col: 63}, {ofs: 5371, row: 188, col: 92}]); tmp691 = new tmp693(tmp695, tmp696); _aether.logStatement([{ofs: 5342, row: 188, col: 63}, {ofs: 5371, row: 188, col: 92}], _aether._userInfo, false);\n tmp692 = WALL_ATTRACTION;\n _aether.logStatementStart([{ofs: 5313, row: 188, col: 34}, {ofs: 5389, row: 188, col: 110}]); tmp688 = _aether.createAPIClone(_aether, tmp689(_aether.restoreAPIClone(_aether, tmp690), _aether.restoreAPIClone(_aether, tmp691), _aether.restoreAPIClone(_aether, tmp692))); _aether.logStatement([{ofs: 5313, row: 188, col: 34}, {ofs: 5389, row: 188, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5287, row: 188, col: 8}, {ofs: 5391, row: 188, col: 112}]); force = _aether.createAPIClone(_aether, tmp684[tmp685](_aether.restoreAPIClone(_aether, tmp687), _aether.restoreAPIClone(_aether, tmp688))); _aether.logStatement([{ofs: 5287, row: 188, col: 8}, {ofs: 5391, row: 188, col: 112}], _aether._userInfo, false);\n tmp702 = 'Vector';\n tmp700 = __global[tmp702];\n tmp701 = 'add';\n tmp703 = force;\n tmp705 = computeAttraction;\n tmp706 = friendPos;\n tmp710 = 'Vector';\n tmp709 = __global[tmp710];\n tmp713 = ARENA_WIDTH;\n _aether.logStatementStart([{ofs: 5488, row: 189, col: 88}, {ofs: 5491, row: 189, col: 91}]); tmp714 = 0.1; _aether.logStatement([{ofs: 5488, row: 189, col: 88}, {ofs: 5491, row: 189, col: 91}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5474, row: 189, col: 74}, {ofs: 5491, row: 189, col: 91}]); tmp711 = tmp713 + tmp714; _aether.logStatement([{ofs: 5474, row: 189, col: 74}, {ofs: 5491, row: 189, col: 91}], _aether._userInfo, false);\n tmp715 = friendPos;\n tmp716 = 'y';\n _aether.logStatementStart([{ofs: 5493, row: 189, col: 93}, {ofs: 5504, row: 189, col: 104}]); tmp712 = tmp715[tmp716]; _aether.logStatement([{ofs: 5493, row: 189, col: 93}, {ofs: 5504, row: 189, col: 104}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5463, row: 189, col: 63}, {ofs: 5505, row: 189, col: 105}]); tmp707 = new tmp709(tmp711, tmp712); _aether.logStatement([{ofs: 5463, row: 189, col: 63}, {ofs: 5505, row: 189, col: 105}], _aether._userInfo, false);\n tmp708 = WALL_ATTRACTION;\n _aether.logStatementStart([{ofs: 5434, row: 189, col: 34}, {ofs: 5523, row: 189, col: 123}]); tmp704 = _aether.createAPIClone(_aether, tmp705(_aether.restoreAPIClone(_aether, tmp706), _aether.restoreAPIClone(_aether, tmp707), _aether.restoreAPIClone(_aether, tmp708))); _aether.logStatement([{ofs: 5434, row: 189, col: 34}, {ofs: 5523, row: 189, col: 123}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5408, row: 189, col: 8}, {ofs: 5525, row: 189, col: 125}]); force = _aether.createAPIClone(_aether, tmp700[tmp701](_aether.restoreAPIClone(_aether, tmp703), _aether.restoreAPIClone(_aether, tmp704))); _aether.logStatement([{ofs: 5408, row: 189, col: 8}, {ofs: 5525, row: 189, col: 125}], _aether._userInfo, false);\n tmp719 = 'Vector';\n tmp717 = __global[tmp719];\n tmp718 = 'add';\n tmp720 = force;\n tmp722 = computeAttraction;\n tmp723 = friendPos;\n tmp727 = 'Vector';\n tmp726 = __global[tmp727];\n tmp730 = friendPos;\n tmp731 = 'x';\n _aether.logStatementStart([{ofs: 5609, row: 190, col: 74}, {ofs: 5620, row: 190, col: 85}]); tmp728 = tmp730[tmp731]; _aether.logStatement([{ofs: 5609, row: 190, col: 74}, {ofs: 5620, row: 190, col: 85}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5623, row: 190, col: 88}, {ofs: 5626, row: 190, col: 91}]); tmp732 = 0.1; _aether.logStatement([{ofs: 5623, row: 190, col: 88}, {ofs: 5626, row: 190, col: 91}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5622, row: 190, col: 87}, {ofs: 5626, row: 190, col: 91}]); tmp729 = -tmp732; _aether.logStatement([{ofs: 5622, row: 190, col: 87}, {ofs: 5626, row: 190, col: 91}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5598, row: 190, col: 63}, {ofs: 5627, row: 190, col: 92}]); tmp724 = new tmp726(tmp728, tmp729); _aether.logStatement([{ofs: 5598, row: 190, col: 63}, {ofs: 5627, row: 190, col: 92}], _aether._userInfo, false);\n tmp725 = WALL_ATTRACTION;\n _aether.logStatementStart([{ofs: 5569, row: 190, col: 34}, {ofs: 5645, row: 190, col: 110}]); tmp721 = _aether.createAPIClone(_aether, tmp722(_aether.restoreAPIClone(_aether, tmp723), _aether.restoreAPIClone(_aether, tmp724), _aether.restoreAPIClone(_aether, tmp725))); _aether.logStatement([{ofs: 5569, row: 190, col: 34}, {ofs: 5645, row: 190, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5543, row: 190, col: 8}, {ofs: 5647, row: 190, col: 112}]); force = _aether.createAPIClone(_aether, tmp717[tmp718](_aether.restoreAPIClone(_aether, tmp720), _aether.restoreAPIClone(_aether, tmp721))); _aether.logStatement([{ofs: 5543, row: 190, col: 8}, {ofs: 5647, row: 190, col: 112}], _aether._userInfo, false);\n tmp735 = 'Vector';\n tmp733 = __global[tmp735];\n tmp734 = 'add';\n tmp736 = force;\n tmp738 = computeAttraction;\n tmp739 = friendPos;\n tmp743 = 'Vector';\n tmp742 = __global[tmp743];\n tmp746 = friendPos;\n tmp747 = 'x';\n _aether.logStatementStart([{ofs: 5732, row: 191, col: 74}, {ofs: 5743, row: 191, col: 85}]); tmp744 = tmp746[tmp747]; _aether.logStatement([{ofs: 5732, row: 191, col: 74}, {ofs: 5743, row: 191, col: 85}], _aether._userInfo, false);\n tmp748 = ARENA_HEIGHT;\n _aether.logStatementStart([{ofs: 5760, row: 191, col: 102}, {ofs: 5763, row: 191, col: 105}]); tmp749 = 0.1; _aether.logStatement([{ofs: 5760, row: 191, col: 102}, {ofs: 5763, row: 191, col: 105}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5745, row: 191, col: 87}, {ofs: 5763, row: 191, col: 105}]); tmp745 = tmp748 + tmp749; _aether.logStatement([{ofs: 5745, row: 191, col: 87}, {ofs: 5763, row: 191, col: 105}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5721, row: 191, col: 63}, {ofs: 5764, row: 191, col: 106}]); tmp740 = new tmp742(tmp744, tmp745); _aether.logStatement([{ofs: 5721, row: 191, col: 63}, {ofs: 5764, row: 191, col: 106}], _aether._userInfo, false);\n tmp741 = WALL_ATTRACTION;\n _aether.logStatementStart([{ofs: 5692, row: 191, col: 34}, {ofs: 5782, row: 191, col: 124}]); tmp737 = _aether.createAPIClone(_aether, tmp738(_aether.restoreAPIClone(_aether, tmp739), _aether.restoreAPIClone(_aether, tmp740), _aether.restoreAPIClone(_aether, tmp741))); _aether.logStatement([{ofs: 5692, row: 191, col: 34}, {ofs: 5782, row: 191, col: 124}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5666, row: 191, col: 8}, {ofs: 5784, row: 191, col: 126}]); force = _aether.createAPIClone(_aether, tmp733[tmp734](_aether.restoreAPIClone(_aether, tmp736), _aether.restoreAPIClone(_aether, tmp737))); _aether.logStatement([{ofs: 5666, row: 191, col: 8}, {ofs: 5784, row: 191, col: 126}], _aether._userInfo, false);\n tmp752 = 'Vector';\n tmp750 = __global[tmp752];\n tmp751 = 'add';\n tmp753 = friendPos;\n tmp757 = 'Vector';\n tmp755 = __global[tmp757];\n tmp756 = 'multiply';\n tmp762 = 'Vector';\n tmp760 = __global[tmp762];\n tmp761 = 'normalize';\n tmp763 = force;\n _aether.logStatementStart([{ofs: 5860, row: 193, col: 59}, {ofs: 5883, row: 193, col: 82}]); tmp758 = _aether.createAPIClone(_aether, tmp760[tmp761](_aether.restoreAPIClone(_aether, tmp763))); _aether.logStatement([{ofs: 5860, row: 193, col: 59}, {ofs: 5883, row: 193, col: 82}], _aether._userInfo, false);\n tmp759 = DIRECTION_CASTAHEAD;\n _aether.logStatementStart([{ofs: 5844, row: 193, col: 43}, {ofs: 5905, row: 193, col: 104}]); tmp754 = _aether.createAPIClone(_aether, tmp755[tmp756](_aether.restoreAPIClone(_aether, tmp758), _aether.restoreAPIClone(_aether, tmp759))); _aether.logStatement([{ofs: 5844, row: 193, col: 43}, {ofs: 5905, row: 193, col: 104}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5809, row: 193, col: 8}, {ofs: 5907, row: 193, col: 106}]); newPos = _aether.createAPIClone(_aether, tmp750[tmp751](_aether.restoreAPIClone(_aether, tmp753), _aether.restoreAPIClone(_aether, tmp754))); _aether.logStatement([{ofs: 5809, row: 193, col: 8}, {ofs: 5907, row: 193, col: 106}], _aether._userInfo, false);\n tmp765 = 'Vector';\n tmp764 = __global[tmp765];\n tmp770 = 'Math';\n tmp768 = __global[tmp770];\n tmp769 = 'min';\n tmp775 = 'Math';\n tmp773 = __global[tmp775];\n tmp774 = 'max';\n tmp778 = newPos;\n tmp779 = 'x';\n _aether.logStatementStart([{ofs: 5967, row: 195, col: 30}, {ofs: 5975, row: 195, col: 38}]); tmp776 = tmp778[tmp779]; _aether.logStatement([{ofs: 5967, row: 195, col: 30}, {ofs: 5975, row: 195, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5977, row: 195, col: 40}, {ofs: 5980, row: 195, col: 43}]); tmp777 = 0; _aether.logStatement([{ofs: 5977, row: 195, col: 40}, {ofs: 5980, row: 195, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5958, row: 195, col: 21}, {ofs: 5981, row: 195, col: 44}]); tmp771 = _aether.createAPIClone(_aether, tmp773[tmp774](_aether.restoreAPIClone(_aether, tmp776), _aether.restoreAPIClone(_aether, tmp777))); _aether.logStatement([{ofs: 5958, row: 195, col: 21}, {ofs: 5981, row: 195, col: 44}], _aether._userInfo, false);\n tmp772 = ARENA_WIDTH;\n _aether.logStatementStart([{ofs: 5949, row: 195, col: 12}, {ofs: 5995, row: 195, col: 58}]); tmp766 = _aether.createAPIClone(_aether, tmp768[tmp769](_aether.restoreAPIClone(_aether, tmp771), _aether.restoreAPIClone(_aether, tmp772))); _aether.logStatement([{ofs: 5949, row: 195, col: 12}, {ofs: 5995, row: 195, col: 58}], _aether._userInfo, false);\n tmp782 = 'Math';\n tmp780 = __global[tmp782];\n tmp781 = 'min';\n tmp787 = 'Math';\n tmp785 = __global[tmp787];\n tmp786 = 'max';\n tmp790 = newPos;\n tmp791 = 'y';\n _aether.logStatementStart([{ofs: 6027, row: 196, col: 30}, {ofs: 6035, row: 196, col: 38}]); tmp788 = tmp790[tmp791]; _aether.logStatement([{ofs: 6027, row: 196, col: 30}, {ofs: 6035, row: 196, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6037, row: 196, col: 40}, {ofs: 6040, row: 196, col: 43}]); tmp789 = 0; _aether.logStatement([{ofs: 6037, row: 196, col: 40}, {ofs: 6040, row: 196, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6018, row: 196, col: 21}, {ofs: 6041, row: 196, col: 44}]); tmp783 = _aether.createAPIClone(_aether, tmp785[tmp786](_aether.restoreAPIClone(_aether, tmp788), _aether.restoreAPIClone(_aether, tmp789))); _aether.logStatement([{ofs: 6018, row: 196, col: 21}, {ofs: 6041, row: 196, col: 44}], _aether._userInfo, false);\n tmp784 = ARENA_HEIGHT;\n _aether.logStatementStart([{ofs: 6009, row: 196, col: 12}, {ofs: 6056, row: 196, col: 59}]); tmp767 = _aether.createAPIClone(_aether, tmp780[tmp781](_aether.restoreAPIClone(_aether, tmp783), _aether.restoreAPIClone(_aether, tmp784))); _aether.logStatement([{ofs: 6009, row: 196, col: 12}, {ofs: 6056, row: 196, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5916, row: 194, col: 8}, {ofs: 6058, row: 196, col: 61}]); newPos = new tmp764(tmp766, tmp767); _aether.logStatement([{ofs: 5916, row: 194, col: 8}, {ofs: 6058, row: 196, col: 61}], _aether._userInfo, false);\n tmp792 = assignments;\n tmp793 = 'push';\n tmp795 = friend;\n tmp796 = newPos;\n _aether.logStatementStart([{ofs: 6093, row: 198, col: 25}, {ofs: 6122, row: 198, col: 54}]); tmp794 = {\n src: tmp795,\n target: tmp796\n }; _aether.logStatement([{ofs: 6093, row: 198, col: 25}, {ofs: 6122, row: 198, col: 54}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6076, row: 198, col: 8}, {ofs: 6123, row: 198, col: 55}]); tmp797 = _aether.createAPIClone(_aether, tmp792[tmp793](_aether.restoreAPIClone(_aether, tmp794))); _aether.logStatement([{ofs: 6076, row: 198, col: 8}, {ofs: 6123, row: 198, col: 55}], _aether._userInfo, false);\n }\n tmp595 = i;\n tmp596 = 1;\n i = tmp595 + tmp596;\n tmp593 = i;\n tmp594 = fLen;\n _aether.logStatementStart([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}]); tmp590 = tmp593 < tmp594; _aether.logStatement([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}], _aether._userInfo, false);\n }\n }\n tmp798 = assignments;\n return _aether.restoreAPIClone(_aether, tmp798);\n }; _aether.logStatement([{ofs: 3990, row: 150, col: 0}, {ofs: 6161, row: 202, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6834, row: 224, col: 0}, {ofs: 7486, row: 243, col: 1}]); createRegressionFunc = function (points) {\n var n, sumX, sumY, meanX, meanY, sumXSquared, sumXY, slope, intercept, tmp799, tmp800, tmp801, tmp802, tmp803, tmp804, tmp810, tmp811, tmp812, tmp813, tmp819, tmp820, tmp821, tmp822, tmp823, tmp824, tmp825, tmp826, tmp836, tmp837, tmp838, tmp839, tmp849, tmp850, tmp851, tmp852, tmp853, tmp854, tmp855, tmp856, tmp857, tmp858, tmp859, tmp860, tmp861, tmp862, tmp863, tmp864, tmp865, tmp866, tmp867; points = _aether.createAPIClone(_aether, points); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp799 = points;\n tmp800 = 'length';\n _aether.logStatementStart([{ofs: 6878, row: 225, col: 4}, {ofs: 6900, row: 225, col: 26}]); n = tmp799[tmp800]; _aether.logStatement([{ofs: 6878, row: 225, col: 4}, {ofs: 6900, row: 225, col: 26}], _aether._userInfo, false);\n tmp801 = points;\n tmp802 = 'reduce';\n _aether.logStatementStart([{ofs: 6935, row: 227, col: 29}, {ofs: 6969, row: 227, col: 63}]); tmp803 = function (a, b) {\n var tmp805, tmp806, tmp807, tmp808, tmp809; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp806 = a;\n tmp808 = b;\n tmp809 = 'x';\n _aether.logStatementStart([{ofs: 6963, row: 227, col: 57}, {ofs: 6966, row: 227, col: 60}]); tmp807 = tmp808[tmp809]; _aether.logStatement([{ofs: 6963, row: 227, col: 57}, {ofs: 6966, row: 227, col: 60}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6959, row: 227, col: 53}, {ofs: 6966, row: 227, col: 60}]); tmp805 = tmp806 + tmp807; _aether.logStatement([{ofs: 6959, row: 227, col: 53}, {ofs: 6966, row: 227, col: 60}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp805);\n }; _aether.logStatement([{ofs: 6935, row: 227, col: 29}, {ofs: 6969, row: 227, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6971, row: 227, col: 65}, {ofs: 6972, row: 227, col: 66}]); tmp804 = 0; _aether.logStatement([{ofs: 6971, row: 227, col: 65}, {ofs: 6972, row: 227, col: 66}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6910, row: 227, col: 4}, {ofs: 6974, row: 227, col: 68}]); sumX = _aether.createAPIClone(_aether, tmp801[tmp802](_aether.restoreAPIClone(_aether, tmp803), _aether.restoreAPIClone(_aether, tmp804))); _aether.logStatement([{ofs: 6910, row: 227, col: 4}, {ofs: 6974, row: 227, col: 68}], _aether._userInfo, false);\n tmp810 = points;\n tmp811 = 'reduce';\n _aether.logStatementStart([{ofs: 7004, row: 228, col: 29}, {ofs: 7038, row: 228, col: 63}]); tmp812 = function (a, b) {\n var tmp814, tmp815, tmp816, tmp817, tmp818; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp815 = a;\n tmp817 = b;\n tmp818 = 'y';\n _aether.logStatementStart([{ofs: 7032, row: 228, col: 57}, {ofs: 7035, row: 228, col: 60}]); tmp816 = tmp817[tmp818]; _aether.logStatement([{ofs: 7032, row: 228, col: 57}, {ofs: 7035, row: 228, col: 60}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7028, row: 228, col: 53}, {ofs: 7035, row: 228, col: 60}]); tmp814 = tmp815 + tmp816; _aether.logStatement([{ofs: 7028, row: 228, col: 53}, {ofs: 7035, row: 228, col: 60}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp814);\n }; _aether.logStatement([{ofs: 7004, row: 228, col: 29}, {ofs: 7038, row: 228, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7040, row: 228, col: 65}, {ofs: 7041, row: 228, col: 66}]); tmp813 = 0; _aether.logStatement([{ofs: 7040, row: 228, col: 65}, {ofs: 7041, row: 228, col: 66}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6979, row: 228, col: 4}, {ofs: 7043, row: 228, col: 68}]); sumY = _aether.createAPIClone(_aether, tmp810[tmp811](_aether.restoreAPIClone(_aether, tmp812), _aether.restoreAPIClone(_aether, tmp813))); _aether.logStatement([{ofs: 6979, row: 228, col: 4}, {ofs: 7043, row: 228, col: 68}], _aether._userInfo, false);\n tmp819 = sumX;\n tmp820 = n;\n _aether.logStatementStart([{ofs: 7048, row: 229, col: 4}, {ofs: 7069, row: 229, col: 25}]); meanX = tmp819 / tmp820; _aether.logStatement([{ofs: 7048, row: 229, col: 4}, {ofs: 7069, row: 229, col: 25}], _aether._userInfo, false);\n tmp821 = sumY;\n tmp822 = n;\n _aether.logStatementStart([{ofs: 7074, row: 230, col: 4}, {ofs: 7095, row: 230, col: 25}]); meanY = tmp821 / tmp822; _aether.logStatement([{ofs: 7074, row: 230, col: 4}, {ofs: 7095, row: 230, col: 25}], _aether._userInfo, false);\n tmp823 = points;\n tmp824 = 'reduce';\n _aether.logStatementStart([{ofs: 7137, row: 232, col: 36}, {ofs: 7179, row: 232, col: 78}]); tmp825 = function (a, b) {\n var tmp827, tmp828, tmp829, tmp830, tmp831, tmp832, tmp833, tmp834, tmp835; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp828 = a;\n tmp832 = b;\n tmp833 = 'x';\n _aether.logStatementStart([{ofs: 7166, row: 232, col: 65}, {ofs: 7169, row: 232, col: 68}]); tmp830 = tmp832[tmp833]; _aether.logStatement([{ofs: 7166, row: 232, col: 65}, {ofs: 7169, row: 232, col: 68}], _aether._userInfo, false);\n tmp834 = b;\n tmp835 = 'x';\n _aether.logStatementStart([{ofs: 7172, row: 232, col: 71}, {ofs: 7175, row: 232, col: 74}]); tmp831 = tmp834[tmp835]; _aether.logStatement([{ofs: 7172, row: 232, col: 71}, {ofs: 7175, row: 232, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7166, row: 232, col: 65}, {ofs: 7175, row: 232, col: 74}]); tmp829 = tmp830 * tmp831; _aether.logStatement([{ofs: 7166, row: 232, col: 65}, {ofs: 7175, row: 232, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7161, row: 232, col: 60}, {ofs: 7176, row: 232, col: 75}]); tmp827 = tmp828 + tmp829; _aether.logStatement([{ofs: 7161, row: 232, col: 60}, {ofs: 7176, row: 232, col: 75}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp827);\n }; _aether.logStatement([{ofs: 7137, row: 232, col: 36}, {ofs: 7179, row: 232, col: 78}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7181, row: 232, col: 80}, {ofs: 7182, row: 232, col: 81}]); tmp826 = 0; _aether.logStatement([{ofs: 7181, row: 232, col: 80}, {ofs: 7182, row: 232, col: 81}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7105, row: 232, col: 4}, {ofs: 7184, row: 232, col: 83}]); sumXSquared = _aether.createAPIClone(_aether, tmp823[tmp824](_aether.restoreAPIClone(_aether, tmp825), _aether.restoreAPIClone(_aether, tmp826))); _aether.logStatement([{ofs: 7105, row: 232, col: 4}, {ofs: 7184, row: 232, col: 83}], _aether._userInfo, false);\n tmp836 = points;\n tmp837 = 'reduce';\n _aether.logStatementStart([{ofs: 7220, row: 234, col: 30}, {ofs: 7262, row: 234, col: 72}]); tmp838 = function (a, b) {\n var tmp840, tmp841, tmp842, tmp843, tmp844, tmp845, tmp846, tmp847, tmp848; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp841 = a;\n tmp845 = b;\n tmp846 = 'x';\n _aether.logStatementStart([{ofs: 7249, row: 234, col: 59}, {ofs: 7252, row: 234, col: 62}]); tmp843 = tmp845[tmp846]; _aether.logStatement([{ofs: 7249, row: 234, col: 59}, {ofs: 7252, row: 234, col: 62}], _aether._userInfo, false);\n tmp847 = b;\n tmp848 = 'y';\n _aether.logStatementStart([{ofs: 7255, row: 234, col: 65}, {ofs: 7258, row: 234, col: 68}]); tmp844 = tmp847[tmp848]; _aether.logStatement([{ofs: 7255, row: 234, col: 65}, {ofs: 7258, row: 234, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7249, row: 234, col: 59}, {ofs: 7258, row: 234, col: 68}]); tmp842 = tmp843 * tmp844; _aether.logStatement([{ofs: 7249, row: 234, col: 59}, {ofs: 7258, row: 234, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7244, row: 234, col: 54}, {ofs: 7259, row: 234, col: 69}]); tmp840 = tmp841 + tmp842; _aether.logStatement([{ofs: 7244, row: 234, col: 54}, {ofs: 7259, row: 234, col: 69}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp840);\n }; _aether.logStatement([{ofs: 7220, row: 234, col: 30}, {ofs: 7262, row: 234, col: 72}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7264, row: 234, col: 74}, {ofs: 7265, row: 234, col: 75}]); tmp839 = 0; _aether.logStatement([{ofs: 7264, row: 234, col: 74}, {ofs: 7265, row: 234, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7194, row: 234, col: 4}, {ofs: 7267, row: 234, col: 77}]); sumXY = _aether.createAPIClone(_aether, tmp836[tmp837](_aether.restoreAPIClone(_aether, tmp838), _aether.restoreAPIClone(_aether, tmp839))); _aether.logStatement([{ofs: 7194, row: 234, col: 4}, {ofs: 7267, row: 234, col: 77}], _aether._userInfo, false);\n tmp851 = sumXY;\n tmp855 = sumX;\n tmp856 = sumY;\n _aether.logStatementStart([{ofs: 7300, row: 236, col: 27}, {ofs: 7311, row: 236, col: 38}]); tmp853 = tmp855 * tmp856; _aether.logStatement([{ofs: 7300, row: 236, col: 27}, {ofs: 7311, row: 236, col: 38}], _aether._userInfo, false);\n tmp854 = n;\n _aether.logStatementStart([{ofs: 7299, row: 236, col: 26}, {ofs: 7316, row: 236, col: 43}]); tmp852 = tmp853 / tmp854; _aether.logStatement([{ofs: 7299, row: 236, col: 26}, {ofs: 7316, row: 236, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7290, row: 236, col: 17}, {ofs: 7317, row: 236, col: 44}]); tmp849 = tmp851 - tmp852; _aether.logStatement([{ofs: 7290, row: 236, col: 17}, {ofs: 7317, row: 236, col: 44}], _aether._userInfo, false);\n tmp857 = sumXSquared;\n tmp861 = sumX;\n tmp862 = sumX;\n _aether.logStatementStart([{ofs: 7338, row: 236, col: 65}, {ofs: 7349, row: 236, col: 76}]); tmp859 = tmp861 * tmp862; _aether.logStatement([{ofs: 7338, row: 236, col: 65}, {ofs: 7349, row: 236, col: 76}], _aether._userInfo, false);\n tmp860 = n;\n _aether.logStatementStart([{ofs: 7337, row: 236, col: 64}, {ofs: 7354, row: 236, col: 81}]); tmp858 = tmp859 / tmp860; _aether.logStatement([{ofs: 7337, row: 236, col: 64}, {ofs: 7354, row: 236, col: 81}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7322, row: 236, col: 49}, {ofs: 7355, row: 236, col: 82}]); tmp850 = tmp857 - tmp858; _aether.logStatement([{ofs: 7322, row: 236, col: 49}, {ofs: 7355, row: 236, col: 82}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7277, row: 236, col: 4}, {ofs: 7357, row: 236, col: 84}]); slope = tmp849 / tmp850; _aether.logStatement([{ofs: 7277, row: 236, col: 4}, {ofs: 7357, row: 236, col: 84}], _aether._userInfo, false);\n tmp863 = meanY;\n tmp865 = slope;\n tmp866 = meanX;\n _aether.logStatementStart([{ofs: 7392, row: 238, col: 29}, {ofs: 7405, row: 238, col: 42}]); tmp864 = tmp865 * tmp866; _aether.logStatement([{ofs: 7392, row: 238, col: 29}, {ofs: 7405, row: 238, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7367, row: 238, col: 4}, {ofs: 7407, row: 238, col: 44}]); intercept = tmp863 - tmp864; _aether.logStatement([{ofs: 7367, row: 238, col: 4}, {ofs: 7407, row: 238, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7424, row: 240, col: 11}, {ofs: 7483, row: 242, col: 5}]); tmp867 = function (x) {\n var tmp868, tmp869, tmp870, tmp871, tmp872; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp871 = slope;\n tmp872 = x;\n _aether.logStatementStart([{ofs: 7454, row: 241, col: 16}, {ofs: 7463, row: 241, col: 25}]); tmp869 = tmp871 * tmp872; _aether.logStatement([{ofs: 7454, row: 241, col: 16}, {ofs: 7463, row: 241, col: 25}], _aether._userInfo, false);\n tmp870 = intercept;\n _aether.logStatementStart([{ofs: 7453, row: 241, col: 15}, {ofs: 7476, row: 241, col: 38}]); tmp868 = tmp869 + tmp870; _aether.logStatement([{ofs: 7453, row: 241, col: 15}, {ofs: 7476, row: 241, col: 38}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp868);\n }; _aether.logStatement([{ofs: 7424, row: 240, col: 11}, {ofs: 7483, row: 242, col: 5}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp867);\n }; _aether.logStatement([{ofs: 6834, row: 224, col: 0}, {ofs: 7486, row: 243, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7488, row: 245, col: 0}, {ofs: 7700, row: 249, col: 1}]); estimateVariance = function (points, regFunc) {\n var mseSum, mse, tmp873, tmp874, tmp875, tmp876, tmp890, tmp891, tmp892, tmp893, tmp894, tmp895, tmp896; points = _aether.createAPIClone(_aether, points); regFunc = _aether.createAPIClone(_aether, regFunc); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp873 = points;\n tmp874 = 'reduce';\n _aether.logStatementStart([{ofs: 7564, row: 246, col: 31}, {ofs: 7633, row: 246, col: 100}]); tmp875 = function (a, b) {\n var ms, tmp877, tmp878, tmp879, tmp880, tmp881, tmp882, tmp883, tmp884, tmp885, tmp886, tmp887, tmp888, tmp889; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp879 = b;\n tmp880 = 'y';\n _aether.logStatementStart([{ofs: 7590, row: 246, col: 57}, {ofs: 7593, row: 246, col: 60}]); tmp877 = tmp879[tmp880]; _aether.logStatement([{ofs: 7590, row: 246, col: 57}, {ofs: 7593, row: 246, col: 60}], _aether._userInfo, false);\n tmp881 = regFunc;\n tmp883 = b;\n tmp884 = 'x';\n _aether.logStatementStart([{ofs: 7604, row: 246, col: 71}, {ofs: 7607, row: 246, col: 74}]); tmp882 = tmp883[tmp884]; _aether.logStatement([{ofs: 7604, row: 246, col: 71}, {ofs: 7607, row: 246, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7596, row: 246, col: 63}, {ofs: 7608, row: 246, col: 75}]); tmp878 = _aether.createAPIClone(_aether, tmp881(_aether.restoreAPIClone(_aether, tmp882))); _aether.logStatement([{ofs: 7596, row: 246, col: 63}, {ofs: 7608, row: 246, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7581, row: 246, col: 48}, {ofs: 7609, row: 246, col: 76}]); ms = tmp877 - tmp878; _aether.logStatement([{ofs: 7581, row: 246, col: 48}, {ofs: 7609, row: 246, col: 76}], _aether._userInfo, false);\n tmp886 = a;\n tmp888 = ms;\n tmp889 = ms;\n _aether.logStatementStart([{ofs: 7622, row: 246, col: 89}, {ofs: 7629, row: 246, col: 96}]); tmp887 = tmp888 * tmp889; _aether.logStatement([{ofs: 7622, row: 246, col: 89}, {ofs: 7629, row: 246, col: 96}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7617, row: 246, col: 84}, {ofs: 7630, row: 246, col: 97}]); tmp885 = tmp886 + tmp887; _aether.logStatement([{ofs: 7617, row: 246, col: 84}, {ofs: 7630, row: 246, col: 97}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp885);\n }; _aether.logStatement([{ofs: 7564, row: 246, col: 31}, {ofs: 7633, row: 246, col: 100}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7635, row: 246, col: 102}, {ofs: 7636, row: 246, col: 103}]); tmp876 = 0; _aether.logStatement([{ofs: 7635, row: 246, col: 102}, {ofs: 7636, row: 246, col: 103}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7537, row: 246, col: 4}, {ofs: 7638, row: 246, col: 105}]); mseSum = _aether.createAPIClone(_aether, tmp873[tmp874](_aether.restoreAPIClone(_aether, tmp875), _aether.restoreAPIClone(_aether, tmp876))); _aether.logStatement([{ofs: 7537, row: 246, col: 4}, {ofs: 7638, row: 246, col: 105}], _aether._userInfo, false);\n tmp890 = mseSum;\n tmp894 = points;\n tmp895 = 'length';\n _aether.logStatementStart([{ofs: 7663, row: 247, col: 24}, {ofs: 7676, row: 247, col: 37}]); tmp892 = tmp894[tmp895]; _aether.logStatement([{ofs: 7663, row: 247, col: 24}, {ofs: 7676, row: 247, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7679, row: 247, col: 40}, {ofs: 7680, row: 247, col: 41}]); tmp893 = 2; _aether.logStatement([{ofs: 7679, row: 247, col: 40}, {ofs: 7680, row: 247, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7663, row: 247, col: 24}, {ofs: 7680, row: 247, col: 41}]); tmp891 = tmp892 - tmp893; _aether.logStatement([{ofs: 7663, row: 247, col: 24}, {ofs: 7680, row: 247, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7643, row: 247, col: 4}, {ofs: 7682, row: 247, col: 43}]); mse = tmp890 / tmp891; _aether.logStatement([{ofs: 7643, row: 247, col: 4}, {ofs: 7682, row: 247, col: 43}], _aether._userInfo, false);\n tmp896 = mse;\n return _aether.restoreAPIClone(_aether, tmp896);\n }; _aether.logStatement([{ofs: 7488, row: 245, col: 0}, {ofs: 7700, row: 249, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7702, row: 251, col: 0}, {ofs: 8470, row: 272, col: 1}]); estimateHighLow = function (points, time) {\n var regFunc, deviation, bound, start, lowStart, highStart, end, lowEnd, highEnd, upperBound, lowerBound, estimate, tmp897, tmp898, tmp899, tmp900, tmp901, tmp902, tmp903, tmp904, tmp905, tmp906, tmp907, tmp908, tmp909, tmp910, tmp911, tmp912, tmp913, tmp914, tmp915, tmp916, tmp917, tmp918, tmp919, tmp920, tmp921, tmp922, tmp923, tmp924, tmp925, tmp926, tmp927, tmp928, tmp929, tmp930, tmp931, tmp932, tmp933, tmp934, tmp935, tmp936, tmp937, tmp938, tmp939, tmp940, tmp941, tmp942, tmp943, tmp944, tmp945, tmp946, tmp947, tmp948, tmp949, tmp950, tmp951, tmp952, tmp953, tmp954, tmp955, tmp956, tmp957, tmp958, tmp959, tmp960, tmp961, tmp962, tmp963, tmp964, tmp965, tmp966, tmp967, tmp968, tmp969, tmp970, tmp971, tmp972, tmp973, tmp974, tmp975, tmp976, tmp977, tmp978, tmp979, tmp980, tmp981, tmp982, tmp983, tmp984, tmp985, tmp986, tmp987, tmp988, tmp989; points = _aether.createAPIClone(_aether, points); time = _aether.createAPIClone(_aether, time); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp897 = createRegressionFunc;\n tmp898 = points;\n _aether.logStatementStart([{ofs: 7747, row: 252, col: 4}, {ofs: 7790, row: 252, col: 47}]); regFunc = _aether.createAPIClone(_aether, tmp897(_aether.restoreAPIClone(_aether, tmp898))); _aether.logStatement([{ofs: 7747, row: 252, col: 4}, {ofs: 7790, row: 252, col: 47}], _aether._userInfo, false);\n tmp901 = 'Math';\n tmp899 = __global[tmp901];\n tmp900 = 'sqrt';\n tmp903 = estimateVariance;\n tmp904 = points;\n tmp905 = regFunc;\n _aether.logStatementStart([{ofs: 7826, row: 254, col: 30}, {ofs: 7859, row: 254, col: 63}]); tmp902 = _aether.createAPIClone(_aether, tmp903(_aether.restoreAPIClone(_aether, tmp904), _aether.restoreAPIClone(_aether, tmp905))); _aether.logStatement([{ofs: 7826, row: 254, col: 30}, {ofs: 7859, row: 254, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7800, row: 254, col: 4}, {ofs: 7861, row: 254, col: 65}]); deviation = _aether.createAPIClone(_aether, tmp899[tmp900](_aether.restoreAPIClone(_aether, tmp902))); _aether.logStatement([{ofs: 7800, row: 254, col: 4}, {ofs: 7861, row: 254, col: 65}], _aether._userInfo, false);\n tmp906 = deviation;\n _aether.logStatementStart([{ofs: 7890, row: 255, col: 28}, {ofs: 7891, row: 255, col: 29}]); tmp907 = 2; _aether.logStatement([{ofs: 7890, row: 255, col: 28}, {ofs: 7891, row: 255, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7866, row: 255, col: 4}, {ofs: 7892, row: 255, col: 30}]); bound = tmp906 * tmp907; _aether.logStatement([{ofs: 7866, row: 255, col: 4}, {ofs: 7892, row: 255, col: 30}], _aether._userInfo, false);\n tmp908 = regFunc;\n tmp912 = points;\n _aether.logStatementStart([{ofs: 7946, row: 257, col: 31}, {ofs: 7947, row: 257, col: 32}]); tmp913 = 0; _aether.logStatement([{ofs: 7946, row: 257, col: 31}, {ofs: 7947, row: 257, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7939, row: 257, col: 24}, {ofs: 7948, row: 257, col: 33}]); tmp910 = tmp912[tmp913]; _aether.logStatement([{ofs: 7939, row: 257, col: 24}, {ofs: 7948, row: 257, col: 33}], _aether._userInfo, false);\n tmp911 = 'x';\n _aether.logStatementStart([{ofs: 7939, row: 257, col: 24}, {ofs: 7950, row: 257, col: 35}]); tmp909 = tmp910[tmp911]; _aether.logStatement([{ofs: 7939, row: 257, col: 24}, {ofs: 7950, row: 257, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7919, row: 257, col: 4}, {ofs: 7952, row: 257, col: 37}]); start = _aether.createAPIClone(_aether, tmp908(_aether.restoreAPIClone(_aether, tmp909))); _aether.logStatement([{ofs: 7919, row: 257, col: 4}, {ofs: 7952, row: 257, col: 37}], _aether._userInfo, false);\n tmp914 = start;\n tmp915 = bound;\n _aether.logStatementStart([{ofs: 7957, row: 258, col: 4}, {ofs: 7986, row: 258, col: 33}]); lowStart = tmp914 - tmp915; _aether.logStatement([{ofs: 7957, row: 258, col: 4}, {ofs: 7986, row: 258, col: 33}], _aether._userInfo, false);\n tmp916 = start;\n tmp917 = bound;\n _aether.logStatementStart([{ofs: 7991, row: 259, col: 4}, {ofs: 8021, row: 259, col: 34}]); highStart = tmp916 + tmp917; _aether.logStatement([{ofs: 7991, row: 259, col: 4}, {ofs: 8021, row: 259, col: 34}], _aether._userInfo, false);\n tmp918 = regFunc;\n tmp922 = points;\n tmp926 = points;\n tmp927 = 'length';\n _aether.logStatementStart([{ofs: 8056, row: 261, col: 29}, {ofs: 8069, row: 261, col: 42}]); tmp924 = tmp926[tmp927]; _aether.logStatement([{ofs: 8056, row: 261, col: 29}, {ofs: 8069, row: 261, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8072, row: 261, col: 45}, {ofs: 8073, row: 261, col: 46}]); tmp925 = 1; _aether.logStatement([{ofs: 8072, row: 261, col: 45}, {ofs: 8073, row: 261, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8056, row: 261, col: 29}, {ofs: 8073, row: 261, col: 46}]); tmp923 = tmp924 - tmp925; _aether.logStatement([{ofs: 8056, row: 261, col: 29}, {ofs: 8073, row: 261, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8049, row: 261, col: 22}, {ofs: 8074, row: 261, col: 47}]); tmp920 = tmp922[tmp923]; _aether.logStatement([{ofs: 8049, row: 261, col: 22}, {ofs: 8074, row: 261, col: 47}], _aether._userInfo, false);\n tmp921 = 'x';\n _aether.logStatementStart([{ofs: 8049, row: 261, col: 22}, {ofs: 8076, row: 261, col: 49}]); tmp919 = tmp920[tmp921]; _aether.logStatement([{ofs: 8049, row: 261, col: 22}, {ofs: 8076, row: 261, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8031, row: 261, col: 4}, {ofs: 8078, row: 261, col: 51}]); end = _aether.createAPIClone(_aether, tmp918(_aether.restoreAPIClone(_aether, tmp919))); _aether.logStatement([{ofs: 8031, row: 261, col: 4}, {ofs: 8078, row: 261, col: 51}], _aether._userInfo, false);\n tmp928 = end;\n tmp929 = bound;\n _aether.logStatementStart([{ofs: 8083, row: 262, col: 4}, {ofs: 8108, row: 262, col: 29}]); lowEnd = tmp928 - tmp929; _aether.logStatement([{ofs: 8083, row: 262, col: 4}, {ofs: 8108, row: 262, col: 29}], _aether._userInfo, false);\n tmp930 = end;\n tmp931 = bound;\n _aether.logStatementStart([{ofs: 8113, row: 263, col: 4}, {ofs: 8139, row: 263, col: 30}]); highEnd = tmp930 + tmp931; _aether.logStatement([{ofs: 8113, row: 263, col: 4}, {ofs: 8139, row: 263, col: 30}], _aether._userInfo, false);\n tmp932 = lerp;\n tmp933 = lowStart;\n tmp934 = highEnd;\n tmp938 = time;\n tmp942 = points;\n _aether.logStatementStart([{ofs: 8205, row: 265, col: 60}, {ofs: 8206, row: 265, col: 61}]); tmp943 = 0; _aether.logStatement([{ofs: 8205, row: 265, col: 60}, {ofs: 8206, row: 265, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8198, row: 265, col: 53}, {ofs: 8207, row: 265, col: 62}]); tmp940 = tmp942[tmp943]; _aether.logStatement([{ofs: 8198, row: 265, col: 53}, {ofs: 8207, row: 265, col: 62}], _aether._userInfo, false);\n tmp941 = 'x';\n _aether.logStatementStart([{ofs: 8198, row: 265, col: 53}, {ofs: 8209, row: 265, col: 64}]); tmp939 = tmp940[tmp941]; _aether.logStatement([{ofs: 8198, row: 265, col: 53}, {ofs: 8209, row: 265, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8191, row: 265, col: 46}, {ofs: 8209, row: 265, col: 64}]); tmp936 = tmp938 - tmp939; _aether.logStatement([{ofs: 8191, row: 265, col: 46}, {ofs: 8209, row: 265, col: 64}], _aether._userInfo, false);\n tmp948 = points;\n tmp952 = points;\n tmp953 = 'length';\n _aether.logStatementStart([{ofs: 8221, row: 265, col: 76}, {ofs: 8234, row: 265, col: 89}]); tmp950 = tmp952[tmp953]; _aether.logStatement([{ofs: 8221, row: 265, col: 76}, {ofs: 8234, row: 265, col: 89}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8237, row: 265, col: 92}, {ofs: 8238, row: 265, col: 93}]); tmp951 = 1; _aether.logStatement([{ofs: 8237, row: 265, col: 92}, {ofs: 8238, row: 265, col: 93}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8221, row: 265, col: 76}, {ofs: 8238, row: 265, col: 93}]); tmp949 = tmp950 - tmp951; _aether.logStatement([{ofs: 8221, row: 265, col: 76}, {ofs: 8238, row: 265, col: 93}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8239, row: 265, col: 94}]); tmp946 = tmp948[tmp949]; _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8239, row: 265, col: 94}], _aether._userInfo, false);\n tmp947 = 'x';\n _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8241, row: 265, col: 96}]); tmp944 = tmp946[tmp947]; _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8241, row: 265, col: 96}], _aether._userInfo, false);\n tmp956 = points;\n _aether.logStatementStart([{ofs: 8251, row: 265, col: 106}, {ofs: 8252, row: 265, col: 107}]); tmp957 = 0; _aether.logStatement([{ofs: 8251, row: 265, col: 106}, {ofs: 8252, row: 265, col: 107}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8244, row: 265, col: 99}, {ofs: 8253, row: 265, col: 108}]); tmp954 = tmp956[tmp957]; _aether.logStatement([{ofs: 8244, row: 265, col: 99}, {ofs: 8253, row: 265, col: 108}], _aether._userInfo, false);\n tmp955 = 'x';\n _aether.logStatementStart([{ofs: 8244, row: 265, col: 99}, {ofs: 8255, row: 265, col: 110}]); tmp945 = tmp954[tmp955]; _aether.logStatement([{ofs: 8244, row: 265, col: 99}, {ofs: 8255, row: 265, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8255, row: 265, col: 110}]); tmp937 = tmp944 - tmp945; _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8255, row: 265, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8190, row: 265, col: 45}, {ofs: 8256, row: 265, col: 111}]); tmp935 = tmp936 / tmp937; _aether.logStatement([{ofs: 8190, row: 265, col: 45}, {ofs: 8256, row: 265, col: 111}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8149, row: 265, col: 4}, {ofs: 8258, row: 265, col: 113}]); upperBound = _aether.createAPIClone(_aether, tmp932(_aether.restoreAPIClone(_aether, tmp933), _aether.restoreAPIClone(_aether, tmp934), _aether.restoreAPIClone(_aether, tmp935))); _aether.logStatement([{ofs: 8149, row: 265, col: 4}, {ofs: 8258, row: 265, col: 113}], _aether._userInfo, false);\n tmp958 = lerp;\n tmp959 = highStart;\n tmp960 = lowEnd;\n tmp964 = time;\n tmp968 = points;\n _aether.logStatementStart([{ofs: 8319, row: 266, col: 60}, {ofs: 8320, row: 266, col: 61}]); tmp969 = 0; _aether.logStatement([{ofs: 8319, row: 266, col: 60}, {ofs: 8320, row: 266, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8312, row: 266, col: 53}, {ofs: 8321, row: 266, col: 62}]); tmp966 = tmp968[tmp969]; _aether.logStatement([{ofs: 8312, row: 266, col: 53}, {ofs: 8321, row: 266, col: 62}], _aether._userInfo, false);\n tmp967 = 'x';\n _aether.logStatementStart([{ofs: 8312, row: 266, col: 53}, {ofs: 8323, row: 266, col: 64}]); tmp965 = tmp966[tmp967]; _aether.logStatement([{ofs: 8312, row: 266, col: 53}, {ofs: 8323, row: 266, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8305, row: 266, col: 46}, {ofs: 8323, row: 266, col: 64}]); tmp962 = tmp964 - tmp965; _aether.logStatement([{ofs: 8305, row: 266, col: 46}, {ofs: 8323, row: 266, col: 64}], _aether._userInfo, false);\n tmp974 = points;\n tmp978 = points;\n tmp979 = 'length';\n _aether.logStatementStart([{ofs: 8335, row: 266, col: 76}, {ofs: 8348, row: 266, col: 89}]); tmp976 = tmp978[tmp979]; _aether.logStatement([{ofs: 8335, row: 266, col: 76}, {ofs: 8348, row: 266, col: 89}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8351, row: 266, col: 92}, {ofs: 8352, row: 266, col: 93}]); tmp977 = 1; _aether.logStatement([{ofs: 8351, row: 266, col: 92}, {ofs: 8352, row: 266, col: 93}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8335, row: 266, col: 76}, {ofs: 8352, row: 266, col: 93}]); tmp975 = tmp976 - tmp977; _aether.logStatement([{ofs: 8335, row: 266, col: 76}, {ofs: 8352, row: 266, col: 93}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8353, row: 266, col: 94}]); tmp972 = tmp974[tmp975]; _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8353, row: 266, col: 94}], _aether._userInfo, false);\n tmp973 = 'x';\n _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8355, row: 266, col: 96}]); tmp970 = tmp972[tmp973]; _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8355, row: 266, col: 96}], _aether._userInfo, false);\n tmp982 = points;\n _aether.logStatementStart([{ofs: 8365, row: 266, col: 106}, {ofs: 8366, row: 266, col: 107}]); tmp983 = 0; _aether.logStatement([{ofs: 8365, row: 266, col: 106}, {ofs: 8366, row: 266, col: 107}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8358, row: 266, col: 99}, {ofs: 8367, row: 266, col: 108}]); tmp980 = tmp982[tmp983]; _aether.logStatement([{ofs: 8358, row: 266, col: 99}, {ofs: 8367, row: 266, col: 108}], _aether._userInfo, false);\n tmp981 = 'x';\n _aether.logStatementStart([{ofs: 8358, row: 266, col: 99}, {ofs: 8369, row: 266, col: 110}]); tmp971 = tmp980[tmp981]; _aether.logStatement([{ofs: 8358, row: 266, col: 99}, {ofs: 8369, row: 266, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8369, row: 266, col: 110}]); tmp963 = tmp970 - tmp971; _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8369, row: 266, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8304, row: 266, col: 45}, {ofs: 8370, row: 266, col: 111}]); tmp961 = tmp962 / tmp963; _aether.logStatement([{ofs: 8304, row: 266, col: 45}, {ofs: 8370, row: 266, col: 111}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8263, row: 266, col: 4}, {ofs: 8372, row: 266, col: 113}]); lowerBound = _aether.createAPIClone(_aether, tmp958(_aether.restoreAPIClone(_aether, tmp959), _aether.restoreAPIClone(_aether, tmp960), _aether.restoreAPIClone(_aether, tmp961))); _aether.logStatement([{ofs: 8263, row: 266, col: 4}, {ofs: 8372, row: 266, col: 113}], _aether._userInfo, false);\n tmp984 = regFunc;\n tmp985 = time;\n _aether.logStatementStart([{ofs: 8382, row: 268, col: 4}, {ofs: 8411, row: 268, col: 33}]); estimate = _aether.createAPIClone(_aether, tmp984(_aether.restoreAPIClone(_aether, tmp985))); _aether.logStatement([{ofs: 8382, row: 268, col: 4}, {ofs: 8411, row: 268, col: 33}], _aether._userInfo, false);\n tmp987 = upperBound;\n tmp988 = estimate;\n tmp989 = lowerBound;\n _aether.logStatementStart([{ofs: 8433, row: 271, col: 11}, {ofs: 8467, row: 271, col: 45}]); tmp986 = [\n tmp987,\n tmp988,\n tmp989\n ]; _aether.logStatement([{ofs: 8433, row: 271, col: 11}, {ofs: 8467, row: 271, col: 45}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp986);\n }; _aether.logStatement([{ofs: 7702, row: 251, col: 0}, {ofs: 8470, row: 272, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11737, row: 400, col: 0}, {ofs: 12713, row: 428, col: 1}]); decideMilitaryToBuild = function (base) {\n var soldierPercent, friendlyLibs, libPercent, friendlyGrif, grifPercent, friendlyKnight, knightPercent, tmp990, tmp991, tmp992, tmp993, tmp994, tmp995, tmp996, tmp997, tmp998, tmp999, tmp1000, tmp1001, tmp1002, tmp1003, tmp1004, tmp1005, tmp1006, tmp1007, tmp1008, tmp1009, tmp1010, tmp1011, tmp1012, tmp1013, tmp1014, tmp1015, tmp1016, tmp1017, tmp1018, tmp1019, tmp1020, tmp1021, tmp1022, tmp1023, tmp1024, tmp1025, tmp1026, tmp1027, tmp1028, tmp1029, tmp1030, tmp1031, tmp1032, tmp1033, tmp1034, tmp1035, tmp1036, tmp1037, tmp1038, tmp1039, tmp1040, tmp1041, tmp1042, tmp1043, tmp1044, tmp1045, tmp1046, tmp1047, tmp1048, tmp1049, tmp1050, tmp1051, tmp1052, tmp1053, tmp1054, tmp1055, tmp1056, tmp1057, tmp1058, tmp1059, tmp1060, tmp1061, tmp1062, tmp1063, tmp1064, tmp1065; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp992 = friendlySoldiers;\n tmp993 = 'length';\n _aether.logStatementStart([{ofs: 11801, row: 401, col: 25}, {ofs: 11824, row: 401, col: 48}]); tmp990 = tmp992[tmp993]; _aether.logStatement([{ofs: 11801, row: 401, col: 25}, {ofs: 11824, row: 401, col: 48}], _aether._userInfo, false);\n tmp994 = militaryFriends;\n tmp995 = 'length';\n _aether.logStatementStart([{ofs: 11827, row: 401, col: 51}, {ofs: 11849, row: 401, col: 73}]); tmp991 = tmp994[tmp995]; _aether.logStatement([{ofs: 11827, row: 401, col: 51}, {ofs: 11849, row: 401, col: 73}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11780, row: 401, col: 4}, {ofs: 11850, row: 401, col: 74}]); soldierPercent = tmp990 / tmp991; _aether.logStatement([{ofs: 11780, row: 401, col: 4}, {ofs: 11850, row: 401, col: 74}], _aether._userInfo, false);\n tmp1000 = friendlySoldiers;\n tmp1001 = 'length';\n _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11887, row: 403, col: 31}]); tmp998 = tmp1000[tmp1001]; _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11887, row: 403, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11890, row: 403, col: 34}, {ofs: 11891, row: 403, col: 35}]); tmp999 = 3; _aether.logStatement([{ofs: 11890, row: 403, col: 34}, {ofs: 11891, row: 403, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11891, row: 403, col: 35}]); tmp997 = tmp998 < tmp999; _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11891, row: 403, col: 35}], _aether._userInfo, false);\n if (tmp997) {\n _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11917, row: 403, col: 61}]); tmp996 = tmp997; _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n } else {\n tmp1002 = soldierPercent;\n _aether.logStatementStart([{ofs: 11913, row: 403, col: 57}, {ofs: 11917, row: 403, col: 61}]); tmp1003 = 0.45; _aether.logStatement([{ofs: 11913, row: 403, col: 57}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11895, row: 403, col: 39}, {ofs: 11917, row: 403, col: 61}]); tmp996 = tmp1002 <= tmp1003; _aether.logStatement([{ofs: 11895, row: 403, col: 39}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n }\n if (tmp996) {\n tmp1005 = alliedTypes;\n tmp1006 = 'soldier';\n _aether.logStatementStart([{ofs: 11936, row: 404, col: 15}, {ofs: 11955, row: 404, col: 34}]); tmp1004 = tmp1005[tmp1006]; _aether.logStatement([{ofs: 11936, row: 404, col: 15}, {ofs: 11955, row: 404, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp1004);\n } else {\n ;\n }\n tmp1007 = filterType;\n tmp1010 = alliedTypes;\n tmp1011 = 'librarian';\n _aether.logStatementStart([{ofs: 12002, row: 407, col: 34}, {ofs: 12023, row: 407, col: 55}]); tmp1008 = tmp1010[tmp1011]; _aether.logStatement([{ofs: 12002, row: 407, col: 34}, {ofs: 12023, row: 407, col: 55}], _aether._userInfo, false);\n tmp1009 = militaryFriends;\n _aether.logStatementStart([{ofs: 11972, row: 407, col: 4}, {ofs: 12042, row: 407, col: 74}]); friendlyLibs = _aether.createAPIClone(_aether, tmp1007(_aether.restoreAPIClone(_aether, tmp1008), _aether.restoreAPIClone(_aether, tmp1009))); _aether.logStatement([{ofs: 11972, row: 407, col: 4}, {ofs: 12042, row: 407, col: 74}], _aether._userInfo, false);\n tmp1014 = friendlyLibs;\n tmp1015 = 'length';\n _aether.logStatementStart([{ofs: 12064, row: 408, col: 21}, {ofs: 12083, row: 408, col: 40}]); tmp1012 = tmp1014[tmp1015]; _aether.logStatement([{ofs: 12064, row: 408, col: 21}, {ofs: 12083, row: 408, col: 40}], _aether._userInfo, false);\n tmp1016 = militaryFriends;\n tmp1017 = 'length';\n _aether.logStatementStart([{ofs: 12086, row: 408, col: 43}, {ofs: 12108, row: 408, col: 65}]); tmp1013 = tmp1016[tmp1017]; _aether.logStatement([{ofs: 12086, row: 408, col: 43}, {ofs: 12108, row: 408, col: 65}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12047, row: 408, col: 4}, {ofs: 12109, row: 408, col: 66}]); libPercent = tmp1012 / tmp1013; _aether.logStatement([{ofs: 12047, row: 408, col: 4}, {ofs: 12109, row: 408, col: 66}], _aether._userInfo, false);\n tmp1022 = friendlyLibs;\n tmp1023 = 'length';\n _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12142, row: 410, col: 27}]); tmp1020 = tmp1022[tmp1023]; _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12142, row: 410, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12145, row: 410, col: 30}, {ofs: 12146, row: 410, col: 31}]); tmp1021 = 2; _aether.logStatement([{ofs: 12145, row: 410, col: 30}, {ofs: 12146, row: 410, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12146, row: 410, col: 31}]); tmp1019 = tmp1020 < tmp1021; _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12146, row: 410, col: 31}], _aether._userInfo, false);\n if (tmp1019) {\n _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12168, row: 410, col: 53}]); tmp1018 = tmp1019; _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n } else {\n tmp1024 = libPercent;\n _aether.logStatementStart([{ofs: 12164, row: 410, col: 49}, {ofs: 12168, row: 410, col: 53}]); tmp1025 = 0.33; _aether.logStatement([{ofs: 12164, row: 410, col: 49}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12150, row: 410, col: 35}, {ofs: 12168, row: 410, col: 53}]); tmp1018 = tmp1024 <= tmp1025; _aether.logStatement([{ofs: 12150, row: 410, col: 35}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n }\n if (tmp1018) {\n tmp1027 = alliedTypes;\n tmp1028 = 'librarian';\n _aether.logStatementStart([{ofs: 12187, row: 411, col: 15}, {ofs: 12208, row: 411, col: 36}]); tmp1026 = tmp1027[tmp1028]; _aether.logStatement([{ofs: 12187, row: 411, col: 15}, {ofs: 12208, row: 411, col: 36}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp1026);\n } else {\n ;\n }\n tmp1029 = filterType;\n tmp1032 = alliedTypes;\n tmp1033 = 'griffinRider';\n _aether.logStatementStart([{ofs: 12255, row: 414, col: 34}, {ofs: 12279, row: 414, col: 58}]); tmp1030 = tmp1032[tmp1033]; _aether.logStatement([{ofs: 12255, row: 414, col: 34}, {ofs: 12279, row: 414, col: 58}], _aether._userInfo, false);\n tmp1031 = militaryFriends;\n _aether.logStatementStart([{ofs: 12225, row: 414, col: 4}, {ofs: 12298, row: 414, col: 77}]); friendlyGrif = _aether.createAPIClone(_aether, tmp1029(_aether.restoreAPIClone(_aether, tmp1030), _aether.restoreAPIClone(_aether, tmp1031))); _aether.logStatement([{ofs: 12225, row: 414, col: 4}, {ofs: 12298, row: 414, col: 77}], _aether._userInfo, false);\n tmp1036 = friendlyGrif;\n tmp1037 = 'length';\n _aether.logStatementStart([{ofs: 12321, row: 415, col: 22}, {ofs: 12340, row: 415, col: 41}]); tmp1034 = tmp1036[tmp1037]; _aether.logStatement([{ofs: 12321, row: 415, col: 22}, {ofs: 12340, row: 415, col: 41}], _aether._userInfo, false);\n tmp1038 = militaryFriends;\n tmp1039 = 'length';\n _aether.logStatementStart([{ofs: 12343, row: 415, col: 44}, {ofs: 12365, row: 415, col: 66}]); tmp1035 = tmp1038[tmp1039]; _aether.logStatement([{ofs: 12343, row: 415, col: 44}, {ofs: 12365, row: 415, col: 66}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12303, row: 415, col: 4}, {ofs: 12366, row: 415, col: 67}]); grifPercent = tmp1034 / tmp1035; _aether.logStatement([{ofs: 12303, row: 415, col: 4}, {ofs: 12366, row: 415, col: 67}], _aether._userInfo, false);\n tmp1041 = grifPercent;\n _aether.logStatementStart([{ofs: 12394, row: 417, col: 22}, {ofs: 12399, row: 417, col: 27}]); tmp1042 = 0.125; _aether.logStatement([{ofs: 12394, row: 417, col: 22}, {ofs: 12399, row: 417, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12380, row: 417, col: 8}, {ofs: 12399, row: 417, col: 27}]); tmp1040 = tmp1041 < tmp1042; _aether.logStatement([{ofs: 12380, row: 417, col: 8}, {ofs: 12399, row: 417, col: 27}], _aether._userInfo, false);\n if (tmp1040) {\n tmp1044 = alliedTypes;\n tmp1045 = 'griffinRider';\n _aether.logStatementStart([{ofs: 12418, row: 418, col: 15}, {ofs: 12442, row: 418, col: 39}]); tmp1043 = tmp1044[tmp1045]; _aether.logStatement([{ofs: 12418, row: 418, col: 15}, {ofs: 12442, row: 418, col: 39}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp1043);\n } else {\n ;\n }\n tmp1046 = filterType;\n tmp1049 = alliedTypes;\n tmp1050 = 'knight';\n _aether.logStatementStart([{ofs: 12491, row: 421, col: 36}, {ofs: 12509, row: 421, col: 54}]); tmp1047 = tmp1049[tmp1050]; _aether.logStatement([{ofs: 12491, row: 421, col: 36}, {ofs: 12509, row: 421, col: 54}], _aether._userInfo, false);\n tmp1048 = militaryFriends;\n _aether.logStatementStart([{ofs: 12459, row: 421, col: 4}, {ofs: 12528, row: 421, col: 73}]); friendlyKnight = _aether.createAPIClone(_aether, tmp1046(_aether.restoreAPIClone(_aether, tmp1047), _aether.restoreAPIClone(_aether, tmp1048))); _aether.logStatement([{ofs: 12459, row: 421, col: 4}, {ofs: 12528, row: 421, col: 73}], _aether._userInfo, false);\n tmp1053 = friendlyKnight;\n tmp1054 = 'length';\n _aether.logStatementStart([{ofs: 12553, row: 422, col: 24}, {ofs: 12574, row: 422, col: 45}]); tmp1051 = tmp1053[tmp1054]; _aether.logStatement([{ofs: 12553, row: 422, col: 24}, {ofs: 12574, row: 422, col: 45}], _aether._userInfo, false);\n tmp1055 = militaryFriends;\n tmp1056 = 'length';\n _aether.logStatementStart([{ofs: 12577, row: 422, col: 48}, {ofs: 12599, row: 422, col: 70}]); tmp1052 = tmp1055[tmp1056]; _aether.logStatement([{ofs: 12577, row: 422, col: 48}, {ofs: 12599, row: 422, col: 70}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12533, row: 422, col: 4}, {ofs: 12600, row: 422, col: 71}]); knightPercent = tmp1051 / tmp1052; _aether.logStatement([{ofs: 12533, row: 422, col: 4}, {ofs: 12600, row: 422, col: 71}], _aether._userInfo, false);\n tmp1058 = knightPercent;\n _aether.logStatementStart([{ofs: 12625, row: 423, col: 24}, {ofs: 12630, row: 423, col: 29}]); tmp1059 = 0.1; _aether.logStatement([{ofs: 12625, row: 423, col: 24}, {ofs: 12630, row: 423, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12609, row: 423, col: 8}, {ofs: 12630, row: 423, col: 29}]); tmp1057 = tmp1058 < tmp1059; _aether.logStatement([{ofs: 12609, row: 423, col: 8}, {ofs: 12630, row: 423, col: 29}], _aether._userInfo, false);\n if (tmp1057) {\n tmp1061 = alliedTypes;\n tmp1062 = 'knight';\n _aether.logStatementStart([{ofs: 12649, row: 424, col: 15}, {ofs: 12667, row: 424, col: 33}]); tmp1060 = tmp1061[tmp1062]; _aether.logStatement([{ofs: 12649, row: 424, col: 15}, {ofs: 12667, row: 424, col: 33}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp1060);\n } else {\n ;\n }\n tmp1064 = alliedTypes;\n tmp1065 = 'soldier';\n _aether.logStatementStart([{ofs: 12691, row: 427, col: 11}, {ofs: 12710, row: 427, col: 30}]); tmp1063 = tmp1064[tmp1065]; _aether.logStatement([{ofs: 12691, row: 427, col: 11}, {ofs: 12710, row: 427, col: 30}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp1063);\n }; _aether.logStatement([{ofs: 11737, row: 400, col: 0}, {ofs: 12713, row: 428, col: 1}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 115, row: 3, col: 13}, {ofs: 124, row: 3, col: 22}]); tmp2 = 'peasant'; _aether.logStatement([{ofs: 115, row: 3, col: 13}, {ofs: 124, row: 3, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 139, row: 4, col: 13}, {ofs: 148, row: 4, col: 22}]); tmp3 = 'soldier'; _aether.logStatement([{ofs: 139, row: 4, col: 13}, {ofs: 148, row: 4, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 162, row: 5, col: 12}, {ofs: 170, row: 5, col: 20}]); tmp4 = 'knight'; _aether.logStatement([{ofs: 162, row: 5, col: 12}, {ofs: 170, row: 5, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 187, row: 6, col: 15}, {ofs: 198, row: 6, col: 26}]); tmp5 = 'librarian'; _aether.logStatement([{ofs: 187, row: 6, col: 15}, {ofs: 198, row: 6, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 218, row: 7, col: 18}, {ofs: 233, row: 7, col: 33}]); tmp6 = 'griffin-rider'; _aether.logStatement([{ofs: 218, row: 7, col: 18}, {ofs: 233, row: 7, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 248, row: 8, col: 13}, {ofs: 257, row: 8, col: 22}]); tmp7 = 'captain'; _aether.logStatement([{ofs: 248, row: 8, col: 13}, {ofs: 257, row: 8, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 82, row: 2, col: 0}, {ofs: 260, row: 9, col: 2}]); alliedTypes = {\n peasant: tmp2,\n soldier: tmp3,\n knight: tmp4,\n librarian: tmp5,\n griffinRider: tmp6,\n captain: tmp7\n }; _aether.logStatement([{ofs: 82, row: 2, col: 0}, {ofs: 260, row: 9, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 294, row: 12, col: 13}, {ofs: 300, row: 12, col: 19}]); tmp8 = 'peon'; _aether.logStatement([{ofs: 294, row: 12, col: 13}, {ofs: 300, row: 12, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 315, row: 13, col: 13}, {ofs: 325, row: 13, col: 23}]); tmp9 = 'munchkin'; _aether.logStatement([{ofs: 315, row: 13, col: 13}, {ofs: 325, row: 13, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 339, row: 14, col: 12}, {ofs: 345, row: 14, col: 18}]); tmp10 = 'ogre'; _aether.logStatement([{ofs: 339, row: 14, col: 12}, {ofs: 345, row: 14, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 362, row: 15, col: 15}, {ofs: 370, row: 15, col: 23}]); tmp11 = 'shaman'; _aether.logStatement([{ofs: 362, row: 15, col: 15}, {ofs: 370, row: 15, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 390, row: 16, col: 18}, {ofs: 401, row: 16, col: 29}]); tmp12 = 'fangrider'; _aether.logStatement([{ofs: 390, row: 16, col: 18}, {ofs: 401, row: 16, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 416, row: 17, col: 13}, {ofs: 425, row: 17, col: 22}]); tmp13 = 'brawler'; _aether.logStatement([{ofs: 416, row: 17, col: 13}, {ofs: 425, row: 17, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 262, row: 11, col: 0}, {ofs: 428, row: 18, col: 2}]); enemyTypes = {\n peasant: tmp8,\n soldier: tmp9,\n knight: tmp10,\n librarian: tmp11,\n griffinRider: tmp12,\n captain: tmp13\n }; _aether.logStatement([{ofs: 262, row: 11, col: 0}, {ofs: 428, row: 18, col: 2}], _aether._userInfo, false);\n tmp19 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp20 = 'buildables';\n _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 449, row: 20, col: 19}]); tmp17 = tmp19[tmp20]; _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 449, row: 20, col: 19}], _aether._userInfo, false);\n tmp18 = 'peasant';\n _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 457, row: 20, col: 27}]); tmp15 = tmp17[tmp18]; _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 457, row: 20, col: 27}], _aether._userInfo, false);\n tmp21 = 'undefined';\n tmp16 = __global[tmp21];\n _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 471, row: 20, col: 41}]); tmp14 = tmp15 === tmp16; _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 471, row: 20, col: 41}], _aether._userInfo, false);\n if (tmp14) {\n tmp = alliedTypes;\n alliedTypes = enemyTypes;\n enemyTypes = tmp;\n } else {\n ;\n }\n tmp22 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp23 = 'getItems';\n _aether.logStatementStart([{ofs: 6245, row: 206, col: 0}, {ofs: 6273, row: 206, col: 28}]); items = _aether.createAPIClone(_aether, tmp22[tmp23]()); _aether.logStatement([{ofs: 6245, row: 206, col: 0}, {ofs: 6273, row: 206, col: 28}], _aether._userInfo, false);\n tmp24 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp25 = 'getFriends';\n _aether.logStatementStart([{ofs: 6274, row: 207, col: 0}, {ofs: 6306, row: 207, col: 32}]); friends = _aether.createAPIClone(_aether, tmp24[tmp25]()); _aether.logStatement([{ofs: 6274, row: 207, col: 0}, {ofs: 6306, row: 207, col: 32}], _aether._userInfo, false);\n tmp26 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp27 = 'getEnemies';\n _aether.logStatementStart([{ofs: 6307, row: 208, col: 0}, {ofs: 6339, row: 208, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp26[tmp27]()); _aether.logStatement([{ofs: 6307, row: 208, col: 0}, {ofs: 6339, row: 208, col: 32}], _aether._userInfo, false);\n tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp31 = 'getByType';\n _aether.logStatementStart([{ofs: 6372, row: 210, col: 31}, {ofs: 6378, row: 210, col: 37}]); tmp32 = 'base'; _aether.logStatement([{ofs: 6372, row: 210, col: 31}, {ofs: 6378, row: 210, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6357, row: 210, col: 16}, {ofs: 6379, row: 210, col: 38}]); tmp28 = _aether.createAPIClone(_aether, tmp30[tmp31](_aether.restoreAPIClone(_aether, tmp32))); _aether.logStatement([{ofs: 6357, row: 210, col: 16}, {ofs: 6379, row: 210, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6380, row: 210, col: 39}, {ofs: 6381, row: 210, col: 40}]); tmp29 = 0; _aether.logStatement([{ofs: 6380, row: 210, col: 39}, {ofs: 6381, row: 210, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6341, row: 210, col: 0}, {ofs: 6383, row: 210, col: 42}]); enemyBase = tmp28[tmp29]; _aether.logStatement([{ofs: 6341, row: 210, col: 0}, {ofs: 6383, row: 210, col: 42}], _aether._userInfo, false);\n tmp33 = enemyBase;\n if (tmp33) {\n tmp34 = enemyBase;\n tmp35 = 'gold';\n _aether.logStatementStart([{ofs: 6412, row: 211, col: 28}, {ofs: 6426, row: 211, col: 42}]); enemyGold = tmp34[tmp35]; _aether.logStatement([{ofs: 6412, row: 211, col: 28}, {ofs: 6426, row: 211, col: 42}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 6429, row: 211, col: 45}, {ofs: 6430, row: 211, col: 46}]); enemyGold = 0; _aether.logStatement([{ofs: 6429, row: 211, col: 45}, {ofs: 6430, row: 211, col: 46}], _aether._userInfo, false);\n }\n tmp36 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp37 = 'getByType';\n tmp39 = alliedTypes;\n tmp40 = 'peasant';\n _aether.logStatementStart([{ofs: 6463, row: 213, col: 30}, {ofs: 6482, row: 213, col: 49}]); tmp38 = tmp39[tmp40]; _aether.logStatement([{ofs: 6463, row: 213, col: 30}, {ofs: 6482, row: 213, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6433, row: 213, col: 0}, {ofs: 6484, row: 213, col: 51}]); peasants = _aether.createAPIClone(_aether, tmp36[tmp37](_aether.restoreAPIClone(_aether, tmp38))); _aether.logStatement([{ofs: 6433, row: 213, col: 0}, {ofs: 6484, row: 213, col: 51}], _aether._userInfo, false);\n tmp41 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp42 = 'getByType';\n tmp44 = enemyTypes;\n tmp45 = 'peasant';\n _aether.logStatementStart([{ofs: 6512, row: 214, col: 27}, {ofs: 6530, row: 214, col: 45}]); tmp43 = tmp44[tmp45]; _aether.logStatement([{ofs: 6512, row: 214, col: 27}, {ofs: 6530, row: 214, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6485, row: 214, col: 0}, {ofs: 6532, row: 214, col: 47}]); peons = _aether.createAPIClone(_aether, tmp41[tmp42](_aether.restoreAPIClone(_aether, tmp43))); _aether.logStatement([{ofs: 6485, row: 214, col: 0}, {ofs: 6532, row: 214, col: 47}], _aether._userInfo, false);\n tmp46 = computeSpringAssignments;\n tmp47 = peasants;\n tmp48 = peons;\n tmp49 = items;\n tmp50 = computeAttractionSquared;\n _aether.logStatementStart([{ofs: 6534, row: 216, col: 0}, {ofs: 6627, row: 216, col: 93}]); assignments = _aether.createAPIClone(_aether, tmp46(_aether.restoreAPIClone(_aether, tmp47), _aether.restoreAPIClone(_aether, tmp48), _aether.restoreAPIClone(_aether, tmp49), _aether.restoreAPIClone(_aether, tmp50))); _aether.logStatement([{ofs: 6534, row: 216, col: 0}, {ofs: 6627, row: 216, col: 93}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6633, row: 217, col: 5}, {ofs: 6642, row: 217, col: 14}]); i = 0; _aether.logStatement([{ofs: 6633, row: 217, col: 5}, {ofs: 6642, row: 217, col: 14}], _aether._userInfo, false);\n tmp52 = i;\n tmp54 = assignments;\n tmp55 = 'length';\n _aether.logStatementStart([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}]); tmp53 = tmp54[tmp55]; _aether.logStatement([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}]); tmp51 = tmp52 < tmp53; _aether.logStatement([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n tmp62: {\n while (tmp51) {\n tmp63: {\n tmp64 = assignments;\n tmp65 = i;\n _aether.logStatementStart([{ofs: 6679, row: 218, col: 4}, {ofs: 6703, row: 218, col: 28}]); as = tmp64[tmp65]; _aether.logStatement([{ofs: 6679, row: 218, col: 4}, {ofs: 6703, row: 218, col: 28}], _aether._userInfo, false);\n tmp66 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp67 = 'command';\n tmp71 = as;\n tmp72 = 'src';\n _aether.logStatementStart([{ofs: 6721, row: 219, col: 17}, {ofs: 6727, row: 219, col: 23}]); tmp68 = tmp71[tmp72]; _aether.logStatement([{ofs: 6721, row: 219, col: 17}, {ofs: 6727, row: 219, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6729, row: 219, col: 25}, {ofs: 6735, row: 219, col: 31}]); tmp69 = 'move'; _aether.logStatement([{ofs: 6729, row: 219, col: 25}, {ofs: 6735, row: 219, col: 31}], _aether._userInfo, false);\n tmp73 = as;\n tmp74 = 'target';\n _aether.logStatementStart([{ofs: 6737, row: 219, col: 33}, {ofs: 6746, row: 219, col: 42}]); tmp70 = tmp73[tmp74]; _aether.logStatement([{ofs: 6737, row: 219, col: 33}, {ofs: 6746, row: 219, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6708, row: 219, col: 4}, {ofs: 6747, row: 219, col: 43}]); tmp75 = _aether.createAPIClone(_aether, tmp66[tmp67](_aether.restoreAPIClone(_aether, tmp68), _aether.restoreAPIClone(_aether, tmp69), _aether.restoreAPIClone(_aether, tmp70))); _aether.logStatement([{ofs: 6708, row: 219, col: 4}, {ofs: 6747, row: 219, col: 43}], _aether._userInfo, false);\n }\n tmp60 = i;\n tmp61 = 1;\n i = tmp60 + tmp61;\n tmp56 = i;\n tmp58 = assignments;\n tmp59 = 'length';\n _aether.logStatementStart([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}]); tmp57 = tmp58[tmp59]; _aether.logStatement([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}]); tmp51 = tmp56 < tmp57; _aether.logStatement([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n }\n }\n tmp76 = filterNotType;\n tmp79 = alliedTypes;\n tmp80 = 'peasant';\n _aether.logStatementStart([{ofs: 8590, row: 276, col: 36}, {ofs: 8609, row: 276, col: 55}]); tmp77 = tmp79[tmp80]; _aether.logStatement([{ofs: 8590, row: 276, col: 36}, {ofs: 8609, row: 276, col: 55}], _aether._userInfo, false);\n tmp78 = friends;\n _aether.logStatementStart([{ofs: 8554, row: 276, col: 0}, {ofs: 8620, row: 276, col: 66}]); militaryFriends = _aether.createAPIClone(_aether, tmp76(_aether.restoreAPIClone(_aether, tmp77), _aether.restoreAPIClone(_aether, tmp78))); _aether.logStatement([{ofs: 8554, row: 276, col: 0}, {ofs: 8620, row: 276, col: 66}], _aether._userInfo, false);\n tmp81 = filterType;\n tmp84 = alliedTypes;\n tmp85 = 'soldier';\n _aether.logStatementStart([{ofs: 8655, row: 277, col: 34}, {ofs: 8674, row: 277, col: 53}]); tmp82 = tmp84[tmp85]; _aether.logStatement([{ofs: 8655, row: 277, col: 34}, {ofs: 8674, row: 277, col: 53}], _aether._userInfo, false);\n tmp83 = friends;\n _aether.logStatementStart([{ofs: 8621, row: 277, col: 0}, {ofs: 8685, row: 277, col: 64}]); friendlySoldiers = _aether.createAPIClone(_aether, tmp81(_aether.restoreAPIClone(_aether, tmp82), _aether.restoreAPIClone(_aether, tmp83))); _aether.logStatement([{ofs: 8621, row: 277, col: 0}, {ofs: 8685, row: 277, col: 64}], _aether._userInfo, false);\n tmp86 = filterNotType;\n _aether.logStatementStart([{ofs: 8722, row: 278, col: 36}, {ofs: 8728, row: 278, col: 42}]); tmp87 = 'base'; _aether.logStatement([{ofs: 8722, row: 278, col: 36}, {ofs: 8728, row: 278, col: 42}], _aether._userInfo, false);\n tmp89 = filterNotType;\n tmp92 = enemyTypes;\n tmp93 = 'peasant';\n _aether.logStatementStart([{ofs: 8744, row: 278, col: 58}, {ofs: 8762, row: 278, col: 76}]); tmp90 = tmp92[tmp93]; _aether.logStatement([{ofs: 8744, row: 278, col: 58}, {ofs: 8762, row: 278, col: 76}], _aether._userInfo, false);\n tmp91 = enemies;\n _aether.logStatementStart([{ofs: 8730, row: 278, col: 44}, {ofs: 8772, row: 278, col: 86}]); tmp88 = _aether.createAPIClone(_aether, tmp89(_aether.restoreAPIClone(_aether, tmp90), _aether.restoreAPIClone(_aether, tmp91))); _aether.logStatement([{ofs: 8730, row: 278, col: 44}, {ofs: 8772, row: 278, col: 86}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8686, row: 278, col: 0}, {ofs: 8774, row: 278, col: 88}]); militaryEnemies = _aether.createAPIClone(_aether, tmp86(_aether.restoreAPIClone(_aether, tmp87), _aether.restoreAPIClone(_aether, tmp88))); _aether.logStatement([{ofs: 8686, row: 278, col: 0}, {ofs: 8774, row: 278, col: 88}], _aether._userInfo, false);\n tmp94 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp95 = 'getNearest';\n tmp96 = militaryEnemies;\n _aether.logStatementStart([{ofs: 8775, row: 279, col: 0}, {ofs: 8827, row: 279, col: 52}]); nearestEnemy = _aether.createAPIClone(_aether, tmp94[tmp95](_aether.restoreAPIClone(_aether, tmp96))); _aether.logStatement([{ofs: 8775, row: 279, col: 0}, {ofs: 8827, row: 279, col: 52}], _aether._userInfo, false);\n tmp100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp101 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 8915, row: 283, col: 4}, {ofs: 8936, row: 283, col: 25}]); tmp98 = tmp100[tmp101]; _aether.logStatement([{ofs: 8915, row: 283, col: 4}, {ofs: 8936, row: 283, col: 25}], _aether._userInfo, false);\n tmp102 = 'undefined';\n tmp99 = __global[tmp102];\n _aether.logStatementStart([{ofs: 8915, row: 283, col: 4}, {ofs: 8950, row: 283, col: 39}]); tmp97 = tmp98 === tmp99; _aether.logStatement([{ofs: 8915, row: 283, col: 4}, {ofs: 8950, row: 283, col: 39}], _aether._userInfo, false);\n if (tmp97) {\n tmp103 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp104 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 8958, row: 284, col: 4}, {ofs: 8985, row: 284, col: 31}]); tmp105 = []; _aether.logStatement([{ofs: 8958, row: 284, col: 4}, {ofs: 8985, row: 284, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8958, row: 284, col: 4}, {ofs: 8984, row: 284, col: 30}]); tmp103[tmp104] = tmp105; _aether.logStatement([{ofs: 8958, row: 284, col: 4}, {ofs: 8984, row: 284, col: 30}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp109 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp110 = 'counter';\n _aether.logStatementStart([{ofs: 8993, row: 287, col: 4}, {ofs: 9005, row: 287, col: 16}]); tmp107 = tmp109[tmp110]; _aether.logStatement([{ofs: 8993, row: 287, col: 4}, {ofs: 9005, row: 287, col: 16}], _aether._userInfo, false);\n tmp111 = 'undefined';\n tmp108 = __global[tmp111];\n _aether.logStatementStart([{ofs: 8993, row: 287, col: 4}, {ofs: 9019, row: 287, col: 30}]); tmp106 = tmp107 === tmp108; _aether.logStatement([{ofs: 8993, row: 287, col: 4}, {ofs: 9019, row: 287, col: 30}], _aether._userInfo, false);\n if (tmp106) {\n tmp112 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp113 = 'counter';\n _aether.logStatementStart([{ofs: 9027, row: 288, col: 4}, {ofs: 9044, row: 288, col: 21}]); tmp114 = 0; _aether.logStatement([{ofs: 9027, row: 288, col: 4}, {ofs: 9044, row: 288, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9027, row: 288, col: 4}, {ofs: 9043, row: 288, col: 20}]); tmp112[tmp113] = tmp114; _aether.logStatement([{ofs: 9027, row: 288, col: 4}, {ofs: 9043, row: 288, col: 20}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 9048, row: 291, col: 0}, {ofs: 9082, row: 291, col: 34}]); PREDICTOR_HISTORY_LENGTH = 25; _aether.logStatement([{ofs: 9048, row: 291, col: 0}, {ofs: 9082, row: 291, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9083, row: 292, col: 0}, {ofs: 9117, row: 292, col: 34}]); PREDICTOR_SAMPLE_INTERVAL = 4; _aether.logStatement([{ofs: 9083, row: 292, col: 0}, {ofs: 9117, row: 292, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9118, row: 293, col: 0}, {ofs: 9152, row: 293, col: 34}]); PREDICTOR_LOOKAHEAD_TIME = 17; _aether.logStatement([{ofs: 9118, row: 293, col: 0}, {ofs: 9152, row: 293, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9154, row: 295, col: 0}, {ofs: 9178, row: 295, col: 24}]); enemyTotalWorth = 0; _aether.logStatement([{ofs: 9154, row: 295, col: 0}, {ofs: 9178, row: 295, col: 24}], _aether._userInfo, false);\n tmp115 = enemyBase;\n if (tmp115) {\n tmp118 = valuateFighters;\n tmp120 = enemyBase;\n tmp121 = 'built';\n _aether.logStatementStart([{ofs: 9234, row: 297, col: 38}, {ofs: 9249, row: 297, col: 53}]); tmp119 = tmp120[tmp121]; _aether.logStatement([{ofs: 9234, row: 297, col: 38}, {ofs: 9249, row: 297, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9218, row: 297, col: 22}, {ofs: 9250, row: 297, col: 54}]); tmp116 = _aether.createAPIClone(_aether, tmp118(_aether.restoreAPIClone(_aether, tmp119))); _aether.logStatement([{ofs: 9218, row: 297, col: 22}, {ofs: 9250, row: 297, col: 54}], _aether._userInfo, false);\n tmp117 = enemyGold;\n _aether.logStatementStart([{ofs: 9200, row: 297, col: 4}, {ofs: 9263, row: 297, col: 67}]); enemyTotalWorth = tmp116 + tmp117; _aether.logStatement([{ofs: 9200, row: 297, col: 4}, {ofs: 9263, row: 297, col: 67}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp128 = 'counter';\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp125 = tmp127[tmp128]; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp130 = 1; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp129 = tmp125 + tmp130; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp127[tmp128] = tmp129; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n tmp126 = PREDICTOR_SAMPLE_INTERVAL;\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9313, row: 300, col: 46}]); tmp123 = tmp125 % tmp126; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9313, row: 300, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9318, row: 300, col: 51}, {ofs: 9319, row: 300, col: 52}]); tmp124 = 0; _aether.logStatement([{ofs: 9318, row: 300, col: 51}, {ofs: 9319, row: 300, col: 52}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9319, row: 300, col: 52}]); tmp122 = tmp123 === tmp124; _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9319, row: 300, col: 52}], _aether._userInfo, false);\n if (tmp122) {\n tmp133 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp134 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 9327, row: 301, col: 4}, {ofs: 9348, row: 301, col: 25}]); tmp131 = tmp133[tmp134]; _aether.logStatement([{ofs: 9327, row: 301, col: 4}, {ofs: 9348, row: 301, col: 25}], _aether._userInfo, false);\n tmp132 = 'push';\n tmp138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp139 = 'now';\n _aether.logStatementStart([{ofs: 9358, row: 301, col: 35}, {ofs: 9368, row: 301, col: 45}]); tmp136 = _aether.createAPIClone(_aether, tmp138[tmp139]()); _aether.logStatement([{ofs: 9358, row: 301, col: 35}, {ofs: 9368, row: 301, col: 45}], _aether._userInfo, false);\n tmp137 = enemyTotalWorth;\n _aether.logStatementStart([{ofs: 9354, row: 301, col: 31}, {ofs: 9389, row: 301, col: 66}]); tmp135 = {\n x: tmp136,\n y: tmp137\n }; _aether.logStatement([{ofs: 9354, row: 301, col: 31}, {ofs: 9389, row: 301, col: 66}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9327, row: 301, col: 4}, {ofs: 9390, row: 301, col: 67}]); tmp140 = _aether.createAPIClone(_aether, tmp131[tmp132](_aether.restoreAPIClone(_aether, tmp135))); _aether.logStatement([{ofs: 9327, row: 301, col: 4}, {ofs: 9390, row: 301, col: 67}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp146 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp147 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9420, row: 304, col: 25}]); tmp144 = tmp146[tmp147]; _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9420, row: 304, col: 25}], _aether._userInfo, false);\n tmp145 = 'length';\n _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9427, row: 304, col: 32}]); tmp142 = tmp144[tmp145]; _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9427, row: 304, col: 32}], _aether._userInfo, false);\n tmp143 = PREDICTOR_HISTORY_LENGTH;\n _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9454, row: 304, col: 59}]); tmp141 = tmp142 > tmp143; _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9454, row: 304, col: 59}], _aether._userInfo, false);\n if (tmp141) {\n tmp150 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp151 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 9462, row: 305, col: 4}, {ofs: 9483, row: 305, col: 25}]); tmp148 = tmp150[tmp151]; _aether.logStatement([{ofs: 9462, row: 305, col: 4}, {ofs: 9483, row: 305, col: 25}], _aether._userInfo, false);\n tmp149 = 'shift';\n _aether.logStatementStart([{ofs: 9462, row: 305, col: 4}, {ofs: 9491, row: 305, col: 33}]); tmp152 = _aether.createAPIClone(_aether, tmp148[tmp149]()); _aether.logStatement([{ofs: 9462, row: 305, col: 4}, {ofs: 9491, row: 305, col: 33}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp153 = valuateFighters;\n tmp154 = militaryFriends;\n _aether.logStatementStart([{ofs: 9496, row: 308, col: 0}, {ofs: 9555, row: 308, col: 59}]); ourMilitaryStrength = _aether.createAPIClone(_aether, tmp153(_aether.restoreAPIClone(_aether, tmp154))); _aether.logStatement([{ofs: 9496, row: 308, col: 0}, {ofs: 9555, row: 308, col: 59}], _aether._userInfo, false);\n tmp155 = valuateFighters;\n tmp156 = militaryEnemies;\n _aether.logStatementStart([{ofs: 9556, row: 309, col: 0}, {ofs: 9617, row: 309, col: 61}]); enemyMilitaryStrength = _aether.createAPIClone(_aether, tmp155(_aether.restoreAPIClone(_aether, tmp156))); _aether.logStatement([{ofs: 9556, row: 309, col: 0}, {ofs: 9617, row: 309, col: 61}], _aether._userInfo, false);\n tmp157 = ourMilitaryStrength;\n tmp159 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp160 = 'gold';\n _aether.logStatementStart([{ofs: 9659, row: 311, col: 40}, {ofs: 9668, row: 311, col: 49}]); tmp158 = tmp159[tmp160]; _aether.logStatement([{ofs: 9659, row: 311, col: 40}, {ofs: 9668, row: 311, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9619, row: 311, col: 0}, {ofs: 9669, row: 311, col: 50}]); ourStrength = tmp157 + tmp158; _aether.logStatement([{ofs: 9619, row: 311, col: 0}, {ofs: 9669, row: 311, col: 50}], _aether._userInfo, false);\n tmp161 = enemyMilitaryStrength;\n tmp162 = enemyGold;\n _aether.logStatementStart([{ofs: 9670, row: 312, col: 0}, {ofs: 9724, row: 312, col: 54}]); enemyStrength = tmp161 + tmp162; _aether.logStatement([{ofs: 9670, row: 312, col: 0}, {ofs: 9724, row: 312, col: 54}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9725, row: 313, col: 0}, {ofs: 9758, row: 313, col: 33}]); enemyStrengthForecast = null; _aether.logStatement([{ofs: 9725, row: 313, col: 0}, {ofs: 9758, row: 313, col: 33}], _aether._userInfo, false);\n tmp168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp169 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9785, row: 315, col: 25}]); tmp166 = tmp168[tmp169]; _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9785, row: 315, col: 25}], _aether._userInfo, false);\n tmp167 = 'length';\n _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9792, row: 315, col: 32}]); tmp164 = tmp166[tmp167]; _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9792, row: 315, col: 32}], _aether._userInfo, false);\n tmp165 = PREDICTOR_HISTORY_LENGTH;\n _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9820, row: 315, col: 60}]); tmp163 = tmp164 >= tmp165; _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9820, row: 315, col: 60}], _aether._userInfo, false);\n if (tmp163) {\n tmp170 = estimateHighLow;\n tmp173 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp174 = 'enemyGoldHistory';\n _aether.logStatementStart([{ofs: 9859, row: 316, col: 35}, {ofs: 9880, row: 316, col: 56}]); tmp171 = tmp173[tmp174]; _aether.logStatement([{ofs: 9859, row: 316, col: 35}, {ofs: 9880, row: 316, col: 56}], _aether._userInfo, false);\n tmp177 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp178 = 'now';\n _aether.logStatementStart([{ofs: 9882, row: 316, col: 58}, {ofs: 9892, row: 316, col: 68}]); tmp175 = _aether.createAPIClone(_aether, tmp177[tmp178]()); _aether.logStatement([{ofs: 9882, row: 316, col: 58}, {ofs: 9892, row: 316, col: 68}], _aether._userInfo, false);\n tmp176 = PREDICTOR_LOOKAHEAD_TIME;\n _aether.logStatementStart([{ofs: 9882, row: 316, col: 58}, {ofs: 9919, row: 316, col: 95}]); tmp172 = tmp175 + tmp176; _aether.logStatement([{ofs: 9882, row: 316, col: 58}, {ofs: 9919, row: 316, col: 95}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9828, row: 316, col: 4}, {ofs: 9921, row: 316, col: 97}]); highLowE = _aether.createAPIClone(_aether, tmp170(_aether.restoreAPIClone(_aether, tmp171), _aether.restoreAPIClone(_aether, tmp172))); _aether.logStatement([{ofs: 9828, row: 316, col: 4}, {ofs: 9921, row: 316, col: 97}], _aether._userInfo, false);\n tmp181 = highLowE;\n _aether.logStatementStart([{ofs: 9958, row: 317, col: 36}, {ofs: 9959, row: 317, col: 37}]); tmp182 = 0; _aether.logStatement([{ofs: 9958, row: 317, col: 36}, {ofs: 9959, row: 317, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9949, row: 317, col: 27}, {ofs: 9960, row: 317, col: 38}]); tmp179 = tmp181[tmp182]; _aether.logStatement([{ofs: 9949, row: 317, col: 27}, {ofs: 9960, row: 317, col: 38}], _aether._userInfo, false);\n tmp180 = enemyTotalWorth;\n _aether.logStatementStart([{ofs: 9926, row: 317, col: 4}, {ofs: 9979, row: 317, col: 57}]); futureEnemyBonus = tmp179 - tmp180; _aether.logStatement([{ofs: 9926, row: 317, col: 4}, {ofs: 9979, row: 317, col: 57}], _aether._userInfo, false);\n tmp183 = enemyStrength;\n tmp184 = futureEnemyBonus;\n _aether.logStatementStart([{ofs: 9985, row: 319, col: 4}, {ofs: 10042, row: 319, col: 61}]); enemyStrengthForecast = tmp183 + tmp184; _aether.logStatement([{ofs: 9985, row: 319, col: 4}, {ofs: 10042, row: 319, col: 61}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 10161, row: 325, col: 10}, {ofs: 10172, row: 325, col: 21}]); tmp185 = 'doNothing'; _aether.logStatement([{ofs: 10161, row: 325, col: 10}, {ofs: 10172, row: 325, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10197, row: 327, col: 18}, {ofs: 10236, row: 329, col: 5}]); tmp186 = function () {\n var tmp188; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 10225, row: 328, col: 15}, {ofs: 10229, row: 328, col: 19}]); tmp188 = true; _aether.logStatement([{ofs: 10225, row: 328, col: 15}, {ofs: 10229, row: 328, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp188);\n }; _aether.logStatement([{ofs: 10197, row: 327, col: 18}, {ofs: 10236, row: 329, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10268, row: 331, col: 21}, {ofs: 10307, row: 333, col: 5}]); tmp187 = function () {\n var tmp189; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 10296, row: 332, col: 15}, {ofs: 10300, row: 332, col: 19}]); tmp189 = null; _aether.logStatement([{ofs: 10296, row: 332, col: 15}, {ofs: 10300, row: 332, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp189);\n }; _aether.logStatement([{ofs: 10268, row: 331, col: 21}, {ofs: 10307, row: 333, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10128, row: 324, col: 0}, {ofs: 10310, row: 334, col: 2}]); doNothingState = {\n name: tmp185,\n wantsControl: tmp186,\n selectBuildType: tmp187\n }; _aether.logStatement([{ofs: 10128, row: 324, col: 0}, {ofs: 10310, row: 334, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10343, row: 337, col: 10}, {ofs: 10352, row: 337, col: 19}]); tmp190 = 'collect'; _aether.logStatement([{ofs: 10343, row: 337, col: 10}, {ofs: 10352, row: 337, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10377, row: 339, col: 18}, {ofs: 10963, row: 358, col: 5}]); tmp191 = function (base) {\n var coinsPerPeasant, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp196 = peasants;\n tmp197 = 'length';\n _aether.logStatementStart([{ofs: 10451, row: 341, col: 13}, {ofs: 10466, row: 341, col: 28}]); tmp194 = tmp196[tmp197]; _aether.logStatement([{ofs: 10451, row: 341, col: 13}, {ofs: 10466, row: 341, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10469, row: 341, col: 31}, {ofs: 10470, row: 341, col: 32}]); tmp195 = 1; _aether.logStatement([{ofs: 10469, row: 341, col: 31}, {ofs: 10470, row: 341, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10451, row: 341, col: 13}, {ofs: 10470, row: 341, col: 32}]); tmp193 = tmp194 < tmp195; _aether.logStatement([{ofs: 10451, row: 341, col: 13}, {ofs: 10470, row: 341, col: 32}], _aether._userInfo, false);\n if (tmp193) {\n _aether.logStatementStart([{ofs: 10493, row: 342, col: 19}, {ofs: 10497, row: 342, col: 23}]); tmp198 = true; _aether.logStatement([{ofs: 10493, row: 342, col: 19}, {ofs: 10497, row: 342, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp198);\n } else {\n ;\n }\n tmp202 = enemyGold;\n _aether.logStatementStart([{ofs: 10597, row: 346, col: 25}, {ofs: 10599, row: 346, col: 27}]); tmp203 = 70; _aether.logStatement([{ofs: 10597, row: 346, col: 25}, {ofs: 10599, row: 346, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10599, row: 346, col: 27}]); tmp201 = tmp202 <= tmp203; _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10599, row: 346, col: 27}], _aether._userInfo, false);\n if (tmp201) {\n tmp206 = peasants;\n tmp207 = 'length';\n _aether.logStatementStart([{ofs: 10603, row: 346, col: 31}, {ofs: 10618, row: 346, col: 46}]); tmp204 = tmp206[tmp207]; _aether.logStatement([{ofs: 10603, row: 346, col: 31}, {ofs: 10618, row: 346, col: 46}], _aether._userInfo, false);\n tmp208 = peons;\n tmp209 = 'length';\n _aether.logStatementStart([{ofs: 10621, row: 346, col: 49}, {ofs: 10633, row: 346, col: 61}]); tmp205 = tmp208[tmp209]; _aether.logStatement([{ofs: 10621, row: 346, col: 49}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10603, row: 346, col: 31}, {ofs: 10633, row: 346, col: 61}]); tmp200 = tmp204 < tmp205; _aether.logStatement([{ofs: 10603, row: 346, col: 31}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10633, row: 346, col: 61}]); tmp200 = tmp201; _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n }\n if (tmp200) {\n tmp212 = peasants;\n tmp213 = 'length';\n _aether.logStatementStart([{ofs: 10637, row: 346, col: 65}, {ofs: 10652, row: 346, col: 80}]); tmp210 = tmp212[tmp213]; _aether.logStatement([{ofs: 10637, row: 346, col: 65}, {ofs: 10652, row: 346, col: 80}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10655, row: 346, col: 83}, {ofs: 10656, row: 346, col: 84}]); tmp211 = 6; _aether.logStatement([{ofs: 10655, row: 346, col: 83}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10637, row: 346, col: 65}, {ofs: 10656, row: 346, col: 84}]); tmp199 = tmp210 < tmp211; _aether.logStatement([{ofs: 10637, row: 346, col: 65}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10656, row: 346, col: 84}]); tmp199 = tmp200; _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n }\n if (tmp199) {\n _aether.logStatementStart([{ofs: 10679, row: 347, col: 19}, {ofs: 10683, row: 347, col: 23}]); tmp214 = true; _aether.logStatement([{ofs: 10679, row: 347, col: 19}, {ofs: 10683, row: 347, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp214);\n } else {\n ;\n }\n tmp217 = items;\n tmp218 = 'length';\n _aether.logStatementStart([{ofs: 10824, row: 352, col: 30}, {ofs: 10836, row: 352, col: 42}]); tmp215 = tmp217[tmp218]; _aether.logStatement([{ofs: 10824, row: 352, col: 30}, {ofs: 10836, row: 352, col: 42}], _aether._userInfo, false);\n tmp219 = peasants;\n tmp220 = 'length';\n _aether.logStatementStart([{ofs: 10839, row: 352, col: 45}, {ofs: 10854, row: 352, col: 60}]); tmp216 = tmp219[tmp220]; _aether.logStatement([{ofs: 10839, row: 352, col: 45}, {ofs: 10854, row: 352, col: 60}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10802, row: 352, col: 8}, {ofs: 10855, row: 352, col: 61}]); coinsPerPeasant = tmp215 / tmp216; _aether.logStatement([{ofs: 10802, row: 352, col: 8}, {ofs: 10855, row: 352, col: 61}], _aether._userInfo, false);\n tmp222 = coinsPerPeasant;\n _aether.logStatementStart([{ofs: 10887, row: 353, col: 31}, {ofs: 10888, row: 353, col: 32}]); tmp223 = 2; _aether.logStatement([{ofs: 10887, row: 353, col: 31}, {ofs: 10888, row: 353, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10868, row: 353, col: 12}, {ofs: 10888, row: 353, col: 32}]); tmp221 = tmp222 >= tmp223; _aether.logStatement([{ofs: 10868, row: 353, col: 12}, {ofs: 10888, row: 353, col: 32}], _aether._userInfo, false);\n if (tmp221) {\n _aether.logStatementStart([{ofs: 10911, row: 354, col: 19}, {ofs: 10915, row: 354, col: 23}]); tmp224 = true; _aether.logStatement([{ofs: 10911, row: 354, col: 19}, {ofs: 10915, row: 354, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp224);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 10951, row: 357, col: 15}, {ofs: 10956, row: 357, col: 20}]); tmp225 = false; _aether.logStatement([{ofs: 10951, row: 357, col: 15}, {ofs: 10956, row: 357, col: 20}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp225);\n }; _aether.logStatement([{ofs: 10377, row: 339, col: 18}, {ofs: 10963, row: 358, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10995, row: 360, col: 21}, {ofs: 11053, row: 362, col: 5}]); tmp192 = function (base) {\n var tmp226, tmp227, tmp228; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp227 = alliedTypes;\n tmp228 = 'peasant';\n _aether.logStatementStart([{ofs: 11027, row: 361, col: 15}, {ofs: 11046, row: 361, col: 34}]); tmp226 = tmp227[tmp228]; _aether.logStatement([{ofs: 11027, row: 361, col: 15}, {ofs: 11046, row: 361, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp226);\n }; _aether.logStatement([{ofs: 10995, row: 360, col: 21}, {ofs: 11053, row: 362, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10312, row: 336, col: 0}, {ofs: 11056, row: 363, col: 2}]); collectState = {\n name: tmp190,\n wantsControl: tmp191,\n selectBuildType: tmp192\n }; _aether.logStatement([{ofs: 10312, row: 336, col: 0}, {ofs: 11056, row: 363, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11086, row: 366, col: 10}, {ofs: 11092, row: 366, col: 16}]); tmp229 = 'poke'; _aether.logStatement([{ofs: 11086, row: 366, col: 10}, {ofs: 11092, row: 366, col: 16}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11117, row: 368, col: 18}, {ofs: 11167, row: 370, col: 5}]); tmp230 = function (base) {\n var tmp232, tmp233, tmp234, tmp235; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp234 = base;\n tmp235 = 'poked';\n _aether.logStatementStart([{ofs: 11150, row: 369, col: 16}, {ofs: 11160, row: 369, col: 26}]); tmp233 = tmp234[tmp235]; _aether.logStatement([{ofs: 11150, row: 369, col: 16}, {ofs: 11160, row: 369, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11149, row: 369, col: 15}, {ofs: 11160, row: 369, col: 26}]); tmp232 = !tmp233; _aether.logStatement([{ofs: 11149, row: 369, col: 15}, {ofs: 11160, row: 369, col: 26}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp232);\n }; _aether.logStatement([{ofs: 11117, row: 368, col: 18}, {ofs: 11167, row: 370, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11199, row: 372, col: 21}, {ofs: 11363, row: 379, col: 5}]); tmp231 = function (base) {\n var tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp239 = base;\n tmp240 = 'gold';\n _aether.logStatementStart([{ofs: 11228, row: 373, col: 12}, {ofs: 11237, row: 373, col: 21}]); tmp237 = tmp239[tmp240]; _aether.logStatement([{ofs: 11228, row: 373, col: 12}, {ofs: 11237, row: 373, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11241, row: 373, col: 25}, {ofs: 11243, row: 373, col: 27}]); tmp238 = 10; _aether.logStatement([{ofs: 11241, row: 373, col: 25}, {ofs: 11243, row: 373, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11228, row: 373, col: 12}, {ofs: 11243, row: 373, col: 27}]); tmp236 = tmp237 >= tmp238; _aether.logStatement([{ofs: 11228, row: 373, col: 12}, {ofs: 11243, row: 373, col: 27}], _aether._userInfo, false);\n if (tmp236) {\n tmp241 = base;\n tmp242 = 'poked';\n _aether.logStatementStart([{ofs: 11259, row: 374, col: 12}, {ofs: 11277, row: 374, col: 30}]); tmp243 = true; _aether.logStatement([{ofs: 11259, row: 374, col: 12}, {ofs: 11277, row: 374, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11259, row: 374, col: 12}, {ofs: 11276, row: 374, col: 29}]); tmp241[tmp242] = tmp243; _aether.logStatement([{ofs: 11259, row: 374, col: 12}, {ofs: 11276, row: 374, col: 29}], _aether._userInfo, false);\n tmp245 = alliedTypes;\n tmp246 = 'soldier';\n _aether.logStatementStart([{ofs: 11297, row: 375, col: 19}, {ofs: 11316, row: 375, col: 38}]); tmp244 = tmp245[tmp246]; _aether.logStatement([{ofs: 11297, row: 375, col: 19}, {ofs: 11316, row: 375, col: 38}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp244);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 11352, row: 378, col: 15}, {ofs: 11356, row: 378, col: 19}]); tmp247 = null; _aether.logStatement([{ofs: 11352, row: 378, col: 15}, {ofs: 11356, row: 378, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp247);\n }; _aether.logStatement([{ofs: 11199, row: 372, col: 21}, {ofs: 11363, row: 379, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11058, row: 365, col: 0}, {ofs: 11366, row: 380, col: 2}]); pokeState = {\n name: tmp229,\n wantsControl: tmp230,\n selectBuildType: tmp231\n }; _aether.logStatement([{ofs: 11058, row: 365, col: 0}, {ofs: 11366, row: 380, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11401, row: 383, col: 10}, {ofs: 11412, row: 383, col: 21}]); tmp248 = 'stockpile'; _aether.logStatement([{ofs: 11401, row: 383, col: 10}, {ofs: 11412, row: 383, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11437, row: 385, col: 18}, {ofs: 11657, row: 393, col: 5}]); tmp249 = function (base) {\n var strengthRatio, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp253 = ourMilitaryStrength;\n tmp255 = base;\n tmp256 = 'gold';\n _aether.logStatementStart([{ofs: 11505, row: 386, col: 51}, {ofs: 11514, row: 386, col: 60}]); tmp254 = tmp255[tmp256]; _aether.logStatement([{ofs: 11505, row: 386, col: 51}, {ofs: 11514, row: 386, col: 60}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11483, row: 386, col: 29}, {ofs: 11514, row: 386, col: 60}]); tmp251 = tmp253 + tmp254; _aether.logStatement([{ofs: 11483, row: 386, col: 29}, {ofs: 11514, row: 386, col: 60}], _aether._userInfo, false);\n tmp252 = enemyMilitaryStrength;\n _aether.logStatementStart([{ofs: 11462, row: 386, col: 8}, {ofs: 11540, row: 386, col: 86}]); strengthRatio = tmp251 / tmp252; _aether.logStatement([{ofs: 11462, row: 386, col: 8}, {ofs: 11540, row: 386, col: 86}], _aether._userInfo, false);\n tmp258 = strengthRatio;\n _aether.logStatementStart([{ofs: 11579, row: 388, col: 29}, {ofs: 11582, row: 388, col: 32}]); tmp259 = 1.2; _aether.logStatement([{ofs: 11579, row: 388, col: 29}, {ofs: 11582, row: 388, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11562, row: 388, col: 12}, {ofs: 11582, row: 388, col: 32}]); tmp257 = tmp258 <= tmp259; _aether.logStatement([{ofs: 11562, row: 388, col: 12}, {ofs: 11582, row: 388, col: 32}], _aether._userInfo, false);\n if (tmp257) {\n _aether.logStatementStart([{ofs: 11605, row: 389, col: 19}, {ofs: 11609, row: 389, col: 23}]); tmp260 = true; _aether.logStatement([{ofs: 11605, row: 389, col: 19}, {ofs: 11609, row: 389, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp260);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 11645, row: 392, col: 15}, {ofs: 11650, row: 392, col: 20}]); tmp261 = false; _aether.logStatement([{ofs: 11645, row: 392, col: 15}, {ofs: 11650, row: 392, col: 20}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp261);\n }; _aether.logStatement([{ofs: 11437, row: 385, col: 18}, {ofs: 11657, row: 393, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11689, row: 395, col: 21}, {ofs: 11732, row: 397, col: 5}]); tmp250 = function (base) {\n var tmp262; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 11721, row: 396, col: 15}, {ofs: 11725, row: 396, col: 19}]); tmp262 = null; _aether.logStatement([{ofs: 11721, row: 396, col: 15}, {ofs: 11725, row: 396, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp262);\n }; _aether.logStatement([{ofs: 11689, row: 395, col: 21}, {ofs: 11732, row: 397, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11368, row: 382, col: 0}, {ofs: 11735, row: 398, col: 2}]); stockpileState = {\n name: tmp248,\n wantsControl: tmp249,\n selectBuildType: tmp250\n }; _aether.logStatement([{ofs: 11368, row: 382, col: 0}, {ofs: 11735, row: 398, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12745, row: 431, col: 10}, {ofs: 12753, row: 431, col: 18}]); tmp263 = 'attack'; _aether.logStatement([{ofs: 12745, row: 431, col: 10}, {ofs: 12753, row: 431, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12778, row: 433, col: 18}, {ofs: 13301, row: 447, col: 5}]); tmp264 = function (base) {\n var threshold, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp269 = base;\n tmp270 = 'now';\n _aether.logStatementStart([{ofs: 12863, row: 435, col: 12}, {ofs: 12873, row: 435, col: 22}]); tmp267 = _aether.createAPIClone(_aether, tmp269[tmp270]()); _aether.logStatement([{ofs: 12863, row: 435, col: 12}, {ofs: 12873, row: 435, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12877, row: 435, col: 26}, {ofs: 12880, row: 435, col: 29}]); tmp268 = 140; _aether.logStatement([{ofs: 12877, row: 435, col: 26}, {ofs: 12880, row: 435, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12863, row: 435, col: 12}, {ofs: 12880, row: 435, col: 29}]); tmp266 = tmp267 >= tmp268; _aether.logStatement([{ofs: 12863, row: 435, col: 12}, {ofs: 12880, row: 435, col: 29}], _aether._userInfo, false);\n if (tmp266) {\n _aether.logStatementStart([{ofs: 12903, row: 436, col: 19}, {ofs: 12907, row: 436, col: 23}]); tmp271 = true; _aether.logStatement([{ofs: 12903, row: 436, col: 19}, {ofs: 12907, row: 436, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp271);\n } else {\n ;\n }\n tmp274 = base;\n tmp275 = 'currentState';\n _aether.logStatementStart([{ofs: 13073, row: 441, col: 25}, {ofs: 13090, row: 441, col: 42}]); tmp273 = tmp274[tmp275]; _aether.logStatement([{ofs: 13073, row: 441, col: 25}, {ofs: 13090, row: 441, col: 42}], _aether._userInfo, false);\n if (tmp273) {\n tmp280 = base;\n tmp281 = 'currentState';\n _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13111, row: 441, col: 63}]); tmp278 = tmp280[tmp281]; _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13111, row: 441, col: 63}], _aether._userInfo, false);\n tmp279 = 'name';\n _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13116, row: 441, col: 68}]); tmp276 = tmp278[tmp279]; _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13116, row: 441, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13121, row: 441, col: 73}, {ofs: 13129, row: 441, col: 81}]); tmp277 = 'attack'; _aether.logStatement([{ofs: 13121, row: 441, col: 73}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13129, row: 441, col: 81}]); tmp272 = tmp276 === tmp277; _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 13073, row: 441, col: 25}, {ofs: 13129, row: 441, col: 81}]); tmp272 = tmp273; _aether.logStatement([{ofs: 13073, row: 441, col: 25}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n }\n if (tmp272) {\n _aether.logStatementStart([{ofs: 13133, row: 441, col: 85}, {ofs: 13134, row: 441, col: 86}]); threshold = 0; _aether.logStatement([{ofs: 13133, row: 441, col: 85}, {ofs: 13134, row: 441, col: 86}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 13137, row: 441, col: 89}, {ofs: 13139, row: 441, col: 91}]); threshold = 20; _aether.logStatement([{ofs: 13137, row: 441, col: 89}, {ofs: 13139, row: 441, col: 91}], _aether._userInfo, false);\n }\n tmp283 = enemyStrengthForecast;\n if (tmp283) {\n tmp286 = ourStrength;\n tmp287 = enemyStrengthForecast;\n _aether.logStatementStart([{ofs: 13178, row: 442, col: 37}, {ofs: 13213, row: 442, col: 72}]); tmp284 = tmp286 - tmp287; _aether.logStatement([{ofs: 13178, row: 442, col: 37}, {ofs: 13213, row: 442, col: 72}], _aether._userInfo, false);\n tmp285 = threshold;\n _aether.logStatementStart([{ofs: 13178, row: 442, col: 37}, {ofs: 13226, row: 442, col: 85}]); tmp282 = tmp284 >= tmp285; _aether.logStatement([{ofs: 13178, row: 442, col: 37}, {ofs: 13226, row: 442, col: 85}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 13153, row: 442, col: 12}, {ofs: 13226, row: 442, col: 85}]); tmp282 = tmp283; _aether.logStatement([{ofs: 13153, row: 442, col: 12}, {ofs: 13226, row: 442, col: 85}], _aether._userInfo, false);\n }\n if (tmp282) {\n _aether.logStatementStart([{ofs: 13249, row: 443, col: 19}, {ofs: 13253, row: 443, col: 23}]); tmp288 = true; _aether.logStatement([{ofs: 13249, row: 443, col: 19}, {ofs: 13253, row: 443, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp288);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 13289, row: 446, col: 15}, {ofs: 13294, row: 446, col: 20}]); tmp289 = false; _aether.logStatement([{ofs: 13289, row: 446, col: 15}, {ofs: 13294, row: 446, col: 20}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp289);\n }; _aether.logStatement([{ofs: 12778, row: 433, col: 18}, {ofs: 13301, row: 447, col: 5}], _aether._userInfo, false);\n tmp265 = decideMilitaryToBuild;\n _aether.logStatementStart([{ofs: 12715, row: 430, col: 0}, {ofs: 13357, row: 450, col: 2}]); attackState = {\n name: tmp263,\n wantsControl: tmp264,\n selectBuildType: tmp265\n }; _aether.logStatement([{ofs: 12715, row: 430, col: 0}, {ofs: 13357, row: 450, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13389, row: 453, col: 10}, {ofs: 13397, row: 453, col: 18}]); tmp290 = 'defend'; _aether.logStatement([{ofs: 13389, row: 453, col: 10}, {ofs: 13397, row: 453, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13422, row: 455, col: 18}, {ofs: 13872, row: 466, col: 5}]); tmp291 = function (base) {\n var nearEnemies, militaryRatio, tmp293, tmp294, tmp295, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp293 = militaryEnemies;\n tmp294 = 'filter';\n _aether.logStatementStart([{ofs: 13488, row: 456, col: 49}, {ofs: 13533, row: 456, col: 94}]); tmp295 = function (x) {\n var tmp296, tmp297, tmp298, tmp299, tmp300, tmp301; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp299 = base;\n tmp300 = 'distance';\n tmp301 = x;\n _aether.logStatementStart([{ofs: 13509, row: 456, col: 70}, {ofs: 13525, row: 456, col: 86}]); tmp297 = _aether.createAPIClone(_aether, tmp299[tmp300](_aether.restoreAPIClone(_aether, tmp301))); _aether.logStatement([{ofs: 13509, row: 456, col: 70}, {ofs: 13525, row: 456, col: 86}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13528, row: 456, col: 89}, {ofs: 13530, row: 456, col: 91}]); tmp298 = 55; _aether.logStatement([{ofs: 13528, row: 456, col: 89}, {ofs: 13530, row: 456, col: 91}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13509, row: 456, col: 70}, {ofs: 13530, row: 456, col: 91}]); tmp296 = tmp297 < tmp298; _aether.logStatement([{ofs: 13509, row: 456, col: 70}, {ofs: 13530, row: 456, col: 91}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp296);\n }; _aether.logStatement([{ofs: 13488, row: 456, col: 49}, {ofs: 13533, row: 456, col: 94}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13447, row: 456, col: 8}, {ofs: 13535, row: 456, col: 96}]); nearEnemies = _aether.createAPIClone(_aether, tmp293[tmp294](_aether.restoreAPIClone(_aether, tmp295))); _aether.logStatement([{ofs: 13447, row: 456, col: 8}, {ofs: 13535, row: 456, col: 96}], _aether._userInfo, false);\n tmp302 = ourMilitaryStrength;\n tmp304 = valuateFighters;\n tmp305 = nearEnemies;\n _aether.logStatementStart([{ofs: 13595, row: 458, col: 50}, {ofs: 13623, row: 458, col: 78}]); tmp303 = _aether.createAPIClone(_aether, tmp304(_aether.restoreAPIClone(_aether, tmp305))); _aether.logStatement([{ofs: 13595, row: 458, col: 50}, {ofs: 13623, row: 458, col: 78}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13553, row: 458, col: 8}, {ofs: 13624, row: 458, col: 79}]); militaryRatio = tmp302 / tmp303; _aether.logStatement([{ofs: 13553, row: 458, col: 8}, {ofs: 13624, row: 458, col: 79}], _aether._userInfo, false);\n tmp308 = nearestEnemy;\n if (tmp308) {\n tmp311 = base;\n tmp312 = 'distance';\n tmp313 = nearestEnemy;\n _aether.logStatementStart([{ofs: 13741, row: 461, col: 28}, {ofs: 13768, row: 461, col: 55}]); tmp309 = _aether.createAPIClone(_aether, tmp311[tmp312](_aether.restoreAPIClone(_aether, tmp313))); _aether.logStatement([{ofs: 13741, row: 461, col: 28}, {ofs: 13768, row: 461, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13772, row: 461, col: 59}, {ofs: 13774, row: 461, col: 61}]); tmp310 = 40; _aether.logStatement([{ofs: 13772, row: 461, col: 59}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13741, row: 461, col: 28}, {ofs: 13774, row: 461, col: 61}]); tmp307 = tmp309 <= tmp310; _aether.logStatement([{ofs: 13741, row: 461, col: 28}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 13725, row: 461, col: 12}, {ofs: 13774, row: 461, col: 61}]); tmp307 = tmp308; _aether.logStatement([{ofs: 13725, row: 461, col: 12}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n }\n if (tmp307) {\n tmp314 = militaryRatio;\n _aether.logStatementStart([{ofs: 13794, row: 461, col: 81}, {ofs: 13797, row: 461, col: 84}]); tmp315 = 1.2; _aether.logStatement([{ofs: 13794, row: 461, col: 81}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 13778, row: 461, col: 65}, {ofs: 13797, row: 461, col: 84}]); tmp306 = tmp314 < tmp315; _aether.logStatement([{ofs: 13778, row: 461, col: 65}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 13725, row: 461, col: 12}, {ofs: 13797, row: 461, col: 84}]); tmp306 = tmp307; _aether.logStatement([{ofs: 13725, row: 461, col: 12}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n }\n if (tmp306) {\n _aether.logStatementStart([{ofs: 13820, row: 462, col: 19}, {ofs: 13824, row: 462, col: 23}]); tmp316 = true; _aether.logStatement([{ofs: 13820, row: 462, col: 19}, {ofs: 13824, row: 462, col: 23}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp316);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 13860, row: 465, col: 15}, {ofs: 13865, row: 465, col: 20}]); tmp317 = false; _aether.logStatement([{ofs: 13860, row: 465, col: 15}, {ofs: 13865, row: 465, col: 20}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp317);\n }; _aether.logStatement([{ofs: 13422, row: 455, col: 18}, {ofs: 13872, row: 466, col: 5}], _aether._userInfo, false);\n tmp292 = decideMilitaryToBuild;\n _aether.logStatementStart([{ofs: 13359, row: 452, col: 0}, {ofs: 13924, row: 469, col: 2}]); defendState = {\n name: tmp290,\n wantsControl: tmp291,\n selectBuildType: tmp292\n }; _aether.logStatement([{ofs: 13359, row: 452, col: 0}, {ofs: 13924, row: 469, col: 2}], _aether._userInfo, false);\n tmp318 = attackState;\n tmp319 = defendState;\n tmp320 = stockpileState;\n tmp321 = collectState;\n tmp322 = pokeState;\n tmp323 = doNothingState;\n _aether.logStatementStart([{ofs: 14008, row: 473, col: 0}, {ofs: 14131, row: 480, col: 2}]); states = [\n tmp318,\n tmp319,\n tmp320,\n tmp321,\n tmp322,\n tmp323\n ]; _aether.logStatement([{ofs: 14008, row: 473, col: 0}, {ofs: 14131, row: 480, col: 2}], _aether._userInfo, false);\n tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp325 = 'updateState';\n _aether.logStatementStart([{ofs: 14133, row: 482, col: 0}, {ofs: 14362, row: 490, col: 2}]); tmp326 = function () {\n var i, sLen, st, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp338, tmp339, tmp340, tmp341, tmp342, tmp343, tmp344, tmp345, tmp346; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}]); i = 0; _aether.logStatement([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}], _aether._userInfo, false);\n tmp327 = states;\n tmp328 = 'length';\n _aether.logStatementStart([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}]); sLen = tmp327[tmp328]; _aether.logStatement([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}], _aether._userInfo, false);\n tmp330 = i;\n tmp331 = sLen;\n _aether.logStatementStart([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}]); tmp329 = tmp330 < tmp331; _aether.logStatement([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}], _aether._userInfo, false);\n tmp336: {\n while (tmp329) {\n tmp337: {\n tmp338 = states;\n tmp339 = i;\n _aether.logStatementStart([{ofs: 14232, row: 484, col: 8}, {ofs: 14251, row: 484, col: 27}]); st = tmp338[tmp339]; _aether.logStatement([{ofs: 14232, row: 484, col: 8}, {ofs: 14251, row: 484, col: 27}], _aether._userInfo, false);\n tmp341 = st;\n tmp342 = 'wantsControl';\n tmp343 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n _aether.logStatementStart([{ofs: 14264, row: 485, col: 12}, {ofs: 14285, row: 485, col: 33}]); tmp340 = _aether.createAPIClone(_aether, tmp341[tmp342](_aether.restoreAPIClone(_aether, tmp343))); _aether.logStatement([{ofs: 14264, row: 485, col: 12}, {ofs: 14285, row: 485, col: 33}], _aether._userInfo, false);\n if (tmp340) {\n tmp344 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp345 = 'currentState';\n tmp346 = st;\n _aether.logStatementStart([{ofs: 14301, row: 486, col: 12}, {ofs: 14323, row: 486, col: 34}]); tmp344[tmp345] = tmp346; _aether.logStatement([{ofs: 14301, row: 486, col: 12}, {ofs: 14323, row: 486, col: 34}], _aether._userInfo, false);\n break tmp336;\n } else {\n ;\n }\n }\n tmp334 = i;\n tmp335 = 1;\n i = tmp334 + tmp335;\n tmp332 = i;\n tmp333 = sLen;\n _aether.logStatementStart([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}]); tmp329 = tmp332 < tmp333; _aether.logStatement([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 14133, row: 482, col: 0}, {ofs: 14362, row: 490, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 14133, row: 482, col: 0}, {ofs: 14361, row: 490, col: 1}]); tmp324[tmp325] = tmp326; _aether.logStatement([{ofs: 14133, row: 482, col: 0}, {ofs: 14361, row: 490, col: 1}], _aether._userInfo, false);\n tmp347 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp348 = 'updateState';\n _aether.logStatementStart([{ofs: 14446, row: 494, col: 0}, {ofs: 14464, row: 494, col: 18}]); tmp349 = _aether.createAPIClone(_aether, tmp347[tmp348]()); _aether.logStatement([{ofs: 14446, row: 494, col: 0}, {ofs: 14464, row: 494, col: 18}], _aether._userInfo, false);\n tmp352 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp353 = 'currentState';\n _aether.logStatementStart([{ofs: 14478, row: 496, col: 11}, {ofs: 14495, row: 496, col: 28}]); tmp350 = tmp352[tmp353]; _aether.logStatement([{ofs: 14478, row: 496, col: 11}, {ofs: 14495, row: 496, col: 28}], _aether._userInfo, false);\n tmp351 = 'selectBuildType';\n tmp354 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n _aether.logStatementStart([{ofs: 14467, row: 496, col: 0}, {ofs: 14518, row: 496, col: 51}]); type = _aether.createAPIClone(_aether, tmp350[tmp351](_aether.restoreAPIClone(_aether, tmp354))); _aether.logStatement([{ofs: 14467, row: 496, col: 0}, {ofs: 14518, row: 496, col: 51}], _aether._userInfo, false);\n tmp356 = type;\n if (tmp356) {\n tmp359 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp360 = 'gold';\n _aether.logStatementStart([{ofs: 14532, row: 498, col: 12}, {ofs: 14541, row: 498, col: 21}]); tmp357 = tmp359[tmp360]; _aether.logStatement([{ofs: 14532, row: 498, col: 12}, {ofs: 14541, row: 498, col: 21}], _aether._userInfo, false);\n tmp365 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp366 = 'buildables';\n _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14560, row: 498, col: 40}]); tmp363 = tmp365[tmp366]; _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14560, row: 498, col: 40}], _aether._userInfo, false);\n tmp364 = type;\n _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14566, row: 498, col: 46}]); tmp361 = tmp363[tmp364]; _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14566, row: 498, col: 46}], _aether._userInfo, false);\n tmp362 = 'goldCost';\n _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14575, row: 498, col: 55}]); tmp358 = tmp361[tmp362]; _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 14532, row: 498, col: 12}, {ofs: 14575, row: 498, col: 55}]); tmp355 = tmp357 >= tmp358; _aether.logStatement([{ofs: 14532, row: 498, col: 12}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 14524, row: 498, col: 4}, {ofs: 14575, row: 498, col: 55}]); tmp355 = tmp356; _aether.logStatement([{ofs: 14524, row: 498, col: 4}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n }\n if (tmp355) {\n tmp367 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp368 = 'build';\n tmp369 = type;\n _aether.logStatementStart([{ofs: 14583, row: 499, col: 4}, {ofs: 14599, row: 499, col: 20}]); tmp370 = _aether.createAPIClone(_aether, tmp367[tmp368](_aether.restoreAPIClone(_aether, tmp369))); _aether.logStatement([{ofs: 14583, row: 499, col: 4}, {ofs: 14599, row: 499, col: 20}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" } }, - "totalScore": 36.7927193835314, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 36.77589873873074, "submitted": true, "submittedCodeLanguage": "javascript", "playtime": 12893, @@ -422,6 +508,10 @@ responses = }, { "_id": "5356fc2e1bfa9bba14b5e039", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, "team": "humans", "levelID": "greed", "levelName": "Greed", @@ -433,65 +523,108 @@ responses = "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" } }, - "totalScore": 31.55513937890014, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 31.538998178536794, "submitted": true, "submittedCodeLanguage": "javascript", - "playtime": 14758, + "playtime": 15648, "codeLanguage": "javascript" }, { "_id": "52fd5bf7e3c53130231726e1", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, "team": "ogres", "levelID": "brawlwood", "levelName": "Brawlwood", "submitted": true, - "totalScore": 54.324748499022, + "totalScore": 53.73511062513137, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, "code": { - "human-base": { - "hear": "...", - "chooseAction": "..." + "ogre-base": { + "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n type = 'shaman';\nelse if(this.built.length % 6 === 1)\n type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n" }, - "programmable-archer": { - "hear": "...", - "chooseAction": "..." + "programmable-munchkin": { + "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n items = this.getItems();\n if(items.length) {\n this.move(items[0].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nif(this.buildIndex === 2) {\n items = this.getItems();\n if(items.length) {\n this.move(items[items.length - 1].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n var d = this.distance(enemy);\n if(enemy.type == 'soldier' && enemy.health > 15) continue;\n if(enemy.type == 'burl' && enemy.health > 30) continue;\n if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n if(d < nearestJuicyTargetDistance) {\n nearestJuicyTarget = enemy;\n nearestJuicyTargetDistance = d;\n }\n}\nif(nearestJuicyTargetDistance < 15) {\n this.attack(nearestJuicyTarget);\n return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}" }, - "s-arrow-tower": { - "chooseAction": "..." - }, - "programmable-soldier": { - "hear": "...", - "chooseAction": "..." - }, - "programmable-artillery": { - "hear": "...", - "chooseAction": "..." - }, - "programmable-shaman": { - "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n this.castShrink(this.shouldShrink.pop());\n return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n this.castSlow(enemy);\n return;\n }\n else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n this.castShrink(enemy);\n return;\n }\n}\nfor (i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if (this.distance(enemy) > 30) continue;\n if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n this.castShrink(enemy);\n return;\n }\n if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n return;\n }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n this.attack(enemy);\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}\n", - "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n if(!this.shouldShrink)\n this.shouldShrink = [];\n this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here." + "programmable-thrower": { + "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", + "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n\n this.move({x: 10, y: 10});\n}\n\n" }, "n-beam-tower": { "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \"!\");\n this.attack(enemy);\n}" }, - "programmable-thrower": { - "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n\n this.move({x: 10, y: 10});\n}\n\n", - "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + "programmable-shaman": { + "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n if(!this.shouldShrink)\n this.shouldShrink = [];\n this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here.", + "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n this.castShrink(this.shouldShrink.pop());\n return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n this.castSlow(enemy);\n return;\n }\n else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n this.castShrink(enemy);\n return;\n }\n}\nfor (i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if (this.distance(enemy) > 30) continue;\n if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n this.castShrink(enemy);\n return;\n }\n if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n return;\n }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n this.attack(enemy);\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}\n" }, - "programmable-munchkin": { - "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n items = this.getItems();\n if(items.length) {\n this.move(items[0].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nif(this.buildIndex === 2) {\n items = this.getItems();\n if(items.length) {\n this.move(items[items.length - 1].pos);\n this.say(\"MINE\", {mission: \"coins\"});\n return;\n }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n var d = this.distance(enemy);\n if(enemy.type == 'soldier' && enemy.health > 15) continue;\n if(enemy.type == 'burl' && enemy.health > 30) continue;\n if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n if(d < nearestJuicyTargetDistance) {\n nearestJuicyTarget = enemy;\n nearestJuicyTargetDistance = d;\n }\n}\nif(nearestJuicyTargetDistance < 15) {\n this.attack(nearestJuicyTarget);\n return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n if(this.buildIndex % 2)\n this.move({x: 53, y: 75});\n else\n this.move({x: 75, y: 53});\n return;\n }\n this.move({x: 10, y: 10});\n}", - "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + "programmable-artillery": { + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp6 = 'now';\n _aether.logStatementStart([{ofs: 509, row: 11, col: 4}, {ofs: 519, row: 11, col: 14}]); tmp3 = _aether.createAPIClone(_aether, tmp5[tmp6]()); _aether.logStatement([{ofs: 509, row: 11, col: 4}, {ofs: 519, row: 11, col: 14}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 522, row: 11, col: 17}, {ofs: 523, row: 11, col: 18}]); tmp4 = 5; _aether.logStatement([{ofs: 522, row: 11, col: 17}, {ofs: 523, row: 11, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 509, row: 11, col: 4}, {ofs: 523, row: 11, col: 18}]); tmp2 = tmp3 < tmp4; _aether.logStatement([{ofs: 509, row: 11, col: 4}, {ofs: 523, row: 11, col: 18}], _aether._userInfo, false);\n if (tmp2) {\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp8 = 'say';\n _aether.logStatementStart([{ofs: 540, row: 12, col: 13}, {ofs: 563, row: 12, col: 36}]); tmp9 = '***BOOM SHAKALAKA!***'; _aether.logStatement([{ofs: 540, row: 12, col: 13}, {ofs: 563, row: 12, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 531, row: 12, col: 4}, {ofs: 564, row: 12, col: 37}]); tmp10 = _aether.createAPIClone(_aether, tmp7[tmp8](_aether.restoreAPIClone(_aether, tmp9))); _aether.logStatement([{ofs: 531, row: 12, col: 4}, {ofs: 564, row: 12, col: 37}], _aether._userInfo, false);\n tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp12 = 'attackXY';\n _aether.logStatementStart([{ofs: 584, row: 13, col: 18}, {ofs: 586, row: 13, col: 20}]); tmp13 = 40; _aether.logStatement([{ofs: 584, row: 13, col: 18}, {ofs: 586, row: 13, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 588, row: 13, col: 22}, {ofs: 590, row: 13, col: 24}]); tmp14 = 40; _aether.logStatement([{ofs: 588, row: 13, col: 22}, {ofs: 590, row: 13, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 570, row: 13, col: 4}, {ofs: 591, row: 13, col: 25}]); tmp15 = _aether.createAPIClone(_aether, tmp11[tmp12](_aether.restoreAPIClone(_aether, tmp13), _aether.restoreAPIClone(_aether, tmp14))); _aether.logStatement([{ofs: 570, row: 13, col: 4}, {ofs: 591, row: 13, col: 25}], _aether._userInfo, false);\n } else {\n tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp17 = 'move';\n _aether.logStatementStart([{ofs: 620, row: 15, col: 18}, {ofs: 622, row: 15, col: 20}]); tmp19 = 41; _aether.logStatement([{ofs: 620, row: 15, col: 18}, {ofs: 622, row: 15, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 627, row: 15, col: 25}, {ofs: 629, row: 15, col: 27}]); tmp20 = 17; _aether.logStatement([{ofs: 627, row: 15, col: 25}, {ofs: 629, row: 15, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 616, row: 15, col: 14}, {ofs: 630, row: 15, col: 28}]); tmp18 = {\n x: tmp19,\n y: tmp20\n }; _aether.logStatement([{ofs: 616, row: 15, col: 14}, {ofs: 630, row: 15, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 606, row: 15, col: 4}, {ofs: 631, row: 15, col: 29}]); tmp21 = _aether.createAPIClone(_aether, tmp16[tmp17](_aether.restoreAPIClone(_aether, tmp18))); _aether.logStatement([{ofs: 606, row: 15, col: 4}, {ofs: 631, row: 15, col: 29}], _aether._userInfo, false);\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));", + "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function (speaker, message, data) {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = speaker;\n tmp6 = 'team';\n _aether.logStatementStart([{ofs: 83, row: 1, col: 3}, {ofs: 95, row: 1, col: 15}]); tmp3 = tmp5[tmp6]; _aether.logStatement([{ofs: 83, row: 1, col: 3}, {ofs: 95, row: 1, col: 15}], _aether._userInfo, false);\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp8 = 'team';\n _aether.logStatementStart([{ofs: 100, row: 1, col: 20}, {ofs: 109, row: 1, col: 29}]); tmp4 = tmp7[tmp8]; _aether.logStatement([{ofs: 100, row: 1, col: 20}, {ofs: 109, row: 1, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 83, row: 1, col: 3}, {ofs: 109, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4; _aether.logStatement([{ofs: 83, row: 1, col: 3}, {ofs: 109, row: 1, col: 29}], _aether._userInfo, false);\n if (tmp2) {\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'hear';\n __global[tmp0] = tmp1;\n}(this));" }, - "ogre-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n type = 'shaman';\nelse if(this.built.length % 6 === 1)\n type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n", - "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." + "programmable-soldier": { + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getNearestEnemy';\n _aether.logStatementStart([{ofs: 172, row: 4, col: 0}, {ofs: 207, row: 4, col: 35}]); enemy = _aether.createAPIClone(_aether, tmp2[tmp3]()); _aether.logStatement([{ofs: 172, row: 4, col: 0}, {ofs: 207, row: 4, col: 35}], _aether._userInfo, false);\n tmp4 = enemy;\n if (tmp4) {\n tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp6 = 'attack';\n tmp7 = enemy;\n _aether.logStatementStart([{ofs: 255, row: 7, col: 4}, {ofs: 273, row: 7, col: 22}]); tmp8 = _aether.createAPIClone(_aether, tmp5[tmp6](_aether.restoreAPIClone(_aether, tmp7))); _aether.logStatement([{ofs: 255, row: 7, col: 4}, {ofs: 273, row: 7, col: 22}], _aether._userInfo, false);\n } else {\n tmp9 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp10 = 'move';\n _aether.logStatementStart([{ofs: 311, row: 10, col: 11}, {ofs: 313, row: 10, col: 13}]); tmp12 = 40; _aether.logStatement([{ofs: 311, row: 10, col: 11}, {ofs: 313, row: 10, col: 13}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 326, row: 11, col: 11}, {ofs: 328, row: 11, col: 13}]); tmp13 = 24; _aether.logStatement([{ofs: 326, row: 11, col: 11}, {ofs: 328, row: 11, col: 13}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 298, row: 9, col: 14}, {ofs: 334, row: 12, col: 5}]); tmp11 = {\n x: tmp12,\n y: tmp13\n }; _aether.logStatement([{ofs: 298, row: 9, col: 14}, {ofs: 334, row: 12, col: 5}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 288, row: 9, col: 4}, {ofs: 335, row: 12, col: 6}]); tmp14 = _aether.createAPIClone(_aether, tmp9[tmp10](_aether.restoreAPIClone(_aether, tmp11))); _aether.logStatement([{ofs: 288, row: 9, col: 4}, {ofs: 335, row: 12, col: 6}], _aether._userInfo, false);\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));", + "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function (speaker, message, data) {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = speaker;\n tmp6 = 'team';\n _aether.logStatementStart([{ofs: 81, row: 1, col: 3}, {ofs: 93, row: 1, col: 15}]); tmp3 = tmp5[tmp6]; _aether.logStatement([{ofs: 81, row: 1, col: 3}, {ofs: 93, row: 1, col: 15}], _aether._userInfo, false);\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp8 = 'team';\n _aether.logStatementStart([{ofs: 98, row: 1, col: 20}, {ofs: 107, row: 1, col: 29}]); tmp4 = tmp7[tmp8]; _aether.logStatement([{ofs: 98, row: 1, col: 20}, {ofs: 107, row: 1, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 81, row: 1, col: 3}, {ofs: 107, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4; _aether.logStatement([{ofs: 81, row: 1, col: 3}, {ofs: 107, row: 1, col: 29}], _aether._userInfo, false);\n if (tmp2) {\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'hear';\n __global[tmp0] = tmp1;\n}(this));" + }, + "s-arrow-tower": { + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getNearestEnemy';\n _aether.logStatementStart([{ofs: 169, row: 4, col: 0}, {ofs: 204, row: 4, col: 35}]); enemy = _aether.createAPIClone(_aether, tmp2[tmp3]()); _aether.logStatement([{ofs: 169, row: 4, col: 0}, {ofs: 204, row: 4, col: 35}], _aether._userInfo, false);\n tmp5 = enemy;\n if (tmp5) {\n tmp8 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp9 = 'distance';\n tmp10 = enemy;\n _aether.logStatementStart([{ofs: 219, row: 6, col: 13}, {ofs: 239, row: 6, col: 33}]); tmp6 = _aether.createAPIClone(_aether, tmp8[tmp9](_aether.restoreAPIClone(_aether, tmp10))); _aether.logStatement([{ofs: 219, row: 6, col: 13}, {ofs: 239, row: 6, col: 33}], _aether._userInfo, false);\n tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp12 = 'attackRange';\n _aether.logStatementStart([{ofs: 242, row: 6, col: 36}, {ofs: 258, row: 6, col: 52}]); tmp7 = tmp11[tmp12]; _aether.logStatement([{ofs: 242, row: 6, col: 36}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 219, row: 6, col: 13}, {ofs: 258, row: 6, col: 52}]); tmp4 = tmp6 < tmp7; _aether.logStatement([{ofs: 219, row: 6, col: 13}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 210, row: 6, col: 4}, {ofs: 258, row: 6, col: 52}]); tmp4 = tmp5; _aether.logStatement([{ofs: 210, row: 6, col: 4}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n }\n if (tmp4) {\n tmp13 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp14 = 'say';\n _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 288, row: 7, col: 26}]); tmp18 = 'EAT DEATH, '; _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 288, row: 7, col: 26}], _aether._userInfo, false);\n tmp20 = enemy;\n tmp21 = 'id';\n _aether.logStatementStart([{ofs: 291, row: 7, col: 29}, {ofs: 299, row: 7, col: 37}]); tmp19 = tmp20[tmp21]; _aether.logStatement([{ofs: 291, row: 7, col: 29}, {ofs: 299, row: 7, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 299, row: 7, col: 37}]); tmp16 = tmp18 + tmp19; _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 299, row: 7, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 302, row: 7, col: 40}, {ofs: 305, row: 7, col: 43}]); tmp17 = '!'; _aether.logStatement([{ofs: 302, row: 7, col: 40}, {ofs: 305, row: 7, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 305, row: 7, col: 43}]); tmp15 = tmp16 + tmp17; _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 305, row: 7, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 266, row: 7, col: 4}, {ofs: 306, row: 7, col: 44}]); tmp22 = _aether.createAPIClone(_aether, tmp13[tmp14](_aether.restoreAPIClone(_aether, tmp15))); _aether.logStatement([{ofs: 266, row: 7, col: 4}, {ofs: 306, row: 7, col: 44}], _aether._userInfo, false);\n tmp23 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp24 = 'attack';\n tmp25 = enemy;\n _aether.logStatementStart([{ofs: 312, row: 8, col: 4}, {ofs: 330, row: 8, col: 22}]); tmp26 = _aether.createAPIClone(_aether, tmp23[tmp24](_aether.restoreAPIClone(_aether, tmp25))); _aether.logStatement([{ofs: 312, row: 8, col: 4}, {ofs: 330, row: 8, col: 22}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" + }, + "programmable-archer": { + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp48, tmp49, tmp50, tmp178, tmp179, tmp180, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getGold';\n _aether.logStatementStart([{ofs: 326, row: 9, col: 0}, {ofs: 974, row: 29, col: 0}]); tmp4 = function (location, saying) {\n var items, item, i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47; location = _aether.createAPIClone(_aether, location); saying = _aether.createAPIClone(_aether, saying); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp6 = 'getItems';\n _aether.logStatementStart([{ofs: 406, row: 11, col: 4}, {ofs: 430, row: 11, col: 28}]); items = _aether.createAPIClone(_aether, tmp5[tmp6]()); _aether.logStatement([{ofs: 406, row: 11, col: 4}, {ofs: 430, row: 11, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 444, row: 12, col: 13}, {ofs: 445, row: 12, col: 14}]); i = 0; _aether.logStatement([{ofs: 444, row: 12, col: 13}, {ofs: 445, row: 12, col: 14}], _aether._userInfo, false);\n tmp8 = i;\n tmp10 = items;\n tmp11 = 'length';\n _aether.logStatementStart([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}]); tmp9 = tmp10[tmp11]; _aether.logStatement([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}]); tmp7 = tmp8 < tmp9; _aether.logStatement([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n tmp18: {\n while (tmp7) {\n tmp19: {\n tmp21 = i;\n _aether.logStatementStart([{ofs: 490, row: 13, col: 18}, {ofs: 491, row: 13, col: 19}]); tmp22 = 3; _aether.logStatement([{ofs: 490, row: 13, col: 18}, {ofs: 491, row: 13, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 484, row: 13, col: 12}, {ofs: 491, row: 13, col: 19}]); tmp20 = tmp21 !== tmp22; _aether.logStatement([{ofs: 484, row: 13, col: 12}, {ofs: 491, row: 13, col: 19}], _aether._userInfo, false);\n if (tmp20) {\n tmp23 = items;\n tmp24 = i;\n _aether.logStatementStart([{ofs: 507, row: 14, col: 12}, {ofs: 523, row: 14, col: 28}]); item = tmp23[tmp24]; _aether.logStatement([{ofs: 507, row: 14, col: 12}, {ofs: 523, row: 14, col: 28}], _aether._userInfo, false);\n tmp28 = location;\n _aether.logStatementStart([{ofs: 553, row: 15, col: 29}, {ofs: 559, row: 15, col: 35}]); tmp29 = 'left'; _aether.logStatement([{ofs: 553, row: 15, col: 29}, {ofs: 559, row: 15, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 541, row: 15, col: 17}, {ofs: 559, row: 15, col: 35}]); tmp27 = tmp28 == tmp29; _aether.logStatement([{ofs: 541, row: 15, col: 17}, {ofs: 559, row: 15, col: 35}], _aether._userInfo, false);\n if (tmp27) {\n tmp32 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp33 = 'distance';\n tmp34 = item;\n _aether.logStatementStart([{ofs: 563, row: 15, col: 39}, {ofs: 582, row: 15, col: 58}]); tmp30 = _aether.createAPIClone(_aether, tmp32[tmp33](_aether.restoreAPIClone(_aether, tmp34))); _aether.logStatement([{ofs: 563, row: 15, col: 39}, {ofs: 582, row: 15, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 585, row: 15, col: 61}, {ofs: 587, row: 15, col: 63}]); tmp31 = 60; _aether.logStatement([{ofs: 585, row: 15, col: 61}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 563, row: 15, col: 39}, {ofs: 587, row: 15, col: 63}]); tmp26 = tmp30 < tmp31; _aether.logStatement([{ofs: 563, row: 15, col: 39}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 541, row: 15, col: 17}, {ofs: 587, row: 15, col: 63}]); tmp26 = tmp27; _aether.logStatement([{ofs: 541, row: 15, col: 17}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n }\n if (tmp26) {\n _aether.logStatementStart([{ofs: 540, row: 15, col: 16}, {ofs: 611, row: 15, col: 87}]); tmp25 = tmp26; _aether.logStatement([{ofs: 540, row: 15, col: 16}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n } else {\n tmp35 = location;\n _aether.logStatementStart([{ofs: 604, row: 15, col: 80}, {ofs: 611, row: 15, col: 87}]); tmp36 = 'right'; _aether.logStatement([{ofs: 604, row: 15, col: 80}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 592, row: 15, col: 68}, {ofs: 611, row: 15, col: 87}]); tmp25 = tmp35 == tmp36; _aether.logStatement([{ofs: 592, row: 15, col: 68}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n }\n if (tmp25) {\n tmp37 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp38 = 'move';\n tmp40 = item;\n tmp41 = 'pos';\n _aether.logStatementStart([{ofs: 641, row: 16, col: 26}, {ofs: 649, row: 16, col: 34}]); tmp39 = tmp40[tmp41]; _aether.logStatement([{ofs: 641, row: 16, col: 26}, {ofs: 649, row: 16, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 631, row: 16, col: 16}, {ofs: 650, row: 16, col: 35}]); tmp42 = _aether.createAPIClone(_aether, tmp37[tmp38](_aether.restoreAPIClone(_aether, tmp39))); _aether.logStatement([{ofs: 631, row: 16, col: 16}, {ofs: 650, row: 16, col: 35}], _aether._userInfo, false);\n tmp43 = saying;\n if (tmp43) {\n tmp44 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp45 = 'say';\n tmp46 = saying;\n _aether.logStatementStart([{ofs: 702, row: 18, col: 20}, {ofs: 718, row: 18, col: 36}]); tmp47 = _aether.createAPIClone(_aether, tmp44[tmp45](_aether.restoreAPIClone(_aether, tmp46))); _aether.logStatement([{ofs: 702, row: 18, col: 20}, {ofs: 718, row: 18, col: 36}], _aether._userInfo, false);\n } else {\n ;\n }\n } else {\n ;\n }\n } else {\n ;\n }\n }\n tmp16 = i;\n tmp17 = 1;\n i = tmp16 + tmp17;\n tmp12 = i;\n tmp14 = items;\n tmp15 = 'length';\n _aether.logStatementStart([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}]); tmp13 = tmp14[tmp15]; _aether.logStatement([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}]); tmp7 = tmp12 < tmp13; _aether.logStatement([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 326, row: 9, col: 0}, {ofs: 974, row: 29, col: 0}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 326, row: 9, col: 0}, {ofs: 769, row: 23, col: 1}]); tmp2[tmp3] = tmp4; _aether.logStatement([{ofs: 326, row: 9, col: 0}, {ofs: 769, row: 23, col: 1}], _aether._userInfo, false);\n tmp48 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp49 = 'evade';\n _aether.logStatementStart([{ofs: 974, row: 29, col: 0}, {ofs: 2278, row: 59, col: 0}]); tmp50 = function () {\n var nearest, distance, maxrange, newx, newy, evadeLoc, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp51 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp52 = 'getNearestEnemy';\n _aether.logStatementStart([{ofs: 1004, row: 30, col: 4}, {ofs: 1041, row: 30, col: 41}]); nearest = _aether.createAPIClone(_aether, tmp51[tmp52]()); _aether.logStatement([{ofs: 1004, row: 30, col: 4}, {ofs: 1041, row: 30, col: 41}], _aether._userInfo, false);\n tmp53 = nearest;\n if (tmp53) {\n tmp54 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp55 = 'distance';\n tmp56 = nearest;\n _aether.logStatementStart([{ofs: 1069, row: 32, col: 8}, {ofs: 1107, row: 32, col: 46}]); distance = _aether.createAPIClone(_aether, tmp54[tmp55](_aether.restoreAPIClone(_aether, tmp56))); _aether.logStatement([{ofs: 1069, row: 32, col: 8}, {ofs: 1107, row: 32, col: 46}], _aether._userInfo, false);\n tmp57 = nearest;\n tmp58 = 'attackRange';\n _aether.logStatementStart([{ofs: 1116, row: 33, col: 8}, {ofs: 1151, row: 33, col: 43}]); maxrange = tmp57[tmp58]; _aether.logStatement([{ofs: 1116, row: 33, col: 8}, {ofs: 1151, row: 33, col: 43}], _aether._userInfo, false);\n tmp60 = maxrange;\n _aether.logStatementStart([{ofs: 1161, row: 34, col: 9}, {ofs: 1170, row: 34, col: 18}]); tmp59 = !tmp60; _aether.logStatement([{ofs: 1161, row: 34, col: 9}, {ofs: 1170, row: 34, col: 18}], _aether._userInfo, false);\n if (tmp59) {\n _aether.logStatementStart([{ofs: 1174, row: 34, col: 22}, {ofs: 1188, row: 34, col: 36}]); maxrange = 10; _aether.logStatement([{ofs: 1174, row: 34, col: 22}, {ofs: 1188, row: 34, col: 36}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp64 = distance;\n tmp66 = maxrange;\n _aether.logStatementStart([{ofs: 1267, row: 36, col: 34}, {ofs: 1268, row: 36, col: 35}]); tmp67 = 3; _aether.logStatement([{ofs: 1267, row: 36, col: 34}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1256, row: 36, col: 23}, {ofs: 1268, row: 36, col: 35}]); tmp65 = tmp66 + tmp67; _aether.logStatement([{ofs: 1256, row: 36, col: 23}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1268, row: 36, col: 35}]); tmp63 = tmp64 < tmp65; _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n if (tmp63) {\n tmp70 = nearest;\n tmp71 = 'type';\n _aether.logStatementStart([{ofs: 1272, row: 36, col: 39}, {ofs: 1284, row: 36, col: 51}]); tmp68 = tmp70[tmp71]; _aether.logStatement([{ofs: 1272, row: 36, col: 39}, {ofs: 1284, row: 36, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1289, row: 36, col: 56}, {ofs: 1301, row: 36, col: 68}]); tmp69 = 'beam-tower'; _aether.logStatement([{ofs: 1289, row: 36, col: 56}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1272, row: 36, col: 39}, {ofs: 1301, row: 36, col: 68}]); tmp62 = tmp68 !== tmp69; _aether.logStatement([{ofs: 1272, row: 36, col: 39}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1301, row: 36, col: 68}]); tmp62 = tmp63; _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n }\n if (tmp62) {\n tmp74 = nearest;\n tmp75 = 'type';\n _aether.logStatementStart([{ofs: 1305, row: 36, col: 72}, {ofs: 1317, row: 36, col: 84}]); tmp72 = tmp74[tmp75]; _aether.logStatement([{ofs: 1305, row: 36, col: 72}, {ofs: 1317, row: 36, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1322, row: 36, col: 89}, {ofs: 1331, row: 36, col: 98}]); tmp73 = 'thrower'; _aether.logStatement([{ofs: 1322, row: 36, col: 89}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1305, row: 36, col: 72}, {ofs: 1331, row: 36, col: 98}]); tmp61 = tmp72 !== tmp73; _aether.logStatement([{ofs: 1305, row: 36, col: 72}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1331, row: 36, col: 98}]); tmp61 = tmp62; _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n }\n if (tmp61) {\n tmp81 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp82 = 'pos';\n _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1359, row: 37, col: 24}]); tmp79 = tmp81[tmp82]; _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1359, row: 37, col: 24}], _aether._userInfo, false);\n tmp80 = 'x';\n _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1361, row: 37, col: 26}]); tmp77 = tmp79[tmp80]; _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1361, row: 37, col: 26}], _aether._userInfo, false);\n tmp85 = nearest;\n tmp86 = 'pos';\n _aether.logStatementStart([{ofs: 1364, row: 37, col: 29}, {ofs: 1375, row: 37, col: 40}]); tmp83 = tmp85[tmp86]; _aether.logStatement([{ofs: 1364, row: 37, col: 29}, {ofs: 1375, row: 37, col: 40}], _aether._userInfo, false);\n tmp84 = 'x';\n _aether.logStatementStart([{ofs: 1364, row: 37, col: 29}, {ofs: 1377, row: 37, col: 42}]); tmp78 = tmp83[tmp84]; _aether.logStatement([{ofs: 1364, row: 37, col: 29}, {ofs: 1377, row: 37, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1377, row: 37, col: 42}]); tmp76 = tmp77 < tmp78; _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1377, row: 37, col: 42}], _aether._userInfo, false);\n if (tmp76) {\n tmp91 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp92 = 'pos';\n _aether.logStatementStart([{ofs: 1388, row: 37, col: 53}, {ofs: 1396, row: 37, col: 61}]); tmp89 = tmp91[tmp92]; _aether.logStatement([{ofs: 1388, row: 37, col: 53}, {ofs: 1396, row: 37, col: 61}], _aether._userInfo, false);\n tmp90 = 'x';\n _aether.logStatementStart([{ofs: 1388, row: 37, col: 53}, {ofs: 1398, row: 37, col: 63}]); tmp87 = tmp89[tmp90]; _aether.logStatement([{ofs: 1388, row: 37, col: 53}, {ofs: 1398, row: 37, col: 63}], _aether._userInfo, false);\n tmp93 = maxrange;\n _aether.logStatementStart([{ofs: 1413, row: 37, col: 78}, {ofs: 1414, row: 37, col: 79}]); tmp94 = 3; _aether.logStatement([{ofs: 1413, row: 37, col: 78}, {ofs: 1414, row: 37, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1402, row: 37, col: 67}, {ofs: 1414, row: 37, col: 79}]); tmp88 = tmp93 + tmp94; _aether.logStatement([{ofs: 1402, row: 37, col: 67}, {ofs: 1414, row: 37, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1381, row: 37, col: 46}, {ofs: 1416, row: 37, col: 81}]); newx = tmp87 - tmp88; _aether.logStatement([{ofs: 1381, row: 37, col: 46}, {ofs: 1416, row: 37, col: 81}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp101 = 'pos';\n _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1443, row: 38, col: 24}]); tmp98 = tmp100[tmp101]; _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1443, row: 38, col: 24}], _aether._userInfo, false);\n tmp99 = 'x';\n _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1445, row: 38, col: 26}]); tmp96 = tmp98[tmp99]; _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1445, row: 38, col: 26}], _aether._userInfo, false);\n tmp104 = nearest;\n tmp105 = 'pos';\n _aether.logStatementStart([{ofs: 1448, row: 38, col: 29}, {ofs: 1459, row: 38, col: 40}]); tmp102 = tmp104[tmp105]; _aether.logStatement([{ofs: 1448, row: 38, col: 29}, {ofs: 1459, row: 38, col: 40}], _aether._userInfo, false);\n tmp103 = 'x';\n _aether.logStatementStart([{ofs: 1448, row: 38, col: 29}, {ofs: 1461, row: 38, col: 42}]); tmp97 = tmp102[tmp103]; _aether.logStatement([{ofs: 1448, row: 38, col: 29}, {ofs: 1461, row: 38, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1461, row: 38, col: 42}]); tmp95 = tmp96 > tmp97; _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1461, row: 38, col: 42}], _aether._userInfo, false);\n if (tmp95) {\n tmp110 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp111 = 'pos';\n _aether.logStatementStart([{ofs: 1472, row: 38, col: 53}, {ofs: 1480, row: 38, col: 61}]); tmp108 = tmp110[tmp111]; _aether.logStatement([{ofs: 1472, row: 38, col: 53}, {ofs: 1480, row: 38, col: 61}], _aether._userInfo, false);\n tmp109 = 'x';\n _aether.logStatementStart([{ofs: 1472, row: 38, col: 53}, {ofs: 1482, row: 38, col: 63}]); tmp106 = tmp108[tmp109]; _aether.logStatement([{ofs: 1472, row: 38, col: 53}, {ofs: 1482, row: 38, col: 63}], _aether._userInfo, false);\n tmp112 = maxrange;\n _aether.logStatementStart([{ofs: 1497, row: 38, col: 78}, {ofs: 1498, row: 38, col: 79}]); tmp113 = 3; _aether.logStatement([{ofs: 1497, row: 38, col: 78}, {ofs: 1498, row: 38, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1486, row: 38, col: 67}, {ofs: 1498, row: 38, col: 79}]); tmp107 = tmp112 + tmp113; _aether.logStatement([{ofs: 1486, row: 38, col: 67}, {ofs: 1498, row: 38, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1465, row: 38, col: 46}, {ofs: 1500, row: 38, col: 81}]); newx = tmp106 + tmp107; _aether.logStatement([{ofs: 1465, row: 38, col: 46}, {ofs: 1500, row: 38, col: 81}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp119 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp120 = 'pos';\n _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1527, row: 39, col: 24}]); tmp117 = tmp119[tmp120]; _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1527, row: 39, col: 24}], _aether._userInfo, false);\n tmp118 = 'y';\n _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1529, row: 39, col: 26}]); tmp115 = tmp117[tmp118]; _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1529, row: 39, col: 26}], _aether._userInfo, false);\n tmp123 = nearest;\n tmp124 = 'pos';\n _aether.logStatementStart([{ofs: 1532, row: 39, col: 29}, {ofs: 1543, row: 39, col: 40}]); tmp121 = tmp123[tmp124]; _aether.logStatement([{ofs: 1532, row: 39, col: 29}, {ofs: 1543, row: 39, col: 40}], _aether._userInfo, false);\n tmp122 = 'y';\n _aether.logStatementStart([{ofs: 1532, row: 39, col: 29}, {ofs: 1545, row: 39, col: 42}]); tmp116 = tmp121[tmp122]; _aether.logStatement([{ofs: 1532, row: 39, col: 29}, {ofs: 1545, row: 39, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1545, row: 39, col: 42}]); tmp114 = tmp115 < tmp116; _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1545, row: 39, col: 42}], _aether._userInfo, false);\n if (tmp114) {\n tmp129 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp130 = 'pos';\n _aether.logStatementStart([{ofs: 1556, row: 39, col: 53}, {ofs: 1564, row: 39, col: 61}]); tmp127 = tmp129[tmp130]; _aether.logStatement([{ofs: 1556, row: 39, col: 53}, {ofs: 1564, row: 39, col: 61}], _aether._userInfo, false);\n tmp128 = 'y';\n _aether.logStatementStart([{ofs: 1556, row: 39, col: 53}, {ofs: 1566, row: 39, col: 63}]); tmp125 = tmp127[tmp128]; _aether.logStatement([{ofs: 1556, row: 39, col: 53}, {ofs: 1566, row: 39, col: 63}], _aether._userInfo, false);\n tmp131 = maxrange;\n _aether.logStatementStart([{ofs: 1581, row: 39, col: 78}, {ofs: 1582, row: 39, col: 79}]); tmp132 = 3; _aether.logStatement([{ofs: 1581, row: 39, col: 78}, {ofs: 1582, row: 39, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1570, row: 39, col: 67}, {ofs: 1582, row: 39, col: 79}]); tmp126 = tmp131 + tmp132; _aether.logStatement([{ofs: 1570, row: 39, col: 67}, {ofs: 1582, row: 39, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1549, row: 39, col: 46}, {ofs: 1584, row: 39, col: 81}]); newy = tmp125 - tmp126; _aether.logStatement([{ofs: 1549, row: 39, col: 46}, {ofs: 1584, row: 39, col: 81}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp139 = 'pos';\n _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1611, row: 40, col: 24}]); tmp136 = tmp138[tmp139]; _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1611, row: 40, col: 24}], _aether._userInfo, false);\n tmp137 = 'y';\n _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1613, row: 40, col: 26}]); tmp134 = tmp136[tmp137]; _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1613, row: 40, col: 26}], _aether._userInfo, false);\n tmp142 = nearest;\n tmp143 = 'pos';\n _aether.logStatementStart([{ofs: 1616, row: 40, col: 29}, {ofs: 1627, row: 40, col: 40}]); tmp140 = tmp142[tmp143]; _aether.logStatement([{ofs: 1616, row: 40, col: 29}, {ofs: 1627, row: 40, col: 40}], _aether._userInfo, false);\n tmp141 = 'y';\n _aether.logStatementStart([{ofs: 1616, row: 40, col: 29}, {ofs: 1629, row: 40, col: 42}]); tmp135 = tmp140[tmp141]; _aether.logStatement([{ofs: 1616, row: 40, col: 29}, {ofs: 1629, row: 40, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1629, row: 40, col: 42}]); tmp133 = tmp134 > tmp135; _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1629, row: 40, col: 42}], _aether._userInfo, false);\n if (tmp133) {\n tmp148 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp149 = 'pos';\n _aether.logStatementStart([{ofs: 1640, row: 40, col: 53}, {ofs: 1648, row: 40, col: 61}]); tmp146 = tmp148[tmp149]; _aether.logStatement([{ofs: 1640, row: 40, col: 53}, {ofs: 1648, row: 40, col: 61}], _aether._userInfo, false);\n tmp147 = 'y';\n _aether.logStatementStart([{ofs: 1640, row: 40, col: 53}, {ofs: 1650, row: 40, col: 63}]); tmp144 = tmp146[tmp147]; _aether.logStatement([{ofs: 1640, row: 40, col: 53}, {ofs: 1650, row: 40, col: 63}], _aether._userInfo, false);\n tmp150 = maxrange;\n _aether.logStatementStart([{ofs: 1665, row: 40, col: 78}, {ofs: 1666, row: 40, col: 79}]); tmp151 = 3; _aether.logStatement([{ofs: 1665, row: 40, col: 78}, {ofs: 1666, row: 40, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1654, row: 40, col: 67}, {ofs: 1666, row: 40, col: 79}]); tmp145 = tmp150 + tmp151; _aether.logStatement([{ofs: 1654, row: 40, col: 67}, {ofs: 1666, row: 40, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1633, row: 40, col: 46}, {ofs: 1668, row: 40, col: 81}]); newy = tmp144 + tmp145; _aether.logStatement([{ofs: 1633, row: 40, col: 46}, {ofs: 1668, row: 40, col: 81}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp154 = 'Math';\n tmp155 = tmp154 in __global;\n if (tmp155) {\n tmp152 = __global[tmp154];\n } else { _aether.logStatementStart([{ofs: 1690, row: 41, col: 19}, {ofs: 1694, row: 41, col: 23}]);\n tmp156 = 'ReferenceError';\n tmp157 = __global[tmp156];\n tmp158 = new tmp157('ReferenceError: ' + (tmp154 + ' is not defined'));\n throw tmp158;\n _aether.logStatement([{ofs: 1690, row: 41, col: 19}, {ofs: 1694, row: 41, col: 23}], _aether._userInfo, false); }\n tmp153 = 'round';\n tmp159 = newx;\n _aether.logStatementStart([{ofs: 1683, row: 41, col: 12}, {ofs: 1707, row: 41, col: 36}]); newx = _aether.createAPIClone(_aether, tmp152[tmp153](_aether.restoreAPIClone(_aether, tmp159))); _aether.logStatement([{ofs: 1683, row: 41, col: 12}, {ofs: 1707, row: 41, col: 36}], _aether._userInfo, false);\n tmp162 = 'Math';\n tmp163 = tmp162 in __global;\n if (tmp163) {\n tmp160 = __global[tmp162];\n } else { _aether.logStatementStart([{ofs: 1727, row: 42, col: 19}, {ofs: 1731, row: 42, col: 23}]);\n tmp164 = 'ReferenceError';\n tmp165 = __global[tmp164];\n tmp166 = new tmp165('ReferenceError: ' + (tmp162 + ' is not defined'));\n throw tmp166;\n _aether.logStatement([{ofs: 1727, row: 42, col: 19}, {ofs: 1731, row: 42, col: 23}], _aether._userInfo, false); }\n tmp161 = 'round';\n tmp167 = newy;\n _aether.logStatementStart([{ofs: 1720, row: 42, col: 12}, {ofs: 1744, row: 42, col: 36}]); newy = _aether.createAPIClone(_aether, tmp160[tmp161](_aether.restoreAPIClone(_aether, tmp167))); _aether.logStatement([{ofs: 1720, row: 42, col: 12}, {ofs: 1744, row: 42, col: 36}], _aether._userInfo, false);\n tmp169 = newx;\n if (tmp169) {\n tmp168 = newy;\n } else {\n _aether.logStatementStart([{ofs: 1761, row: 43, col: 16}, {ofs: 1773, row: 43, col: 28}]); tmp168 = tmp169; _aether.logStatement([{ofs: 1761, row: 43, col: 16}, {ofs: 1773, row: 43, col: 28}], _aether._userInfo, false);\n }\n if (tmp168) {\n tmp170 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp171 = 'move';\n tmp173 = newx;\n tmp174 = newy;\n _aether.logStatementStart([{ofs: 1884, row: 45, col: 26}, {ofs: 1902, row: 45, col: 44}]); tmp172 = {\n x: tmp173,\n y: tmp174\n }; _aether.logStatement([{ofs: 1884, row: 45, col: 26}, {ofs: 1902, row: 45, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1874, row: 45, col: 16}, {ofs: 1903, row: 45, col: 45}]); tmp175 = _aether.createAPIClone(_aether, tmp170[tmp171](_aether.restoreAPIClone(_aether, tmp172))); _aether.logStatement([{ofs: 1874, row: 45, col: 16}, {ofs: 1903, row: 45, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1928, row: 46, col: 23}, {ofs: 1937, row: 46, col: 32}]); tmp176 = 'evading'; _aether.logStatement([{ofs: 1928, row: 46, col: 23}, {ofs: 1937, row: 46, col: 32}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp176);\n } else {\n ;\n }\n } else {\n ;\n }\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 1980, row: 50, col: 11}, {ofs: 1987, row: 50, col: 18}]); tmp177 = 'clear'; _aether.logStatement([{ofs: 1980, row: 50, col: 11}, {ofs: 1987, row: 50, col: 18}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp177);\n }; _aether.logStatement([{ofs: 974, row: 29, col: 0}, {ofs: 2278, row: 59, col: 0}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 974, row: 29, col: 0}, {ofs: 1990, row: 51, col: 1}]); tmp48[tmp49] = tmp50; _aether.logStatement([{ofs: 974, row: 29, col: 0}, {ofs: 1990, row: 51, col: 1}], _aether._userInfo, false);\n tmp178 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp179 = 'attackLow';\n _aether.logStatementStart([{ofs: 2278, row: 59, col: 0}, {ofs: 3395, row: 95, col: 0}]); tmp180 = function (attackLoc, saying) {\n var lowHealth, enemies, enemy, e, evadeState, tmp181, tmp182, tmp183, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272; attackLoc = _aether.createAPIClone(_aether, attackLoc); saying = _aether.createAPIClone(_aether, saying); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp181 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp182 = 'attackLowMove';\n _aether.logStatementStart([{ofs: 2329, row: 60, col: 4}, {ofs: 2591, row: 70, col: 4}]); tmp183 = function () {\n var tmp184, tmp185, tmp186, tmp187, tmp188, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp188 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp189 = 'evade';\n _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2387, row: 61, col: 24}]); tmp186 = _aether.createAPIClone(_aether, tmp188[tmp189]()); _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2387, row: 61, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2391, row: 61, col: 28}, {ofs: 2398, row: 61, col: 35}]); tmp187 = 'clear'; _aether.logStatement([{ofs: 2391, row: 61, col: 28}, {ofs: 2398, row: 61, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2398, row: 61, col: 35}]); tmp185 = tmp186 == tmp187; _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2398, row: 61, col: 35}], _aether._userInfo, false);\n if (tmp185) {\n tmp192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp193 = 'now';\n _aether.logStatementStart([{ofs: 2402, row: 61, col: 39}, {ofs: 2412, row: 61, col: 49}]); tmp190 = _aether.createAPIClone(_aether, tmp192[tmp193]()); _aether.logStatement([{ofs: 2402, row: 61, col: 39}, {ofs: 2412, row: 61, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2415, row: 61, col: 52}, {ofs: 2416, row: 61, col: 53}]); tmp191 = 4; _aether.logStatement([{ofs: 2415, row: 61, col: 52}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2402, row: 61, col: 39}, {ofs: 2416, row: 61, col: 53}]); tmp184 = tmp190 > tmp191; _aether.logStatement([{ofs: 2402, row: 61, col: 39}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2416, row: 61, col: 53}]); tmp184 = tmp185; _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n }\n if (tmp184) {\n tmp197 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp198 = 'now';\n _aether.logStatementStart([{ofs: 2436, row: 62, col: 16}, {ofs: 2446, row: 62, col: 26}]); tmp195 = _aether.createAPIClone(_aether, tmp197[tmp198]()); _aether.logStatement([{ofs: 2436, row: 62, col: 16}, {ofs: 2446, row: 62, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2449, row: 62, col: 29}, {ofs: 2451, row: 62, col: 31}]); tmp196 = 15; _aether.logStatement([{ofs: 2449, row: 62, col: 29}, {ofs: 2451, row: 62, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2436, row: 62, col: 16}, {ofs: 2451, row: 62, col: 31}]); tmp194 = tmp195 < tmp196; _aether.logStatement([{ofs: 2436, row: 62, col: 16}, {ofs: 2451, row: 62, col: 31}], _aether._userInfo, false);\n if (tmp194) {\n tmp199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp200 = 'move';\n _aether.logStatementStart([{ofs: 2485, row: 63, col: 30}, {ofs: 2487, row: 63, col: 32}]); tmp202 = 68; _aether.logStatement([{ofs: 2485, row: 63, col: 30}, {ofs: 2487, row: 63, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2492, row: 63, col: 37}, {ofs: 2493, row: 63, col: 38}]); tmp203 = 8; _aether.logStatement([{ofs: 2492, row: 63, col: 37}, {ofs: 2493, row: 63, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2481, row: 63, col: 26}, {ofs: 2494, row: 63, col: 39}]); tmp201 = {\n x: tmp202,\n y: tmp203\n }; _aether.logStatement([{ofs: 2481, row: 63, col: 26}, {ofs: 2494, row: 63, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2471, row: 63, col: 16}, {ofs: 2495, row: 63, col: 40}]); tmp204 = _aether.createAPIClone(_aether, tmp199[tmp200](_aether.restoreAPIClone(_aether, tmp201))); _aether.logStatement([{ofs: 2471, row: 63, col: 16}, {ofs: 2495, row: 63, col: 40}], _aether._userInfo, false);\n } else {\n tmp205 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp206 = 'move';\n tmp207 = attackLoc;\n _aether.logStatementStart([{ofs: 2534, row: 65, col: 16}, {ofs: 2554, row: 65, col: 36}]); tmp208 = _aether.createAPIClone(_aether, tmp205[tmp206](_aether.restoreAPIClone(_aether, tmp207))); _aether.logStatement([{ofs: 2534, row: 65, col: 16}, {ofs: 2554, row: 65, col: 36}], _aether._userInfo, false);\n }\n } else {\n ;\n }\n return;\n }; _aether.logStatement([{ofs: 2329, row: 60, col: 4}, {ofs: 2591, row: 70, col: 4}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2329, row: 60, col: 4}, {ofs: 2585, row: 68, col: 5}]); tmp181[tmp182] = tmp183; _aether.logStatement([{ofs: 2329, row: 60, col: 4}, {ofs: 2585, row: 68, col: 5}], _aether._userInfo, false);\n tmp209 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp210 = 'getEnemies';\n _aether.logStatementStart([{ofs: 2657, row: 71, col: 4}, {ofs: 2685, row: 71, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp209[tmp210]()); _aether.logStatement([{ofs: 2657, row: 71, col: 4}, {ofs: 2685, row: 71, col: 32}], _aether._userInfo, false);\n tmp211 = enemies;\n if (tmp211) {\n _aether.logStatementStart([{ofs: 2713, row: 73, col: 8}, {ofs: 2734, row: 73, col: 29}]); lowHealth = 99999999; _aether.logStatement([{ofs: 2713, row: 73, col: 8}, {ofs: 2734, row: 73, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2752, row: 74, col: 17}, {ofs: 2753, row: 74, col: 18}]); e = 0; _aether.logStatement([{ofs: 2752, row: 74, col: 17}, {ofs: 2753, row: 74, col: 18}], _aether._userInfo, false);\n tmp213 = e;\n tmp215 = enemies;\n tmp216 = 'length';\n _aether.logStatementStart([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}]); tmp214 = tmp215[tmp216]; _aether.logStatement([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}]); tmp212 = tmp213 < tmp214; _aether.logStatement([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n tmp223: {\n while (tmp212) {\n tmp224: {\n tmp225 = enemies;\n tmp226 = e;\n _aether.logStatementStart([{ofs: 2794, row: 75, col: 12}, {ofs: 2813, row: 75, col: 31}]); enemy = tmp225[tmp226]; _aether.logStatement([{ofs: 2794, row: 75, col: 12}, {ofs: 2813, row: 75, col: 31}], _aether._userInfo, false);\n tmp231 = enemy;\n tmp232 = 'health';\n _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2842, row: 76, col: 28}]); tmp229 = tmp231[tmp232]; _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2842, row: 76, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2845, row: 76, col: 31}, {ofs: 2846, row: 76, col: 32}]); tmp230 = 0; _aether.logStatement([{ofs: 2845, row: 76, col: 31}, {ofs: 2846, row: 76, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2846, row: 76, col: 32}]); tmp228 = tmp229 > tmp230; _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2846, row: 76, col: 32}], _aether._userInfo, false);\n if (tmp228) {\n tmp235 = enemy;\n tmp236 = 'health';\n _aether.logStatementStart([{ofs: 2850, row: 76, col: 36}, {ofs: 2862, row: 76, col: 48}]); tmp233 = tmp235[tmp236]; _aether.logStatement([{ofs: 2850, row: 76, col: 36}, {ofs: 2862, row: 76, col: 48}], _aether._userInfo, false);\n tmp234 = lowHealth;\n _aether.logStatementStart([{ofs: 2850, row: 76, col: 36}, {ofs: 2874, row: 76, col: 60}]); tmp227 = tmp233 < tmp234; _aether.logStatement([{ofs: 2850, row: 76, col: 36}, {ofs: 2874, row: 76, col: 60}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2874, row: 76, col: 60}]); tmp227 = tmp228; _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2874, row: 76, col: 60}], _aether._userInfo, false);\n }\n if (tmp227) {\n tmp237 = enemy;\n tmp238 = 'health';\n _aether.logStatementStart([{ofs: 2894, row: 77, col: 16}, {ofs: 2919, row: 77, col: 41}]); lowHealth = tmp237[tmp238]; _aether.logStatement([{ofs: 2894, row: 77, col: 16}, {ofs: 2919, row: 77, col: 41}], _aether._userInfo, false);\n tmp239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp240 = 'lowTarget';\n tmp241 = enemy;\n _aether.logStatementStart([{ofs: 2936, row: 78, col: 16}, {ofs: 2958, row: 78, col: 38}]); tmp239[tmp240] = tmp241; _aether.logStatement([{ofs: 2936, row: 78, col: 16}, {ofs: 2958, row: 78, col: 38}], _aether._userInfo, false);\n } else {\n ;\n }\n }\n tmp221 = e;\n tmp222 = 1;\n e = tmp221 + tmp222;\n tmp217 = e;\n tmp219 = enemies;\n tmp220 = 'length';\n _aether.logStatementStart([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}]); tmp218 = tmp219[tmp220]; _aether.logStatement([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}]); tmp212 = tmp217 < tmp218; _aether.logStatement([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n }\n }\n tmp242 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp243 = 'evade';\n _aether.logStatementStart([{ofs: 2992, row: 81, col: 8}, {ofs: 3018, row: 81, col: 34}]); evadeState = _aether.createAPIClone(_aether, tmp242[tmp243]()); _aether.logStatement([{ofs: 2992, row: 81, col: 8}, {ofs: 3018, row: 81, col: 34}], _aether._userInfo, false);\n tmp247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp248 = 'lowTarget';\n _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3045, row: 82, col: 26}]); tmp246 = tmp247[tmp248]; _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3045, row: 82, col: 26}], _aether._userInfo, false);\n if (tmp246) {\n tmp253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp254 = 'lowTarget';\n _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3063, row: 82, col: 44}]); tmp251 = tmp253[tmp254]; _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3063, row: 82, col: 44}], _aether._userInfo, false);\n tmp252 = 'health';\n _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3070, row: 82, col: 51}]); tmp249 = tmp251[tmp252]; _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3070, row: 82, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3073, row: 82, col: 54}, {ofs: 3074, row: 82, col: 55}]); tmp250 = 0; _aether.logStatement([{ofs: 3073, row: 82, col: 54}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3074, row: 82, col: 55}]); tmp245 = tmp249 > tmp250; _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3074, row: 82, col: 55}]); tmp245 = tmp246; _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n }\n if (tmp245) {\n tmp255 = evadeState;\n _aether.logStatementStart([{ofs: 3092, row: 82, col: 73}, {ofs: 3099, row: 82, col: 80}]); tmp256 = 'clear'; _aether.logStatement([{ofs: 3092, row: 82, col: 73}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3078, row: 82, col: 59}, {ofs: 3099, row: 82, col: 80}]); tmp244 = tmp255 == tmp256; _aether.logStatement([{ofs: 3078, row: 82, col: 59}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3099, row: 82, col: 80}]); tmp244 = tmp245; _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n }\n if (tmp244) {\n tmp257 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp258 = 'say';\n tmp259 = saying;\n _aether.logStatementStart([{ofs: 3115, row: 83, col: 12}, {ofs: 3131, row: 83, col: 28}]); tmp260 = _aether.createAPIClone(_aether, tmp257[tmp258](_aether.restoreAPIClone(_aether, tmp259))); _aether.logStatement([{ofs: 3115, row: 83, col: 12}, {ofs: 3131, row: 83, col: 28}], _aether._userInfo, false);\n tmp261 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp262 = 'attack';\n tmp264 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp265 = 'lowTarget';\n _aether.logStatementStart([{ofs: 3157, row: 84, col: 24}, {ofs: 3171, row: 84, col: 38}]); tmp263 = tmp264[tmp265]; _aether.logStatement([{ofs: 3157, row: 84, col: 24}, {ofs: 3171, row: 84, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3145, row: 84, col: 12}, {ofs: 3172, row: 84, col: 39}]); tmp266 = _aether.createAPIClone(_aether, tmp261[tmp262](_aether.restoreAPIClone(_aether, tmp263))); _aether.logStatement([{ofs: 3145, row: 84, col: 12}, {ofs: 3172, row: 84, col: 39}], _aether._userInfo, false);\n } else {\n tmp267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp268 = 'attackLowMove';\n _aether.logStatementStart([{ofs: 3203, row: 86, col: 12}, {ofs: 3223, row: 86, col: 32}]); tmp269 = _aether.createAPIClone(_aether, tmp267[tmp268]()); _aether.logStatement([{ofs: 3203, row: 86, col: 12}, {ofs: 3223, row: 86, col: 32}], _aether._userInfo, false);\n }\n } else {\n tmp270 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp271 = 'attackLowMove';\n _aether.logStatementStart([{ofs: 3256, row: 89, col: 8}, {ofs: 3276, row: 89, col: 28}]); tmp272 = _aether.createAPIClone(_aether, tmp270[tmp271]()); _aether.logStatement([{ofs: 3256, row: 89, col: 8}, {ofs: 3276, row: 89, col: 28}], _aether._userInfo, false);\n }\n return;\n }; _aether.logStatement([{ofs: 2278, row: 59, col: 0}, {ofs: 3395, row: 95, col: 0}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2278, row: 59, col: 0}, {ofs: 3285, row: 91, col: 1}]); tmp178[tmp179] = tmp180; _aether.logStatement([{ofs: 2278, row: 59, col: 0}, {ofs: 3285, row: 91, col: 1}], _aether._userInfo, false);\n tmp278 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp279 = 'buildIndex';\n _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3414, row: 95, col: 19}]); tmp276 = tmp278[tmp279]; _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3414, row: 95, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3418, row: 95, col: 23}, {ofs: 3419, row: 95, col: 24}]); tmp277 = 1; _aether.logStatement([{ofs: 3418, row: 95, col: 23}, {ofs: 3419, row: 95, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3419, row: 95, col: 24}]); tmp275 = tmp276 == tmp277; _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3419, row: 95, col: 24}], _aether._userInfo, false);\n if (tmp275) {\n tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp283 = 'now';\n _aether.logStatementStart([{ofs: 3423, row: 95, col: 28}, {ofs: 3433, row: 95, col: 38}]); tmp280 = _aether.createAPIClone(_aether, tmp282[tmp283]()); _aether.logStatement([{ofs: 3423, row: 95, col: 28}, {ofs: 3433, row: 95, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3436, row: 95, col: 41}, {ofs: 3437, row: 95, col: 42}]); tmp281 = 9; _aether.logStatement([{ofs: 3436, row: 95, col: 41}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3423, row: 95, col: 28}, {ofs: 3437, row: 95, col: 42}]); tmp274 = tmp280 < tmp281; _aether.logStatement([{ofs: 3423, row: 95, col: 28}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3437, row: 95, col: 42}]); tmp274 = tmp275; _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n }\n if (tmp274) {\n tmp288 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp289 = 'getItems';\n _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3456, row: 95, col: 61}]); tmp286 = _aether.createAPIClone(_aether, tmp288[tmp289]()); _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3456, row: 95, col: 61}], _aether._userInfo, false);\n tmp287 = 'length';\n _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3463, row: 95, col: 68}]); tmp284 = tmp286[tmp287]; _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3463, row: 95, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3466, row: 95, col: 71}, {ofs: 3467, row: 95, col: 72}]); tmp285 = 0; _aether.logStatement([{ofs: 3466, row: 95, col: 71}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3467, row: 95, col: 72}]); tmp273 = tmp284 > tmp285; _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3467, row: 95, col: 72}]); tmp273 = tmp274; _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n }\n if (tmp273) {\n tmp290 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp291 = 'move';\n _aether.logStatementStart([{ofs: 3489, row: 96, col: 18}, {ofs: 3491, row: 96, col: 20}]); tmp293 = 13; _aether.logStatement([{ofs: 3489, row: 96, col: 18}, {ofs: 3491, row: 96, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3496, row: 96, col: 25}, {ofs: 3498, row: 96, col: 27}]); tmp294 = 15; _aether.logStatement([{ofs: 3496, row: 96, col: 25}, {ofs: 3498, row: 96, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3485, row: 96, col: 14}, {ofs: 3499, row: 96, col: 28}]); tmp292 = {\n x: tmp293,\n y: tmp294\n }; _aether.logStatement([{ofs: 3485, row: 96, col: 14}, {ofs: 3499, row: 96, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3475, row: 96, col: 4}, {ofs: 3500, row: 96, col: 29}]); tmp295 = _aether.createAPIClone(_aether, tmp290[tmp291](_aether.restoreAPIClone(_aether, tmp292))); _aether.logStatement([{ofs: 3475, row: 96, col: 4}, {ofs: 3500, row: 96, col: 29}], _aether._userInfo, false);\n tmp296 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp297 = 'getGold';\n _aether.logStatementStart([{ofs: 3519, row: 97, col: 17}, {ofs: 3525, row: 97, col: 23}]); tmp298 = 'left'; _aether.logStatement([{ofs: 3519, row: 97, col: 17}, {ofs: 3525, row: 97, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3527, row: 97, col: 25}, {ofs: 3553, row: 97, col: 51}]); tmp299 = 'I\\'m feeling just golden!'; _aether.logStatement([{ofs: 3527, row: 97, col: 25}, {ofs: 3553, row: 97, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3506, row: 97, col: 4}, {ofs: 3554, row: 97, col: 52}]); tmp300 = _aether.createAPIClone(_aether, tmp296[tmp297](_aether.restoreAPIClone(_aether, tmp298), _aether.restoreAPIClone(_aether, tmp299))); _aether.logStatement([{ofs: 3506, row: 97, col: 4}, {ofs: 3554, row: 97, col: 52}], _aether._userInfo, false);\n } else {\n tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp307 = 'buildIndex';\n _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3582, row: 98, col: 26}]); tmp304 = tmp306[tmp307]; _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3582, row: 98, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3586, row: 98, col: 30}, {ofs: 3587, row: 98, col: 31}]); tmp305 = 0; _aether.logStatement([{ofs: 3586, row: 98, col: 30}, {ofs: 3587, row: 98, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3587, row: 98, col: 31}]); tmp303 = tmp304 == tmp305; _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3587, row: 98, col: 31}], _aether._userInfo, false);\n if (tmp303) {\n tmp310 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp311 = 'now';\n _aether.logStatementStart([{ofs: 3591, row: 98, col: 35}, {ofs: 3601, row: 98, col: 45}]); tmp308 = _aether.createAPIClone(_aether, tmp310[tmp311]()); _aether.logStatement([{ofs: 3591, row: 98, col: 35}, {ofs: 3601, row: 98, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3604, row: 98, col: 48}, {ofs: 3605, row: 98, col: 49}]); tmp309 = 9; _aether.logStatement([{ofs: 3604, row: 98, col: 48}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3591, row: 98, col: 35}, {ofs: 3605, row: 98, col: 49}]); tmp302 = tmp308 < tmp309; _aether.logStatement([{ofs: 3591, row: 98, col: 35}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3605, row: 98, col: 49}]); tmp302 = tmp303; _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n }\n if (tmp302) {\n tmp316 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp317 = 'getItems';\n _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3624, row: 98, col: 68}]); tmp314 = _aether.createAPIClone(_aether, tmp316[tmp317]()); _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3624, row: 98, col: 68}], _aether._userInfo, false);\n tmp315 = 'length';\n _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3631, row: 98, col: 75}]); tmp312 = tmp314[tmp315]; _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3631, row: 98, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3634, row: 98, col: 78}, {ofs: 3635, row: 98, col: 79}]); tmp313 = 0; _aether.logStatement([{ofs: 3634, row: 98, col: 78}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3635, row: 98, col: 79}]); tmp301 = tmp312 > tmp313; _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3635, row: 98, col: 79}]); tmp301 = tmp302; _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n }\n if (tmp301) {\n tmp318 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp319 = 'move';\n _aether.logStatementStart([{ofs: 3657, row: 99, col: 18}, {ofs: 3659, row: 99, col: 20}]); tmp321 = 74; _aether.logStatement([{ofs: 3657, row: 99, col: 18}, {ofs: 3659, row: 99, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3664, row: 99, col: 25}, {ofs: 3666, row: 99, col: 27}]); tmp322 = 30; _aether.logStatement([{ofs: 3664, row: 99, col: 25}, {ofs: 3666, row: 99, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3653, row: 99, col: 14}, {ofs: 3667, row: 99, col: 28}]); tmp320 = {\n x: tmp321,\n y: tmp322\n }; _aether.logStatement([{ofs: 3653, row: 99, col: 14}, {ofs: 3667, row: 99, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3643, row: 99, col: 4}, {ofs: 3668, row: 99, col: 29}]); tmp323 = _aether.createAPIClone(_aether, tmp318[tmp319](_aether.restoreAPIClone(_aether, tmp320))); _aether.logStatement([{ofs: 3643, row: 99, col: 4}, {ofs: 3668, row: 99, col: 29}], _aether._userInfo, false);\n tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp325 = 'getGold';\n _aether.logStatementStart([{ofs: 3687, row: 100, col: 17}, {ofs: 3694, row: 100, col: 24}]); tmp326 = 'right'; _aether.logStatement([{ofs: 3687, row: 100, col: 17}, {ofs: 3694, row: 100, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3696, row: 100, col: 26}, {ofs: 3726, row: 100, col: 56}]); tmp327 = 'I\\'m feeling just golden too!'; _aether.logStatement([{ofs: 3696, row: 100, col: 26}, {ofs: 3726, row: 100, col: 56}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3674, row: 100, col: 4}, {ofs: 3727, row: 100, col: 57}]); tmp328 = _aether.createAPIClone(_aether, tmp324[tmp325](_aether.restoreAPIClone(_aether, tmp326), _aether.restoreAPIClone(_aether, tmp327))); _aether.logStatement([{ofs: 3674, row: 100, col: 4}, {ofs: 3727, row: 100, col: 57}], _aether._userInfo, false);\n } else {\n tmp329 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp330 = 'attackLow';\n _aether.logStatementStart([{ofs: 3761, row: 102, col: 23}, {ofs: 3763, row: 102, col: 25}]); tmp333 = 70; _aether.logStatement([{ofs: 3761, row: 102, col: 23}, {ofs: 3763, row: 102, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3768, row: 102, col: 30}, {ofs: 3770, row: 102, col: 32}]); tmp334 = 70; _aether.logStatement([{ofs: 3768, row: 102, col: 30}, {ofs: 3770, row: 102, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3757, row: 102, col: 19}, {ofs: 3771, row: 102, col: 33}]); tmp331 = {\n x: tmp333,\n y: tmp334\n }; _aether.logStatement([{ofs: 3757, row: 102, col: 19}, {ofs: 3771, row: 102, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3773, row: 102, col: 35}, {ofs: 3777, row: 102, col: 39}]); tmp332 = ':)'; _aether.logStatement([{ofs: 3773, row: 102, col: 35}, {ofs: 3777, row: 102, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3742, row: 102, col: 4}, {ofs: 3778, row: 102, col: 40}]); tmp335 = _aether.createAPIClone(_aether, tmp329[tmp330](_aether.restoreAPIClone(_aether, tmp331), _aether.restoreAPIClone(_aether, tmp332))); _aether.logStatement([{ofs: 3742, row: 102, col: 4}, {ofs: 3778, row: 102, col: 40}], _aether._userInfo, false);\n }\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));", + "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function (speaker, message, data) {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = speaker;\n tmp6 = 'team';\n _aether.logStatementStart([{ofs: 80, row: 1, col: 3}, {ofs: 92, row: 1, col: 15}]); tmp3 = tmp5[tmp6]; _aether.logStatement([{ofs: 80, row: 1, col: 3}, {ofs: 92, row: 1, col: 15}], _aether._userInfo, false);\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp8 = 'team';\n _aether.logStatementStart([{ofs: 97, row: 1, col: 20}, {ofs: 106, row: 1, col: 29}]); tmp4 = tmp7[tmp8]; _aether.logStatement([{ofs: 97, row: 1, col: 20}, {ofs: 106, row: 1, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 80, row: 1, col: 3}, {ofs: 106, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4; _aether.logStatement([{ofs: 80, row: 1, col: 3}, {ofs: 106, row: 1, col: 29}], _aether._userInfo, false);\n if (tmp2) {\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'hear';\n __global[tmp0] = tmp1;\n}(this));" + }, + "human-base": { + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var type, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47, tmp48; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp6 = 'cannonNum';\n _aether.logStatementStart([{ofs: 266, row: 7, col: 5}, {ofs: 280, row: 7, col: 19}]); tmp4 = tmp5[tmp6]; _aether.logStatement([{ofs: 266, row: 7, col: 5}, {ofs: 280, row: 7, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 265, row: 7, col: 4}, {ofs: 280, row: 7, col: 19}]); tmp3 = !tmp4; _aether.logStatement([{ofs: 265, row: 7, col: 4}, {ofs: 280, row: 7, col: 19}], _aether._userInfo, false);\n if (tmp3) {\n tmp8 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp9 = 'goldRushNum';\n _aether.logStatementStart([{ofs: 285, row: 7, col: 24}, {ofs: 301, row: 7, col: 40}]); tmp7 = tmp8[tmp9]; _aether.logStatement([{ofs: 285, row: 7, col: 24}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 284, row: 7, col: 23}, {ofs: 301, row: 7, col: 40}]); tmp2 = !tmp7; _aether.logStatement([{ofs: 284, row: 7, col: 23}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 265, row: 7, col: 4}, {ofs: 301, row: 7, col: 40}]); tmp2 = tmp3; _aether.logStatement([{ofs: 265, row: 7, col: 4}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n }\n if (tmp2) {\n tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp11 = 'cannonNum';\n _aether.logStatementStart([{ofs: 309, row: 8, col: 4}, {ofs: 328, row: 8, col: 23}]); tmp12 = 0; _aether.logStatement([{ofs: 309, row: 8, col: 4}, {ofs: 328, row: 8, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 309, row: 8, col: 4}, {ofs: 327, row: 8, col: 22}]); tmp10[tmp11] = tmp12; _aether.logStatement([{ofs: 309, row: 8, col: 4}, {ofs: 327, row: 8, col: 22}], _aether._userInfo, false);\n tmp13 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp14 = 'goldRushNum';\n _aether.logStatementStart([{ofs: 333, row: 9, col: 4}, {ofs: 354, row: 9, col: 25}]); tmp15 = 0; _aether.logStatement([{ofs: 333, row: 9, col: 4}, {ofs: 354, row: 9, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 333, row: 9, col: 4}, {ofs: 353, row: 9, col: 24}]); tmp13[tmp14] = tmp15; _aether.logStatement([{ofs: 333, row: 9, col: 4}, {ofs: 353, row: 9, col: 24}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 426, row: 14, col: 0}, {ofs: 446, row: 14, col: 20}]); type = 'archer'; _aether.logStatement([{ofs: 426, row: 14, col: 0}, {ofs: 446, row: 14, col: 20}], _aether._userInfo, false);\n tmp19 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp20 = 'goldRushNum';\n _aether.logStatementStart([{ofs: 659, row: 24, col: 3}, {ofs: 675, row: 24, col: 19}]); tmp17 = tmp19[tmp20]; _aether.logStatement([{ofs: 659, row: 24, col: 3}, {ofs: 675, row: 24, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 678, row: 24, col: 22}, {ofs: 679, row: 24, col: 23}]); tmp18 = 3; _aether.logStatement([{ofs: 678, row: 24, col: 22}, {ofs: 679, row: 24, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 659, row: 24, col: 3}, {ofs: 679, row: 24, col: 23}]); tmp16 = tmp17 < tmp18; _aether.logStatement([{ofs: 659, row: 24, col: 3}, {ofs: 679, row: 24, col: 23}], _aether._userInfo, false);\n if (tmp16) {\n _aether.logStatementStart([{ofs: 687, row: 25, col: 4}, {ofs: 703, row: 25, col: 20}]); type = 'archer'; _aether.logStatement([{ofs: 687, row: 25, col: 4}, {ofs: 703, row: 25, col: 20}], _aether._userInfo, false);\n tmp21 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp22 = 'goldRushNum';\n tmp26 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp27 = 'goldRushNum';\n _aether.logStatementStart([{ofs: 727, row: 26, col: 23}, {ofs: 743, row: 26, col: 39}]); tmp24 = tmp26[tmp27]; _aether.logStatement([{ofs: 727, row: 26, col: 23}, {ofs: 743, row: 26, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 746, row: 26, col: 42}, {ofs: 747, row: 26, col: 43}]); tmp25 = 1; _aether.logStatement([{ofs: 746, row: 26, col: 42}, {ofs: 747, row: 26, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 708, row: 26, col: 4}, {ofs: 748, row: 26, col: 44}]); tmp23 = tmp24 + tmp25; _aether.logStatement([{ofs: 708, row: 26, col: 4}, {ofs: 748, row: 26, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 708, row: 26, col: 4}, {ofs: 747, row: 26, col: 43}]); tmp21[tmp22] = tmp23; _aether.logStatement([{ofs: 708, row: 26, col: 4}, {ofs: 747, row: 26, col: 43}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp32 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp33 = 'cannonNum';\n _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 828, row: 31, col: 17}]); tmp30 = tmp32[tmp33]; _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 828, row: 31, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 831, row: 31, col: 20}, {ofs: 832, row: 31, col: 21}]); tmp31 = 1; _aether.logStatement([{ofs: 831, row: 31, col: 20}, {ofs: 832, row: 31, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 832, row: 31, col: 21}]); tmp29 = tmp30 < tmp31; _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 832, row: 31, col: 21}], _aether._userInfo, false);\n if (tmp29) {\n tmp36 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp37 = 'goldRushNum';\n _aether.logStatementStart([{ofs: 836, row: 31, col: 25}, {ofs: 852, row: 31, col: 41}]); tmp34 = tmp36[tmp37]; _aether.logStatement([{ofs: 836, row: 31, col: 25}, {ofs: 852, row: 31, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 857, row: 31, col: 46}, {ofs: 858, row: 31, col: 47}]); tmp35 = 3; _aether.logStatement([{ofs: 857, row: 31, col: 46}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 836, row: 31, col: 25}, {ofs: 858, row: 31, col: 47}]); tmp28 = tmp34 === tmp35; _aether.logStatement([{ofs: 836, row: 31, col: 25}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 858, row: 31, col: 47}]); tmp28 = tmp29; _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n }\n if (tmp28) {\n _aether.logStatementStart([{ofs: 871, row: 32, col: 8}, {ofs: 890, row: 32, col: 27}]); type = 'artillery'; _aether.logStatement([{ofs: 871, row: 32, col: 8}, {ofs: 890, row: 32, col: 27}], _aether._userInfo, false);\n tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp39 = 'cannonNum';\n tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp44 = 'cannonNum';\n _aether.logStatementStart([{ofs: 916, row: 33, col: 25}, {ofs: 930, row: 33, col: 39}]); tmp41 = tmp43[tmp44]; _aether.logStatement([{ofs: 916, row: 33, col: 25}, {ofs: 930, row: 33, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 933, row: 33, col: 42}, {ofs: 934, row: 33, col: 43}]); tmp42 = 1; _aether.logStatement([{ofs: 933, row: 33, col: 42}, {ofs: 934, row: 33, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 899, row: 33, col: 8}, {ofs: 935, row: 33, col: 44}]); tmp40 = tmp41 + tmp42; _aether.logStatement([{ofs: 899, row: 33, col: 8}, {ofs: 935, row: 33, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 899, row: 33, col: 8}, {ofs: 934, row: 33, col: 43}]); tmp38[tmp39] = tmp40; _aether.logStatement([{ofs: 899, row: 33, col: 8}, {ofs: 934, row: 33, col: 43}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp46 = 'build';\n tmp47 = type;\n _aether.logStatementStart([{ofs: 1047, row: 38, col: 0}, {ofs: 1063, row: 38, col: 16}]); tmp48 = _aether.createAPIClone(_aether, tmp45[tmp46](_aether.restoreAPIClone(_aether, tmp47))); _aether.logStatement([{ofs: 1047, row: 38, col: 0}, {ofs: 1063, row: 38, col: 16}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));", + "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function (speaker, message, data) {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp5 = speaker;\n tmp6 = 'team';\n _aether.logStatementStart([{ofs: 78, row: 1, col: 3}, {ofs: 90, row: 1, col: 15}]); tmp3 = tmp5[tmp6]; _aether.logStatement([{ofs: 78, row: 1, col: 3}, {ofs: 90, row: 1, col: 15}], _aether._userInfo, false);\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp8 = 'team';\n _aether.logStatementStart([{ofs: 95, row: 1, col: 20}, {ofs: 104, row: 1, col: 29}]); tmp4 = tmp7[tmp8]; _aether.logStatement([{ofs: 95, row: 1, col: 20}, {ofs: 104, row: 1, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 78, row: 1, col: 3}, {ofs: 104, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4; _aether.logStatement([{ofs: 78, row: 1, col: 3}, {ofs: 104, row: 1, col: 29}], _aether._userInfo, false);\n if (tmp2) {\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'hear';\n __global[tmp0] = tmp1;\n}(this));" } }, "submittedCodeLanguage": "javascript", - "playtime": 107, + "playtime": 178, "codeLanguage": "javascript" }, { "_id": "5317ad4909098828ed071f4d", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, "team": "humans", "levelID": "dungeon-arena", "levelName": "Dungeon Arena", @@ -511,18 +644,34 @@ responses = "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n" }, "tharin-1": { - "chooseAction": "..." + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n _aether.logCallStart(this._aetherUserInfo); var enemies, enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;\n tmp2 = 'use strict';\n tmp3 = __interceptThis(this, __global);\n tmp4 = 'getEnemies';\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}]); enemies = tmp3[tmp4](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}], \"var enemies = this.getEnemies();\", this._aetherUserInfo);\n tmp5 = __interceptThis(this, __global);\n tmp6 = 'getNearest';\n tmp7 = enemies;\n _aether.logStatementStart([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}]); enemy = tmp5[tmp6](tmp7); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}], \"var enemy = this.getNearest(enemies);\", this._aetherUserInfo);\n tmp10 = __interceptThis(this, __global);\n tmp11 = 'getCooldown';\n _aether.logStatementStart([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}]); tmp12 = 'warcry'; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}], \"'warcry'\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}]); tmp9 = tmp10[tmp11](tmp12); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}], \"this.getCooldown('warcry')\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}]); tmp8 = !tmp9; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}], \"!this.getCooldown('warcry')\", this._aetherUserInfo);\n if (tmp8) {\n tmp13 = __interceptThis(this, __global);\n tmp14 = 'warcry';\n _aether.logStatementStart([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}]); tmp15 = tmp13[tmp14](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}], \"this.warcry()\", this._aetherUserInfo);\n } else {\n tmp16 = enemy;\n if (tmp16) {\n tmp17 = __interceptThis(this, __global);\n tmp18 = 'attack';\n tmp19 = enemy;\n _aether.logStatementStart([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}]); tmp20 = tmp17[tmp18](tmp19); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}], \"this.attack(enemy)\", this._aetherUserInfo);\n } else {\n tmp21 = __interceptThis(this, __global);\n tmp22 = 'move';\n _aether.logStatementStart([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}]); tmp24 = 10; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}], \"10\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}]); tmp25 = 30; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}], \"30\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}]); tmp23 = {\n x: tmp24,\n y: tmp25\n }; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}], \"{x: 10, y: 30}\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}]); tmp26 = tmp21[tmp22](tmp23); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}], \"this.move({x: 10, y: 30})\", this._aetherUserInfo);\n }\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" }, "programmable-tharin": { "chooseAction": "/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n If they fully base race us, we actually do want to produce archers since they DPS faster\n The effective DPS on soldiers is better if they attack us\n but worse if they straight race us\n\n //not sure if this is good but...\n if they're attacking our base with a small number of units\n we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n} \nif (!this.getCooldown('warcry') && friends.length > 5) {\n this.warcry();\n} \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n this.shield();\n}\nelse {\n this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/" } }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, "submittedCodeLanguage": "javascript", - "playtime": 9634, + "playtime": 9753, "codeLanguage": "javascript" }, { "_id": "53361c80948ad7a777a10d9c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, "team": "ogres", "levelID": "gold-rush", "levelName": "Gold Rush", @@ -534,7 +683,18 @@ responses = "chooseAction": "var items = this.getItems();\nvar enemy = this.getNearestEnemy();\n\nvar c = new Vector(60, 40);\n//this.say(Math.round(c.x) + \", \" + Math.round(c.y));\nvar bestItem = null;\nvar bestValue = 0;\nvar canJump = !this.getCooldown('jump');\nvar i, item, d1, d2, d3, value;\nfor (i = 0; i < items.length; ++i) {\n item = items[i];\n d1 = this.distance(item) * (canJump ? 0.5 : 1);\n d2 = c.distance(item.pos);\n value = item.bountyGold / (d1 + d2 / 5);\n if (value > bestValue) {\n bestItem = item;\n bestValue = value;\n }\n} \n\nMath.random(); Math.random(); Math.random();\nvar secondBestItem = null;\nvar secondBestValue = 0;\nfor (i = 0; i < items.length; ++i) {\n if (item == bestItem) continue;\n item = items[i];\n d1 = this.distance(item);\n d2 = c.distance(item.pos);\n d3 = item.pos.distance(bestItem);\n value = item.bountyGold / (d1 + d2 / 5 + d3);\n if (value > secondBestValue) {\n secondBestItem = item;\n secondBestValue = value;\n }\n}\n\nif (!canJump && secondBestItem && this.distance(secondBestItem) < this.distance(bestItem))\n bestItem = secondBestItem; // Pick it up on the way.\nif (bestItem) {\n if(canJump && this.distance(bestItem) > 30)\n this.jumpTo(bestItem);\n else\n this.move(bestItem.pos);\n}" } }, - "totalScore": 40.77678387026546, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "totalScore": 40.73558595296533, "submitted": true, "submittedCodeLanguage": "javascript", "playtime": 1014, @@ -542,6 +702,10 @@ responses = }, { "_id": "531920069f44be00001a7aef", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, "team": "ogres", "levelID": "dungeon-arena", "levelName": "Dungeon Arena", @@ -549,13 +713,13 @@ responses = "totalScore": 26.50666470188054, "code": { "human-base": { - "chooseAction": "..." + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var hero, count, ranged, i, tmp2, tmp3, tmp4, tmp45, tmp46, tmp47, tmp88, tmp89, tmp90, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185, tmp186, tmp187, tmp188, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp336, tmp337, tmp338, tmp339, tmp340, tmp341, tmp342, tmp343, tmp344, tmp345, tmp346, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370, tmp371, tmp372, tmp373, tmp374, tmp375, tmp376, tmp377, tmp378, tmp379, tmp380, tmp381, tmp382, tmp383, tmp384, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392, tmp393, tmp394, tmp395, tmp396, tmp397, tmp398, tmp399, tmp400, tmp401, tmp402, tmp403, tmp404, tmp405, tmp406, tmp407, tmp408, tmp409, tmp410, tmp411, tmp412, tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419, tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427, tmp428, tmp429, tmp430, tmp431, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440, tmp441, tmp442, tmp443, tmp444, tmp445, tmp446, tmp447, tmp448, tmp449, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getEnemyHero';\n _aether.logStatementStart([{ofs: 222, row: 4, col: 0}, {ofs: 489, row: 11, col: 2}]); tmp4 = function () {\n var i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 305, row: 6, col: 9}, {ofs: 314, row: 6, col: 18}]); i = 0; _aether.logStatement([{ofs: 305, row: 6, col: 9}, {ofs: 314, row: 6, col: 18}], _aether._userInfo, false);\n tmp6 = i;\n tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp11 = 'enemies';\n _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}]); tmp8 = tmp10[tmp11]; _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}], _aether._userInfo, false);\n tmp9 = 'length';\n _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}]); tmp7 = tmp8[tmp9]; _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}]); tmp5 = tmp6 < tmp7; _aether.logStatement([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n tmp20: {\n while (tmp5) {\n tmp21: {\n tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp31 = 'enemies';\n _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 372, row: 7, col: 24}]); tmp28 = tmp30[tmp31]; _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 372, row: 7, col: 24}], _aether._userInfo, false);\n tmp29 = i;\n _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 375, row: 7, col: 27}]); tmp26 = tmp28[tmp29]; _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 375, row: 7, col: 27}], _aether._userInfo, false);\n tmp27 = 'type';\n _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 380, row: 7, col: 32}]); tmp24 = tmp26[tmp27]; _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 380, row: 7, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 385, row: 7, col: 37}, {ofs: 394, row: 7, col: 46}]); tmp25 = 'brawler'; _aether.logStatement([{ofs: 385, row: 7, col: 37}, {ofs: 394, row: 7, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 394, row: 7, col: 46}]); tmp23 = tmp24 === tmp25; _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 394, row: 7, col: 46}], _aether._userInfo, false);\n if (tmp23) {\n _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 431, row: 7, col: 83}]); tmp22 = tmp23; _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n } else {\n tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp39 = 'enemies';\n _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 410, row: 7, col: 62}]); tmp36 = tmp38[tmp39]; _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 410, row: 7, col: 62}], _aether._userInfo, false);\n tmp37 = i;\n _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 413, row: 7, col: 65}]); tmp34 = tmp36[tmp37]; _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 413, row: 7, col: 65}], _aether._userInfo, false);\n tmp35 = 'type';\n _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 418, row: 7, col: 70}]); tmp32 = tmp34[tmp35]; _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 418, row: 7, col: 70}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 423, row: 7, col: 75}, {ofs: 431, row: 7, col: 83}]); tmp33 = 'shaman'; _aether.logStatement([{ofs: 423, row: 7, col: 75}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 431, row: 7, col: 83}]); tmp22 = tmp32 === tmp33; _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n }\n if (tmp22) {\n tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp44 = 'enemies';\n _aether.logStatementStart([{ofs: 454, row: 8, col: 19}, {ofs: 466, row: 8, col: 31}]); tmp41 = tmp43[tmp44]; _aether.logStatement([{ofs: 454, row: 8, col: 19}, {ofs: 466, row: 8, col: 31}], _aether._userInfo, false);\n tmp42 = i;\n _aether.logStatementStart([{ofs: 454, row: 8, col: 19}, {ofs: 469, row: 8, col: 34}]); tmp40 = tmp41[tmp42]; _aether.logStatement([{ofs: 454, row: 8, col: 19}, {ofs: 469, row: 8, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp40);\n } else {\n ;\n }\n }\n tmp18 = i;\n tmp19 = 1;\n i = tmp18 + tmp19;\n tmp12 = i;\n tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp17 = 'enemies';\n _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}]); tmp14 = tmp16[tmp17]; _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}], _aether._userInfo, false);\n tmp15 = 'length';\n _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}]); tmp13 = tmp14[tmp15]; _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}]); tmp5 = tmp12 < tmp13; _aether.logStatement([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 222, row: 4, col: 0}, {ofs: 489, row: 11, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 222, row: 4, col: 0}, {ofs: 488, row: 11, col: 1}]); tmp2[tmp3] = tmp4; _aether.logStatement([{ofs: 222, row: 4, col: 0}, {ofs: 488, row: 11, col: 1}], _aether._userInfo, false);\n tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp46 = 'getMyHero';\n _aether.logStatementStart([{ofs: 491, row: 13, col: 0}, {ofs: 757, row: 20, col: 2}]); tmp47 = function () {\n var i, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 571, row: 15, col: 9}, {ofs: 580, row: 15, col: 18}]); i = 0; _aether.logStatement([{ofs: 571, row: 15, col: 9}, {ofs: 580, row: 15, col: 18}], _aether._userInfo, false);\n tmp49 = i;\n tmp53 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp54 = 'friends';\n _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}]); tmp51 = tmp53[tmp54]; _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}], _aether._userInfo, false);\n tmp52 = 'length';\n _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}]); tmp50 = tmp51[tmp52]; _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}]); tmp48 = tmp49 < tmp50; _aether.logStatement([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n tmp63: {\n while (tmp48) {\n tmp64: {\n tmp73 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp74 = 'friends';\n _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 638, row: 16, col: 24}]); tmp71 = tmp73[tmp74]; _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 638, row: 16, col: 24}], _aether._userInfo, false);\n tmp72 = i;\n _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 641, row: 16, col: 27}]); tmp69 = tmp71[tmp72]; _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 641, row: 16, col: 27}], _aether._userInfo, false);\n tmp70 = 'type';\n _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 646, row: 16, col: 32}]); tmp67 = tmp69[tmp70]; _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 646, row: 16, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 651, row: 16, col: 37}, {ofs: 659, row: 16, col: 45}]); tmp68 = 'knight'; _aether.logStatement([{ofs: 651, row: 16, col: 37}, {ofs: 659, row: 16, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 659, row: 16, col: 45}]); tmp66 = tmp67 === tmp68; _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 659, row: 16, col: 45}], _aether._userInfo, false);\n if (tmp66) {\n _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 699, row: 16, col: 85}]); tmp65 = tmp66; _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n } else {\n tmp81 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp82 = 'friends';\n _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 675, row: 16, col: 61}]); tmp79 = tmp81[tmp82]; _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 675, row: 16, col: 61}], _aether._userInfo, false);\n tmp80 = i;\n _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 678, row: 16, col: 64}]); tmp77 = tmp79[tmp80]; _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 678, row: 16, col: 64}], _aether._userInfo, false);\n tmp78 = 'type';\n _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 683, row: 16, col: 69}]); tmp75 = tmp77[tmp78]; _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 683, row: 16, col: 69}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 688, row: 16, col: 74}, {ofs: 699, row: 16, col: 85}]); tmp76 = 'librarian'; _aether.logStatement([{ofs: 688, row: 16, col: 74}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 699, row: 16, col: 85}]); tmp65 = tmp75 === tmp76; _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n }\n if (tmp65) {\n tmp86 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp87 = 'friends';\n _aether.logStatementStart([{ofs: 722, row: 17, col: 19}, {ofs: 734, row: 17, col: 31}]); tmp84 = tmp86[tmp87]; _aether.logStatement([{ofs: 722, row: 17, col: 19}, {ofs: 734, row: 17, col: 31}], _aether._userInfo, false);\n tmp85 = i;\n _aether.logStatementStart([{ofs: 722, row: 17, col: 19}, {ofs: 737, row: 17, col: 34}]); tmp83 = tmp84[tmp85]; _aether.logStatement([{ofs: 722, row: 17, col: 19}, {ofs: 737, row: 17, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp83);\n } else {\n ;\n }\n }\n tmp61 = i;\n tmp62 = 1;\n i = tmp61 + tmp62;\n tmp55 = i;\n tmp59 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp60 = 'friends';\n _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}]); tmp57 = tmp59[tmp60]; _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}], _aether._userInfo, false);\n tmp58 = 'length';\n _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}]); tmp56 = tmp57[tmp58]; _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}]); tmp48 = tmp55 < tmp56; _aether.logStatement([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 491, row: 13, col: 0}, {ofs: 757, row: 20, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 491, row: 13, col: 0}, {ofs: 756, row: 20, col: 1}]); tmp45[tmp46] = tmp47; _aether.logStatement([{ofs: 491, row: 13, col: 0}, {ofs: 756, row: 20, col: 1}], _aether._userInfo, false);\n tmp88 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp89 = 'doesEnemyHaveMix';\n _aether.logStatementStart([{ofs: 759, row: 22, col: 0}, {ofs: 1200, row: 39, col: 2}]); tmp90 = function () {\n var ranged, melee, i, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 849, row: 24, col: 4}, {ofs: 864, row: 24, col: 19}]); ranged = 0; _aether.logStatement([{ofs: 849, row: 24, col: 4}, {ofs: 864, row: 24, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 869, row: 25, col: 4}, {ofs: 883, row: 25, col: 18}]); melee = 0; _aether.logStatement([{ofs: 869, row: 25, col: 4}, {ofs: 883, row: 25, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 892, row: 26, col: 8}, {ofs: 901, row: 26, col: 17}]); i = 2; _aether.logStatement([{ofs: 892, row: 26, col: 8}, {ofs: 901, row: 26, col: 17}], _aether._userInfo, false);\n tmp92 = i;\n tmp96 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp97 = 'enemies';\n _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}]); tmp94 = tmp96[tmp97]; _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}], _aether._userInfo, false);\n tmp95 = 'length';\n _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}]); tmp93 = tmp94[tmp95]; _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}]); tmp91 = tmp92 < tmp93; _aether.logStatement([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n tmp106: {\n while (tmp91) {\n tmp107: {\n tmp115 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp116 = 'enemies';\n _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 958, row: 27, col: 23}]); tmp113 = tmp115[tmp116]; _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 958, row: 27, col: 23}], _aether._userInfo, false);\n tmp114 = i;\n _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 961, row: 27, col: 26}]); tmp111 = tmp113[tmp114]; _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 961, row: 27, col: 26}], _aether._userInfo, false);\n tmp112 = 'type';\n _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 966, row: 27, col: 31}]); tmp109 = tmp111[tmp112]; _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 966, row: 27, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 971, row: 27, col: 36}, {ofs: 980, row: 27, col: 45}]); tmp110 = 'thrower'; _aether.logStatement([{ofs: 971, row: 27, col: 36}, {ofs: 980, row: 27, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 980, row: 27, col: 45}]); tmp108 = tmp109 === tmp110; _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 980, row: 27, col: 45}], _aether._userInfo, false);\n if (tmp108) {\n _aether.logStatementStart([{ofs: 996, row: 28, col: 12}, {ofs: 1008, row: 28, col: 24}]); tmp117 = 1; _aether.logStatement([{ofs: 996, row: 28, col: 12}, {ofs: 1008, row: 28, col: 24}], _aether._userInfo, false);\n tmp118 = ranged;\n tmp119 = tmp117;\n ranged = tmp118 + tmp119;\n } else {\n tmp127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp128 = 'enemies';\n _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1047, row: 30, col: 28}]); tmp125 = tmp127[tmp128]; _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1047, row: 30, col: 28}], _aether._userInfo, false);\n tmp126 = i;\n _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1050, row: 30, col: 31}]); tmp123 = tmp125[tmp126]; _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1050, row: 30, col: 31}], _aether._userInfo, false);\n tmp124 = 'type';\n _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1055, row: 30, col: 36}]); tmp121 = tmp123[tmp124]; _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1055, row: 30, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1060, row: 30, col: 41}, {ofs: 1070, row: 30, col: 51}]); tmp122 = 'munchkin'; _aether.logStatement([{ofs: 1060, row: 30, col: 41}, {ofs: 1070, row: 30, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1070, row: 30, col: 51}]); tmp120 = tmp121 === tmp122; _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1070, row: 30, col: 51}], _aether._userInfo, false);\n if (tmp120) {\n _aether.logStatementStart([{ofs: 1086, row: 31, col: 12}, {ofs: 1097, row: 31, col: 23}]); tmp129 = 1; _aether.logStatement([{ofs: 1086, row: 31, col: 12}, {ofs: 1097, row: 31, col: 23}], _aether._userInfo, false);\n tmp130 = melee;\n tmp131 = tmp129;\n melee = tmp130 + tmp131;\n } else {\n ;\n }\n }\n }\n tmp104 = i;\n tmp105 = 1;\n i = tmp104 + tmp105;\n tmp98 = i;\n tmp102 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp103 = 'enemies';\n _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}]); tmp100 = tmp102[tmp103]; _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}], _aether._userInfo, false);\n tmp101 = 'length';\n _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}]); tmp99 = tmp100[tmp101]; _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}]); tmp91 = tmp98 < tmp99; _aether.logStatement([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n }\n }\n tmp134 = ranged;\n _aether.logStatementStart([{ofs: 1130, row: 34, col: 16}, {ofs: 1131, row: 34, col: 17}]); tmp135 = 0; _aether.logStatement([{ofs: 1130, row: 34, col: 16}, {ofs: 1131, row: 34, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1121, row: 34, col: 7}, {ofs: 1131, row: 34, col: 17}]); tmp133 = tmp134 > tmp135; _aether.logStatement([{ofs: 1121, row: 34, col: 7}, {ofs: 1131, row: 34, col: 17}], _aether._userInfo, false);\n if (tmp133) {\n tmp136 = melee;\n _aether.logStatementStart([{ofs: 1143, row: 34, col: 29}, {ofs: 1144, row: 34, col: 30}]); tmp137 = 0; _aether.logStatement([{ofs: 1143, row: 34, col: 29}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1135, row: 34, col: 21}, {ofs: 1144, row: 34, col: 30}]); tmp132 = tmp136 > tmp137; _aether.logStatement([{ofs: 1135, row: 34, col: 21}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1121, row: 34, col: 7}, {ofs: 1144, row: 34, col: 30}]); tmp132 = tmp133; _aether.logStatement([{ofs: 1121, row: 34, col: 7}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n }\n if (tmp132) {\n _aether.logStatementStart([{ofs: 1163, row: 35, col: 15}, {ofs: 1167, row: 35, col: 19}]); tmp138 = true; _aether.logStatement([{ofs: 1163, row: 35, col: 15}, {ofs: 1167, row: 35, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp138);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 1191, row: 38, col: 11}, {ofs: 1196, row: 38, col: 16}]); tmp139 = false; _aether.logStatement([{ofs: 1191, row: 38, col: 11}, {ofs: 1196, row: 38, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp139);\n }; _aether.logStatement([{ofs: 759, row: 22, col: 0}, {ofs: 1200, row: 39, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 759, row: 22, col: 0}, {ofs: 1199, row: 39, col: 1}]); tmp88[tmp89] = tmp90; _aether.logStatement([{ofs: 759, row: 22, col: 0}, {ofs: 1199, row: 39, col: 1}], _aether._userInfo, false);\n tmp140 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp141 = 'enemies';\n tmp143 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp144 = 'getEnemies';\n _aether.logStatementStart([{ofs: 1202, row: 41, col: 0}, {ofs: 1235, row: 41, col: 33}]); tmp142 = _aether.createAPIClone(_aether, tmp143[tmp144]()); _aether.logStatement([{ofs: 1202, row: 41, col: 0}, {ofs: 1235, row: 41, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1202, row: 41, col: 0}, {ofs: 1234, row: 41, col: 32}]); tmp140[tmp141] = tmp142; _aether.logStatement([{ofs: 1202, row: 41, col: 0}, {ofs: 1234, row: 41, col: 32}], _aether._userInfo, false);\n tmp145 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp146 = 'friends';\n tmp148 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp149 = 'getFriends';\n _aether.logStatementStart([{ofs: 1236, row: 42, col: 0}, {ofs: 1269, row: 42, col: 33}]); tmp147 = _aether.createAPIClone(_aether, tmp148[tmp149]()); _aether.logStatement([{ofs: 1236, row: 42, col: 0}, {ofs: 1269, row: 42, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1236, row: 42, col: 0}, {ofs: 1268, row: 42, col: 32}]); tmp145[tmp146] = tmp147; _aether.logStatement([{ofs: 1236, row: 42, col: 0}, {ofs: 1268, row: 42, col: 32}], _aether._userInfo, false);\n tmp150 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp151 = 'myHero';\n tmp153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp154 = 'getMyHero';\n _aether.logStatementStart([{ofs: 1270, row: 43, col: 0}, {ofs: 1301, row: 43, col: 31}]); tmp152 = _aether.createAPIClone(_aether, tmp153[tmp154]()); _aether.logStatement([{ofs: 1270, row: 43, col: 0}, {ofs: 1301, row: 43, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1270, row: 43, col: 0}, {ofs: 1300, row: 43, col: 30}]); tmp150[tmp151] = tmp152; _aether.logStatement([{ofs: 1270, row: 43, col: 0}, {ofs: 1300, row: 43, col: 30}], _aether._userInfo, false);\n tmp155 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp156 = 'enemyHero';\n tmp158 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp159 = 'getEnemyHero';\n _aether.logStatementStart([{ofs: 1302, row: 44, col: 0}, {ofs: 1339, row: 44, col: 37}]); tmp157 = _aether.createAPIClone(_aether, tmp158[tmp159]()); _aether.logStatement([{ofs: 1302, row: 44, col: 0}, {ofs: 1339, row: 44, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1302, row: 44, col: 0}, {ofs: 1338, row: 44, col: 36}]); tmp155[tmp156] = tmp157; _aether.logStatement([{ofs: 1302, row: 44, col: 0}, {ofs: 1338, row: 44, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1400, row: 47, col: 0}, {ofs: 1416, row: 47, col: 16}]); hero = 'tharin'; _aether.logStatement([{ofs: 1400, row: 47, col: 0}, {ofs: 1416, row: 47, col: 16}], _aether._userInfo, false);\n tmp161 = hero;\n if (tmp161) {\n tmp163 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp164 = 'builtHero';\n _aether.logStatementStart([{ofs: 1526, row: 50, col: 13}, {ofs: 1540, row: 50, col: 27}]); tmp162 = tmp163[tmp164]; _aether.logStatement([{ofs: 1526, row: 50, col: 13}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1525, row: 50, col: 12}, {ofs: 1540, row: 50, col: 27}]); tmp160 = !tmp162; _aether.logStatement([{ofs: 1525, row: 50, col: 12}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1517, row: 50, col: 4}, {ofs: 1540, row: 50, col: 27}]); tmp160 = tmp161; _aether.logStatement([{ofs: 1517, row: 50, col: 4}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n }\n if (tmp160) {\n tmp165 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp166 = 'builtHero';\n tmp168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp169 = 'build';\n tmp170 = hero;\n _aether.logStatementStart([{ofs: 1548, row: 51, col: 4}, {ofs: 1582, row: 51, col: 38}]); tmp167 = _aether.createAPIClone(_aether, tmp168[tmp169](_aether.restoreAPIClone(_aether, tmp170))); _aether.logStatement([{ofs: 1548, row: 51, col: 4}, {ofs: 1582, row: 51, col: 38}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1548, row: 51, col: 4}, {ofs: 1581, row: 51, col: 37}]); tmp165[tmp166] = tmp167; _aether.logStatement([{ofs: 1548, row: 51, col: 4}, {ofs: 1581, row: 51, col: 37}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp174 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp175 = 'myHero';\n _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2504, row: 76, col: 14}]); tmp173 = tmp174[tmp175]; _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2504, row: 76, col: 14}], _aether._userInfo, false);\n if (tmp173) {\n tmp178 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp179 = 'myHero';\n _aether.logStatementStart([{ofs: 2508, row: 76, col: 18}, {ofs: 2519, row: 76, col: 29}]); tmp176 = tmp178[tmp179]; _aether.logStatement([{ofs: 2508, row: 76, col: 18}, {ofs: 2519, row: 76, col: 29}], _aether._userInfo, false);\n tmp177 = 'notHeroFirst';\n _aether.logStatementStart([{ofs: 2508, row: 76, col: 18}, {ofs: 2532, row: 76, col: 42}]); tmp172 = tmp176[tmp177]; _aether.logStatement([{ofs: 2508, row: 76, col: 18}, {ofs: 2532, row: 76, col: 42}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2532, row: 76, col: 42}]); tmp172 = tmp173; _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2532, row: 76, col: 42}], _aether._userInfo, false);\n }\n if (tmp172) {\n tmp182 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp183 = 'myHero';\n _aether.logStatementStart([{ofs: 2536, row: 76, col: 46}, {ofs: 2547, row: 76, col: 57}]); tmp180 = tmp182[tmp183]; _aether.logStatement([{ofs: 2536, row: 76, col: 46}, {ofs: 2547, row: 76, col: 57}], _aether._userInfo, false);\n tmp181 = 'notHeroSecond';\n _aether.logStatementStart([{ofs: 2536, row: 76, col: 46}, {ofs: 2561, row: 76, col: 71}]); tmp171 = tmp180[tmp181]; _aether.logStatement([{ofs: 2536, row: 76, col: 46}, {ofs: 2561, row: 76, col: 71}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2561, row: 76, col: 71}]); tmp171 = tmp172; _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2561, row: 76, col: 71}], _aether._userInfo, false);\n }\n if (tmp171) {\n tmp184 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp185 = 'build';\n _aether.logStatementStart([{ofs: 2580, row: 77, col: 15}, {ofs: 2588, row: 77, col: 23}]); tmp186 = 'archer'; _aether.logStatement([{ofs: 2580, row: 77, col: 15}, {ofs: 2588, row: 77, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2569, row: 77, col: 4}, {ofs: 2589, row: 77, col: 24}]); tmp187 = _aether.createAPIClone(_aether, tmp184[tmp185](_aether.restoreAPIClone(_aether, tmp186))); _aether.logStatement([{ofs: 2569, row: 77, col: 4}, {ofs: 2589, row: 77, col: 24}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n tmp192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp193 = 'myHero';\n _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2764, row: 83, col: 19}]); tmp191 = tmp192[tmp193]; _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2764, row: 83, col: 19}], _aether._userInfo, false);\n if (tmp191) {\n tmp196 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp197 = 'myHero';\n _aether.logStatementStart([{ofs: 2768, row: 83, col: 23}, {ofs: 2779, row: 83, col: 34}]); tmp194 = tmp196[tmp197]; _aether.logStatement([{ofs: 2768, row: 83, col: 23}, {ofs: 2779, row: 83, col: 34}], _aether._userInfo, false);\n tmp195 = 'notHeroFirst';\n _aether.logStatementStart([{ofs: 2768, row: 83, col: 23}, {ofs: 2792, row: 83, col: 47}]); tmp190 = tmp194[tmp195]; _aether.logStatement([{ofs: 2768, row: 83, col: 23}, {ofs: 2792, row: 83, col: 47}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2792, row: 83, col: 47}]); tmp190 = tmp191; _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2792, row: 83, col: 47}], _aether._userInfo, false);\n }\n if (tmp190) {\n tmp200 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp201 = 'myHero';\n _aether.logStatementStart([{ofs: 2796, row: 83, col: 51}, {ofs: 2807, row: 83, col: 62}]); tmp198 = tmp200[tmp201]; _aether.logStatement([{ofs: 2796, row: 83, col: 51}, {ofs: 2807, row: 83, col: 62}], _aether._userInfo, false);\n tmp199 = 'terrifyCooldown';\n _aether.logStatementStart([{ofs: 2796, row: 83, col: 51}, {ofs: 2823, row: 83, col: 78}]); tmp189 = tmp198[tmp199]; _aether.logStatement([{ofs: 2796, row: 83, col: 51}, {ofs: 2823, row: 83, col: 78}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2823, row: 83, col: 78}]); tmp189 = tmp190; _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2823, row: 83, col: 78}], _aether._userInfo, false);\n }\n if (tmp189) {\n tmp208 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp209 = 'myHero';\n _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2839, row: 83, col: 94}]); tmp206 = tmp208[tmp209]; _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2839, row: 83, col: 94}], _aether._userInfo, false);\n tmp207 = 'terrifyUnitCount';\n _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2856, row: 83, col: 111}]); tmp204 = tmp206[tmp207]; _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2856, row: 83, col: 111}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2860, row: 83, col: 115}, {ofs: 2861, row: 83, col: 116}]); tmp205 = 5; _aether.logStatement([{ofs: 2860, row: 83, col: 115}, {ofs: 2861, row: 83, col: 116}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2861, row: 83, col: 116}]); tmp203 = tmp204 != tmp205; _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2861, row: 83, col: 116}], _aether._userInfo, false);\n if (tmp203) {\n tmp214 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp215 = 'myHero';\n _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2876, row: 83, col: 131}]); tmp212 = tmp214[tmp215]; _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2876, row: 83, col: 131}], _aether._userInfo, false);\n tmp213 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2891, row: 83, col: 146}]); tmp210 = tmp212[tmp213]; _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2891, row: 83, col: 146}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2895, row: 83, col: 150}, {ofs: 2896, row: 83, col: 151}]); tmp211 = 4; _aether.logStatement([{ofs: 2895, row: 83, col: 150}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2896, row: 83, col: 151}]); tmp202 = tmp210 != tmp211; _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2896, row: 83, col: 151}]); tmp202 = tmp203; _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n }\n if (tmp202) {\n tmp220 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp221 = 'myHero';\n _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2911, row: 83, col: 166}]); tmp218 = tmp220[tmp221]; _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2911, row: 83, col: 166}], _aether._userInfo, false);\n tmp219 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2926, row: 83, col: 181}]); tmp216 = tmp218[tmp219]; _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2926, row: 83, col: 181}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2930, row: 83, col: 185}, {ofs: 2931, row: 83, col: 186}]); tmp217 = 1; _aether.logStatement([{ofs: 2930, row: 83, col: 185}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2931, row: 83, col: 186}]); tmp188 = tmp216 != tmp217; _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2931, row: 83, col: 186}]); tmp188 = tmp202; _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2932, row: 83, col: 187}]); tmp188 = tmp189; _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2932, row: 83, col: 187}], _aether._userInfo, false);\n }\n if (tmp188) {\n tmp222 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp223 = 'noArcher';\n _aether.logStatementStart([{ofs: 2940, row: 84, col: 4}, {ofs: 2961, row: 84, col: 25}]); tmp224 = true; _aether.logStatement([{ofs: 2940, row: 84, col: 4}, {ofs: 2961, row: 84, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2940, row: 84, col: 4}, {ofs: 2960, row: 84, col: 24}]); tmp222[tmp223] = tmp224; _aether.logStatement([{ofs: 2940, row: 84, col: 4}, {ofs: 2960, row: 84, col: 24}], _aether._userInfo, false);\n tmp225 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp226 = 'build';\n _aether.logStatementStart([{ofs: 2977, row: 85, col: 15}, {ofs: 2986, row: 85, col: 24}]); tmp227 = 'soldier'; _aether.logStatement([{ofs: 2977, row: 85, col: 15}, {ofs: 2986, row: 85, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2966, row: 85, col: 4}, {ofs: 2987, row: 85, col: 25}]); tmp228 = _aether.createAPIClone(_aether, tmp225[tmp226](_aether.restoreAPIClone(_aether, tmp227))); _aether.logStatement([{ofs: 2966, row: 85, col: 4}, {ofs: 2987, row: 85, col: 25}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n }\n tmp231 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp232 = 'myHero';\n _aether.logStatementStart([{ofs: 3203, row: 94, col: 7}, {ofs: 3214, row: 94, col: 18}]); tmp230 = tmp231[tmp232]; _aether.logStatement([{ofs: 3203, row: 94, col: 7}, {ofs: 3214, row: 94, col: 18}], _aether._userInfo, false);\n if (tmp230) {\n tmp235 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp236 = 'myHero';\n _aether.logStatementStart([{ofs: 3218, row: 94, col: 22}, {ofs: 3229, row: 94, col: 33}]); tmp233 = tmp235[tmp236]; _aether.logStatement([{ofs: 3218, row: 94, col: 22}, {ofs: 3229, row: 94, col: 33}], _aether._userInfo, false);\n tmp234 = 'midJump';\n _aether.logStatementStart([{ofs: 3218, row: 94, col: 22}, {ofs: 3237, row: 94, col: 41}]); tmp229 = tmp233[tmp234]; _aether.logStatement([{ofs: 3218, row: 94, col: 22}, {ofs: 3237, row: 94, col: 41}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3203, row: 94, col: 7}, {ofs: 3237, row: 94, col: 41}]); tmp229 = tmp230; _aether.logStatement([{ofs: 3203, row: 94, col: 7}, {ofs: 3237, row: 94, col: 41}], _aether._userInfo, false);\n }\n if (tmp229) {\n tmp237 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp238 = 'build';\n _aether.logStatementStart([{ofs: 3260, row: 95, col: 19}, {ofs: 3269, row: 95, col: 28}]); tmp239 = 'soldier'; _aether.logStatement([{ofs: 3260, row: 95, col: 19}, {ofs: 3269, row: 95, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3249, row: 95, col: 8}, {ofs: 3270, row: 95, col: 29}]); tmp240 = _aether.createAPIClone(_aether, tmp237[tmp238](_aether.restoreAPIClone(_aether, tmp239))); _aether.logStatement([{ofs: 3249, row: 95, col: 8}, {ofs: 3270, row: 95, col: 29}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp246 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp247 = 'myHero';\n _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3313, row: 99, col: 18}]); tmp245 = tmp246[tmp247]; _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3313, row: 99, col: 18}], _aether._userInfo, false);\n if (tmp245) {\n tmp250 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp251 = 'myHero';\n _aether.logStatementStart([{ofs: 3317, row: 99, col: 22}, {ofs: 3328, row: 99, col: 33}]); tmp248 = tmp250[tmp251]; _aether.logStatement([{ofs: 3317, row: 99, col: 22}, {ofs: 3328, row: 99, col: 33}], _aether._userInfo, false);\n tmp249 = 'earlyJump';\n _aether.logStatementStart([{ofs: 3317, row: 99, col: 22}, {ofs: 3338, row: 99, col: 43}]); tmp244 = tmp248[tmp249]; _aether.logStatement([{ofs: 3317, row: 99, col: 22}, {ofs: 3338, row: 99, col: 43}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3338, row: 99, col: 43}]); tmp244 = tmp245; _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3338, row: 99, col: 43}], _aether._userInfo, false);\n }\n if (tmp244) {\n tmp254 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp255 = 'myHero';\n _aether.logStatementStart([{ofs: 3342, row: 99, col: 47}, {ofs: 3353, row: 99, col: 58}]); tmp252 = tmp254[tmp255]; _aether.logStatement([{ofs: 3342, row: 99, col: 47}, {ofs: 3353, row: 99, col: 58}], _aether._userInfo, false);\n tmp253 = 'terrifyCooldown';\n _aether.logStatementStart([{ofs: 3342, row: 99, col: 47}, {ofs: 3369, row: 99, col: 74}]); tmp243 = tmp252[tmp253]; _aether.logStatement([{ofs: 3342, row: 99, col: 47}, {ofs: 3369, row: 99, col: 74}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3369, row: 99, col: 74}]); tmp243 = tmp244; _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3369, row: 99, col: 74}], _aether._userInfo, false);\n }\n if (tmp243) {\n tmp260 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp261 = 'myHero';\n _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3384, row: 99, col: 89}]); tmp258 = tmp260[tmp261]; _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3384, row: 99, col: 89}], _aether._userInfo, false);\n tmp259 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3399, row: 99, col: 104}]); tmp256 = tmp258[tmp259]; _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3399, row: 99, col: 104}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3404, row: 99, col: 109}, {ofs: 3405, row: 99, col: 110}]); tmp257 = 4; _aether.logStatement([{ofs: 3404, row: 99, col: 109}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3405, row: 99, col: 110}]); tmp242 = tmp256 === tmp257; _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3405, row: 99, col: 110}]); tmp242 = tmp243; _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n }\n if (tmp242) {\n tmp266 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp267 = 'myHero';\n _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3420, row: 99, col: 125}]); tmp264 = tmp266[tmp267]; _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3420, row: 99, col: 125}], _aether._userInfo, false);\n tmp265 = 'terrifyUnitCount';\n _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3437, row: 99, col: 142}]); tmp262 = tmp264[tmp265]; _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3437, row: 99, col: 142}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3442, row: 99, col: 147}, {ofs: 3443, row: 99, col: 148}]); tmp263 = 3; _aether.logStatement([{ofs: 3442, row: 99, col: 147}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3443, row: 99, col: 148}]); tmp241 = tmp262 === tmp263; _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3443, row: 99, col: 148}]); tmp241 = tmp242; _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n }\n if (tmp241) {\n tmp268 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp269 = 'build';\n _aether.logStatementStart([{ofs: 3466, row: 100, col: 19}, {ofs: 3475, row: 100, col: 28}]); tmp270 = 'soldier'; _aether.logStatement([{ofs: 3466, row: 100, col: 19}, {ofs: 3475, row: 100, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3455, row: 100, col: 8}, {ofs: 3476, row: 100, col: 29}]); tmp271 = _aether.createAPIClone(_aether, tmp268[tmp269](_aether.restoreAPIClone(_aether, tmp270))); _aether.logStatement([{ofs: 3455, row: 100, col: 8}, {ofs: 3476, row: 100, col: 29}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp280 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp281 = 'noArcher';\n _aether.logStatementStart([{ofs: 3509, row: 104, col: 8}, {ofs: 3522, row: 104, col: 21}]); tmp279 = tmp280[tmp281]; _aether.logStatement([{ofs: 3509, row: 104, col: 8}, {ofs: 3522, row: 104, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3522, row: 104, col: 21}]); tmp278 = !tmp279; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3522, row: 104, col: 21}], _aether._userInfo, false);\n if (tmp278) {\n tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp283 = 'myHero';\n _aether.logStatementStart([{ofs: 3526, row: 104, col: 25}, {ofs: 3537, row: 104, col: 36}]); tmp277 = tmp282[tmp283]; _aether.logStatement([{ofs: 3526, row: 104, col: 25}, {ofs: 3537, row: 104, col: 36}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3537, row: 104, col: 36}]); tmp277 = tmp278; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3537, row: 104, col: 36}], _aether._userInfo, false);\n }\n if (tmp277) {\n tmp286 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp287 = 'myHero';\n _aether.logStatementStart([{ofs: 3541, row: 104, col: 40}, {ofs: 3552, row: 104, col: 51}]); tmp284 = tmp286[tmp287]; _aether.logStatement([{ofs: 3541, row: 104, col: 40}, {ofs: 3552, row: 104, col: 51}], _aether._userInfo, false);\n tmp285 = 'terrifyCooldown';\n _aether.logStatementStart([{ofs: 3541, row: 104, col: 40}, {ofs: 3568, row: 104, col: 67}]); tmp276 = tmp284[tmp285]; _aether.logStatement([{ofs: 3541, row: 104, col: 40}, {ofs: 3568, row: 104, col: 67}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3568, row: 104, col: 67}]); tmp276 = tmp277; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3568, row: 104, col: 67}], _aether._userInfo, false);\n }\n if (tmp276) {\n tmp290 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp291 = 'myHero';\n _aether.logStatementStart([{ofs: 3572, row: 104, col: 71}, {ofs: 3583, row: 104, col: 82}]); tmp288 = tmp290[tmp291]; _aether.logStatement([{ofs: 3572, row: 104, col: 71}, {ofs: 3583, row: 104, col: 82}], _aether._userInfo, false);\n tmp289 = 'earlyJump';\n _aether.logStatementStart([{ofs: 3572, row: 104, col: 71}, {ofs: 3593, row: 104, col: 92}]); tmp275 = tmp288[tmp289]; _aether.logStatement([{ofs: 3572, row: 104, col: 71}, {ofs: 3593, row: 104, col: 92}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3593, row: 104, col: 92}]); tmp275 = tmp276; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3593, row: 104, col: 92}], _aether._userInfo, false);\n }\n if (tmp275) {\n tmp296 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp297 = 'enemies';\n _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3609, row: 104, col: 108}]); tmp294 = tmp296[tmp297]; _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3609, row: 104, col: 108}], _aether._userInfo, false);\n tmp295 = 'length';\n _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3616, row: 104, col: 115}]); tmp292 = tmp294[tmp295]; _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3616, row: 104, col: 115}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3621, row: 104, col: 120}, {ofs: 3622, row: 104, col: 121}]); tmp293 = 4; _aether.logStatement([{ofs: 3621, row: 104, col: 120}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3622, row: 104, col: 121}]); tmp274 = tmp292 === tmp293; _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3622, row: 104, col: 121}]); tmp274 = tmp275; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n }\n if (tmp274) {\n tmp302 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp303 = 'myHero';\n _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3637, row: 104, col: 136}]); tmp300 = tmp302[tmp303]; _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3637, row: 104, col: 136}], _aether._userInfo, false);\n tmp301 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3652, row: 104, col: 151}]); tmp298 = tmp300[tmp301]; _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3652, row: 104, col: 151}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3657, row: 104, col: 156}, {ofs: 3658, row: 104, col: 157}]); tmp299 = 1; _aether.logStatement([{ofs: 3657, row: 104, col: 156}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3658, row: 104, col: 157}]); tmp273 = tmp298 === tmp299; _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3658, row: 104, col: 157}]); tmp273 = tmp274; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n }\n if (tmp273) {\n tmp304 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp305 = 'doesEnemyHaveMix';\n _aether.logStatementStart([{ofs: 3662, row: 104, col: 161}, {ofs: 3685, row: 104, col: 184}]); tmp272 = _aether.createAPIClone(_aether, tmp304[tmp305]()); _aether.logStatement([{ofs: 3662, row: 104, col: 161}, {ofs: 3685, row: 104, col: 184}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3685, row: 104, col: 184}]); tmp272 = tmp273; _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3685, row: 104, col: 184}], _aether._userInfo, false);\n }\n if (tmp272) {\n tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp307 = 'noArcher';\n _aether.logStatementStart([{ofs: 3697, row: 105, col: 8}, {ofs: 3718, row: 105, col: 29}]); tmp308 = true; _aether.logStatement([{ofs: 3697, row: 105, col: 8}, {ofs: 3718, row: 105, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3697, row: 105, col: 8}, {ofs: 3717, row: 105, col: 28}]); tmp306[tmp307] = tmp308; _aether.logStatement([{ofs: 3697, row: 105, col: 8}, {ofs: 3717, row: 105, col: 28}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp313 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp314 = 'myHero';\n _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3744, row: 108, col: 18}]); tmp312 = tmp313[tmp314]; _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3744, row: 108, col: 18}], _aether._userInfo, false);\n if (tmp312) {\n tmp317 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp318 = 'myHero';\n _aether.logStatementStart([{ofs: 3748, row: 108, col: 22}, {ofs: 3759, row: 108, col: 33}]); tmp315 = tmp317[tmp318]; _aether.logStatement([{ofs: 3748, row: 108, col: 22}, {ofs: 3759, row: 108, col: 33}], _aether._userInfo, false);\n tmp316 = 'terrifyCooldown';\n _aether.logStatementStart([{ofs: 3748, row: 108, col: 22}, {ofs: 3775, row: 108, col: 49}]); tmp311 = tmp315[tmp316]; _aether.logStatement([{ofs: 3748, row: 108, col: 22}, {ofs: 3775, row: 108, col: 49}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3775, row: 108, col: 49}]); tmp311 = tmp312; _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3775, row: 108, col: 49}], _aether._userInfo, false);\n }\n if (tmp311) {\n tmp323 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp324 = 'myHero';\n _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3790, row: 108, col: 64}]); tmp321 = tmp323[tmp324]; _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3790, row: 108, col: 64}], _aether._userInfo, false);\n tmp322 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3805, row: 108, col: 79}]); tmp319 = tmp321[tmp322]; _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3805, row: 108, col: 79}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3809, row: 108, col: 83}, {ofs: 3810, row: 108, col: 84}]); tmp320 = 2; _aether.logStatement([{ofs: 3809, row: 108, col: 83}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3810, row: 108, col: 84}]); tmp310 = tmp319 != tmp320; _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3810, row: 108, col: 84}]); tmp310 = tmp311; _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n }\n if (tmp310) {\n tmp326 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp327 = 'noArcher';\n _aether.logStatementStart([{ofs: 3815, row: 108, col: 89}, {ofs: 3828, row: 108, col: 102}]); tmp325 = tmp326[tmp327]; _aether.logStatement([{ofs: 3815, row: 108, col: 89}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3814, row: 108, col: 88}, {ofs: 3828, row: 108, col: 102}]); tmp309 = !tmp325; _aether.logStatement([{ofs: 3814, row: 108, col: 88}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3828, row: 108, col: 102}]); tmp309 = tmp310; _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n }\n if (tmp309) {\n tmp328 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp329 = 'build';\n _aether.logStatementStart([{ofs: 3851, row: 109, col: 19}, {ofs: 3859, row: 109, col: 27}]); tmp330 = 'archer'; _aether.logStatement([{ofs: 3851, row: 109, col: 19}, {ofs: 3859, row: 109, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3840, row: 109, col: 8}, {ofs: 3860, row: 109, col: 28}]); tmp331 = _aether.createAPIClone(_aether, tmp328[tmp329](_aether.restoreAPIClone(_aether, tmp330))); _aether.logStatement([{ofs: 3840, row: 109, col: 8}, {ofs: 3860, row: 109, col: 28}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp337 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp338 = 'myHero';\n _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3904, row: 114, col: 18}]); tmp336 = tmp337[tmp338]; _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3904, row: 114, col: 18}], _aether._userInfo, false);\n if (tmp336) {\n tmp341 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp342 = 'myHero';\n _aether.logStatementStart([{ofs: 3908, row: 114, col: 22}, {ofs: 3919, row: 114, col: 33}]); tmp339 = tmp341[tmp342]; _aether.logStatement([{ofs: 3908, row: 114, col: 22}, {ofs: 3919, row: 114, col: 33}], _aether._userInfo, false);\n tmp340 = 'earlyJump';\n _aether.logStatementStart([{ofs: 3908, row: 114, col: 22}, {ofs: 3929, row: 114, col: 43}]); tmp335 = tmp339[tmp340]; _aether.logStatement([{ofs: 3908, row: 114, col: 22}, {ofs: 3929, row: 114, col: 43}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3929, row: 114, col: 43}]); tmp335 = tmp336; _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3929, row: 114, col: 43}], _aether._userInfo, false);\n }\n if (tmp335) {\n tmp345 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp346 = 'now';\n _aether.logStatementStart([{ofs: 3933, row: 114, col: 47}, {ofs: 3943, row: 114, col: 57}]); tmp343 = _aether.createAPIClone(_aether, tmp345[tmp346]()); _aether.logStatement([{ofs: 3933, row: 114, col: 47}, {ofs: 3943, row: 114, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3947, row: 114, col: 61}, {ofs: 3948, row: 114, col: 62}]); tmp344 = 5; _aether.logStatement([{ofs: 3947, row: 114, col: 61}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3933, row: 114, col: 47}, {ofs: 3948, row: 114, col: 62}]); tmp334 = tmp343 >= tmp344; _aether.logStatement([{ofs: 3933, row: 114, col: 47}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3948, row: 114, col: 62}]); tmp334 = tmp335; _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n }\n if (tmp334) {\n tmp351 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp352 = 'myHero';\n _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3963, row: 114, col: 77}]); tmp349 = tmp351[tmp352]; _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3963, row: 114, col: 77}], _aether._userInfo, false);\n tmp350 = 'terrifyTargets';\n _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3978, row: 114, col: 92}]); tmp347 = tmp349[tmp350]; _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3978, row: 114, col: 92}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3982, row: 114, col: 96}, {ofs: 3983, row: 114, col: 97}]); tmp348 = 2; _aether.logStatement([{ofs: 3982, row: 114, col: 96}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3983, row: 114, col: 97}]); tmp333 = tmp347 != tmp348; _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3983, row: 114, col: 97}]); tmp333 = tmp334; _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n }\n if (tmp333) {\n tmp354 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp355 = 'noArcher';\n _aether.logStatementStart([{ofs: 3988, row: 114, col: 102}, {ofs: 4001, row: 114, col: 115}]); tmp353 = tmp354[tmp355]; _aether.logStatement([{ofs: 3988, row: 114, col: 102}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3987, row: 114, col: 101}, {ofs: 4001, row: 114, col: 115}]); tmp332 = !tmp353; _aether.logStatement([{ofs: 3987, row: 114, col: 101}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 4001, row: 114, col: 115}]); tmp332 = tmp333; _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n }\n if (tmp332) {\n tmp356 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp357 = 'build';\n _aether.logStatementStart([{ofs: 4025, row: 115, col: 19}, {ofs: 4033, row: 115, col: 27}]); tmp358 = 'archer'; _aether.logStatement([{ofs: 4025, row: 115, col: 19}, {ofs: 4033, row: 115, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4014, row: 115, col: 8}, {ofs: 4034, row: 115, col: 28}]); tmp359 = _aether.createAPIClone(_aether, tmp356[tmp357](_aether.restoreAPIClone(_aether, tmp358))); _aether.logStatement([{ofs: 4014, row: 115, col: 8}, {ofs: 4034, row: 115, col: 28}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp363 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp364 = 'archers';\n _aether.logStatementStart([{ofs: 4293, row: 124, col: 8}, {ofs: 4305, row: 124, col: 20}]); tmp362 = tmp363[tmp364]; _aether.logStatement([{ofs: 4293, row: 124, col: 8}, {ofs: 4305, row: 124, col: 20}], _aether._userInfo, false);\n if (tmp362) {\n tmp369 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp370 = 'friends';\n _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4321, row: 124, col: 36}]); tmp367 = tmp369[tmp370]; _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4321, row: 124, col: 36}], _aether._userInfo, false);\n tmp368 = 'length';\n _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4328, row: 124, col: 43}]); tmp365 = tmp367[tmp368]; _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4328, row: 124, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4332, row: 124, col: 47}, {ofs: 4333, row: 124, col: 48}]); tmp366 = 5; _aether.logStatement([{ofs: 4332, row: 124, col: 47}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4333, row: 124, col: 48}]); tmp361 = tmp365 >= tmp366; _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4293, row: 124, col: 8}, {ofs: 4333, row: 124, col: 48}]); tmp361 = tmp362; _aether.logStatement([{ofs: 4293, row: 124, col: 8}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n }\n if (tmp361) {\n _aether.logStatementStart([{ofs: 4292, row: 124, col: 7}, {ofs: 4371, row: 124, col: 86}]); tmp360 = tmp361; _aether.logStatement([{ofs: 4292, row: 124, col: 7}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n } else {\n tmp374 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp375 = 'now';\n _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4348, row: 124, col: 63}]); tmp372 = _aether.createAPIClone(_aether, tmp374[tmp375]()); _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4348, row: 124, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4351, row: 124, col: 66}, {ofs: 4353, row: 124, col: 68}]); tmp373 = 12; _aether.logStatement([{ofs: 4351, row: 124, col: 66}, {ofs: 4353, row: 124, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4353, row: 124, col: 68}]); tmp371 = tmp372 > tmp373; _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4353, row: 124, col: 68}], _aether._userInfo, false);\n if (tmp371) {\n tmp377 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp378 = 'noArcher';\n _aether.logStatementStart([{ofs: 4358, row: 124, col: 73}, {ofs: 4371, row: 124, col: 86}]); tmp376 = tmp377[tmp378]; _aether.logStatement([{ofs: 4358, row: 124, col: 73}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4357, row: 124, col: 72}, {ofs: 4371, row: 124, col: 86}]); tmp360 = !tmp376; _aether.logStatement([{ofs: 4357, row: 124, col: 72}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4371, row: 124, col: 86}]); tmp360 = tmp371; _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n }\n }\n if (tmp360) {\n tmp379 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp380 = 'build';\n _aether.logStatementStart([{ofs: 4394, row: 125, col: 19}, {ofs: 4402, row: 125, col: 27}]); tmp381 = 'archer'; _aether.logStatement([{ofs: 4394, row: 125, col: 19}, {ofs: 4402, row: 125, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4383, row: 125, col: 8}, {ofs: 4403, row: 125, col: 28}]); tmp382 = _aether.createAPIClone(_aether, tmp379[tmp380](_aether.restoreAPIClone(_aether, tmp381))); _aether.logStatement([{ofs: 4383, row: 125, col: 8}, {ofs: 4403, row: 125, col: 28}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp387 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp388 = 'myHero';\n _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4445, row: 128, col: 18}]); tmp386 = tmp387[tmp388]; _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4445, row: 128, col: 18}], _aether._userInfo, false);\n if (tmp386) {\n tmp391 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp392 = 'myHero';\n _aether.logStatementStart([{ofs: 4449, row: 128, col: 22}, {ofs: 4460, row: 128, col: 33}]); tmp389 = tmp391[tmp392]; _aether.logStatement([{ofs: 4449, row: 128, col: 22}, {ofs: 4460, row: 128, col: 33}], _aether._userInfo, false);\n tmp390 = 'lateJump';\n _aether.logStatementStart([{ofs: 4449, row: 128, col: 22}, {ofs: 4469, row: 128, col: 42}]); tmp385 = tmp389[tmp390]; _aether.logStatement([{ofs: 4449, row: 128, col: 22}, {ofs: 4469, row: 128, col: 42}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4469, row: 128, col: 42}]); tmp385 = tmp386; _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4469, row: 128, col: 42}], _aether._userInfo, false);\n }\n if (tmp385) {\n tmp397 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp398 = 'friends';\n _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4485, row: 128, col: 58}]); tmp395 = tmp397[tmp398]; _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4485, row: 128, col: 58}], _aether._userInfo, false);\n tmp396 = 'length';\n _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4492, row: 128, col: 65}]); tmp393 = tmp395[tmp396]; _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4492, row: 128, col: 65}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4496, row: 128, col: 69}, {ofs: 4497, row: 128, col: 70}]); tmp394 = 3; _aether.logStatement([{ofs: 4496, row: 128, col: 69}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4497, row: 128, col: 70}]); tmp384 = tmp393 >= tmp394; _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4497, row: 128, col: 70}]); tmp384 = tmp385; _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n }\n if (tmp384) {\n tmp400 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp401 = 'noArcher';\n _aether.logStatementStart([{ofs: 4502, row: 128, col: 75}, {ofs: 4515, row: 128, col: 88}]); tmp399 = tmp400[tmp401]; _aether.logStatement([{ofs: 4502, row: 128, col: 75}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4501, row: 128, col: 74}, {ofs: 4515, row: 128, col: 88}]); tmp383 = !tmp399; _aether.logStatement([{ofs: 4501, row: 128, col: 74}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4515, row: 128, col: 88}]); tmp383 = tmp384; _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n }\n if (tmp383) {\n tmp402 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp403 = 'build';\n _aether.logStatementStart([{ofs: 4538, row: 129, col: 19}, {ofs: 4546, row: 129, col: 27}]); tmp404 = 'archer'; _aether.logStatement([{ofs: 4538, row: 129, col: 19}, {ofs: 4546, row: 129, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4527, row: 129, col: 8}, {ofs: 4547, row: 129, col: 28}]); tmp405 = _aether.createAPIClone(_aether, tmp402[tmp403](_aether.restoreAPIClone(_aether, tmp404))); _aether.logStatement([{ofs: 4527, row: 129, col: 8}, {ofs: 4547, row: 129, col: 28}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp412 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp413 = 'enemies';\n _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4592, row: 134, col: 16}]); tmp410 = tmp412[tmp413]; _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4592, row: 134, col: 16}], _aether._userInfo, false);\n tmp411 = 'length';\n _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4599, row: 134, col: 23}]); tmp408 = tmp410[tmp411]; _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4599, row: 134, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4603, row: 134, col: 27}, {ofs: 4604, row: 134, col: 28}]); tmp409 = 3; _aether.logStatement([{ofs: 4603, row: 134, col: 27}, {ofs: 4604, row: 134, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4604, row: 134, col: 28}]); tmp407 = tmp408 >= tmp409; _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4604, row: 134, col: 28}], _aether._userInfo, false);\n if (tmp407) {\n tmp415 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp416 = 'noArcher';\n _aether.logStatementStart([{ofs: 4609, row: 134, col: 33}, {ofs: 4622, row: 134, col: 46}]); tmp414 = tmp415[tmp416]; _aether.logStatement([{ofs: 4609, row: 134, col: 33}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4608, row: 134, col: 32}, {ofs: 4622, row: 134, col: 46}]); tmp406 = !tmp414; _aether.logStatement([{ofs: 4608, row: 134, col: 32}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4622, row: 134, col: 46}]); tmp406 = tmp407; _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n }\n if (tmp406) {\n _aether.logStatementStart([{ofs: 4630, row: 135, col: 4}, {ofs: 4644, row: 135, col: 18}]); count = 0; _aether.logStatement([{ofs: 4630, row: 135, col: 4}, {ofs: 4644, row: 135, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4649, row: 136, col: 4}, {ofs: 4664, row: 136, col: 19}]); ranged = 0; _aether.logStatement([{ofs: 4649, row: 136, col: 4}, {ofs: 4664, row: 136, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4674, row: 137, col: 9}, {ofs: 4683, row: 137, col: 18}]); i = 1; _aether.logStatement([{ofs: 4674, row: 137, col: 9}, {ofs: 4683, row: 137, col: 18}], _aether._userInfo, false);\n tmp418 = i;\n tmp422 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp423 = 'enemies';\n _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}]); tmp420 = tmp422[tmp423]; _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}], _aether._userInfo, false);\n tmp421 = 'length';\n _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}]); tmp419 = tmp420[tmp421]; _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}]); tmp417 = tmp418 < tmp419; _aether.logStatement([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n tmp432: {\n while (tmp417) {\n tmp433: {\n tmp440 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp441 = 'enemies';\n _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4741, row: 138, col: 24}]); tmp438 = tmp440[tmp441]; _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4741, row: 138, col: 24}], _aether._userInfo, false);\n tmp439 = i;\n _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4744, row: 138, col: 27}]); tmp436 = tmp438[tmp439]; _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4744, row: 138, col: 27}], _aether._userInfo, false);\n tmp437 = 'target';\n _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4751, row: 138, col: 34}]); tmp435 = tmp436[tmp437]; _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4751, row: 138, col: 34}], _aether._userInfo, false);\n if (tmp435) {\n tmp450 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp451 = 'enemies';\n _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4767, row: 138, col: 50}]); tmp448 = tmp450[tmp451]; _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4767, row: 138, col: 50}], _aether._userInfo, false);\n tmp449 = i;\n _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4770, row: 138, col: 53}]); tmp446 = tmp448[tmp449]; _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4770, row: 138, col: 53}], _aether._userInfo, false);\n tmp447 = 'target';\n _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4777, row: 138, col: 60}]); tmp444 = tmp446[tmp447]; _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4777, row: 138, col: 60}], _aether._userInfo, false);\n tmp445 = 'type';\n _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4782, row: 138, col: 65}]); tmp442 = tmp444[tmp445]; _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4782, row: 138, col: 65}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4787, row: 138, col: 70}, {ofs: 4793, row: 138, col: 76}]); tmp443 = 'base'; _aether.logStatement([{ofs: 4787, row: 138, col: 70}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4793, row: 138, col: 76}]); tmp434 = tmp442 === tmp443; _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4793, row: 138, col: 76}]); tmp434 = tmp435; _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n }\n if (tmp434) {\n _aether.logStatementStart([{ofs: 4809, row: 139, col: 12}, {ofs: 4820, row: 139, col: 23}]); tmp452 = 1; _aether.logStatement([{ofs: 4809, row: 139, col: 12}, {ofs: 4820, row: 139, col: 23}], _aether._userInfo, false);\n tmp453 = count;\n tmp454 = tmp452;\n count = tmp453 + tmp454;\n } else {\n ;\n }\n tmp462 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp463 = 'enemies';\n _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4855, row: 141, col: 24}]); tmp460 = tmp462[tmp463]; _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4855, row: 141, col: 24}], _aether._userInfo, false);\n tmp461 = i;\n _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4858, row: 141, col: 27}]); tmp458 = tmp460[tmp461]; _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4858, row: 141, col: 27}], _aether._userInfo, false);\n tmp459 = 'type';\n _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4863, row: 141, col: 32}]); tmp456 = tmp458[tmp459]; _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4863, row: 141, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4868, row: 141, col: 37}, {ofs: 4877, row: 141, col: 46}]); tmp457 = 'thrower'; _aether.logStatement([{ofs: 4868, row: 141, col: 37}, {ofs: 4877, row: 141, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4877, row: 141, col: 46}]); tmp455 = tmp456 === tmp457; _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4877, row: 141, col: 46}], _aether._userInfo, false);\n if (tmp455) {\n _aether.logStatementStart([{ofs: 4893, row: 142, col: 12}, {ofs: 4905, row: 142, col: 24}]); tmp464 = 1; _aether.logStatement([{ofs: 4893, row: 142, col: 12}, {ofs: 4905, row: 142, col: 24}], _aether._userInfo, false);\n tmp465 = ranged;\n tmp466 = tmp464;\n ranged = tmp465 + tmp466;\n } else {\n ;\n }\n }\n tmp430 = i;\n tmp431 = 1;\n i = tmp430 + tmp431;\n tmp424 = i;\n tmp428 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp429 = 'enemies';\n _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}]); tmp426 = tmp428[tmp429]; _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}], _aether._userInfo, false);\n tmp427 = 'length';\n _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}]); tmp425 = tmp426[tmp427]; _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}]); tmp417 = tmp424 < tmp425; _aether.logStatement([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n }\n }\n tmp469 = count;\n tmp475 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp476 = 'enemies';\n _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4951, row: 145, col: 29}]); tmp473 = tmp475[tmp476]; _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4951, row: 145, col: 29}], _aether._userInfo, false);\n tmp474 = 'length';\n _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4958, row: 145, col: 36}]); tmp471 = tmp473[tmp474]; _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4958, row: 145, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4961, row: 145, col: 39}, {ofs: 4962, row: 145, col: 40}]); tmp472 = 2; _aether.logStatement([{ofs: 4961, row: 145, col: 39}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4962, row: 145, col: 40}]); tmp470 = tmp471 - tmp472; _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4930, row: 145, col: 8}, {ofs: 4962, row: 145, col: 40}]); tmp468 = tmp469 >= tmp470; _aether.logStatement([{ofs: 4930, row: 145, col: 8}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n if (tmp468) {\n tmp477 = ranged;\n _aether.logStatementStart([{ofs: 4976, row: 145, col: 54}, {ofs: 4977, row: 145, col: 55}]); tmp478 = 1; _aether.logStatement([{ofs: 4976, row: 145, col: 54}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4966, row: 145, col: 44}, {ofs: 4977, row: 145, col: 55}]); tmp467 = tmp477 >= tmp478; _aether.logStatement([{ofs: 4966, row: 145, col: 44}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4930, row: 145, col: 8}, {ofs: 4977, row: 145, col: 55}]); tmp467 = tmp468; _aether.logStatement([{ofs: 4930, row: 145, col: 8}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n }\n if (tmp467) {\n tmp479 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp480 = 'archers';\n _aether.logStatementStart([{ofs: 4989, row: 146, col: 8}, {ofs: 5009, row: 146, col: 28}]); tmp481 = true; _aether.logStatement([{ofs: 4989, row: 146, col: 8}, {ofs: 5009, row: 146, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4989, row: 146, col: 8}, {ofs: 5008, row: 146, col: 27}]); tmp479[tmp480] = tmp481; _aether.logStatement([{ofs: 4989, row: 146, col: 8}, {ofs: 5008, row: 146, col: 27}], _aether._userInfo, false);\n } else {\n ;\n }\n } else {\n ;\n }\n tmp482 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp483 = 'build';\n _aether.logStatementStart([{ofs: 5060, row: 150, col: 11}, {ofs: 5069, row: 150, col: 20}]); tmp484 = 'soldier'; _aether.logStatement([{ofs: 5060, row: 150, col: 11}, {ofs: 5069, row: 150, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5049, row: 150, col: 0}, {ofs: 5070, row: 150, col: 21}]); tmp485 = _aether.createAPIClone(_aether, tmp482[tmp483](_aether.restoreAPIClone(_aether, tmp484))); _aether.logStatement([{ofs: 5049, row: 150, col: 0}, {ofs: 5070, row: 150, col: 21}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" }, "programmable-tharin": { - "chooseAction": "..." + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var tUnit, tmp2, tmp3, tmp4, tmp45, tmp46, tmp47, tmp79, tmp80, tmp81, tmp186, tmp187, tmp188, tmp239, tmp240, tmp241, tmp273, tmp274, tmp275, tmp324, tmp325, tmp326, tmp376, tmp377, tmp378, tmp428, tmp429, tmp430, tmp494, tmp495, tmp496, tmp623, tmp624, tmp625, tmp626, tmp627, tmp628, tmp629, tmp630, tmp631, tmp632, tmp633, tmp634, tmp635, tmp636, tmp637, tmp638, tmp639, tmp640, tmp641, tmp642, tmp643, tmp644, tmp645, tmp646, tmp647, tmp648, tmp649, tmp650, tmp651, tmp652, tmp653, tmp654, tmp655, tmp656, tmp657, tmp658, tmp659, tmp660, tmp661, tmp662, tmp663, tmp664, tmp665, tmp666, tmp667, tmp668, tmp669, tmp670, tmp671, tmp672, tmp673, tmp674, tmp675, tmp676, tmp677, tmp678, tmp679, tmp680, tmp681, tmp682, tmp683, tmp684, tmp685, tmp686, tmp687, tmp688, tmp689, tmp690, tmp691, tmp692, tmp693, tmp694, tmp695, tmp696, tmp697, tmp698, tmp699, tmp700, tmp701, tmp702, tmp703, tmp704, tmp705, tmp706, tmp707, tmp708, tmp709, tmp710, tmp711, tmp712, tmp713, tmp714, tmp715, tmp716, tmp717, tmp718, tmp719, tmp720, tmp721, tmp722, tmp723, tmp724, tmp725, tmp726, tmp727, tmp728, tmp729, tmp730, tmp731, tmp732, tmp733, tmp734, tmp735, tmp736, tmp737, tmp738, tmp739, tmp740, tmp741, tmp742, tmp743, tmp744, tmp745, tmp746, tmp747, tmp748, tmp749, tmp750, tmp751, tmp752, tmp753, tmp754, tmp755, tmp756, tmp757, tmp758, tmp759, tmp760, tmp761, tmp762, tmp763, tmp764, tmp765, tmp766, tmp767, tmp768, tmp769, tmp770, tmp771, tmp772, tmp773, tmp774, tmp775, tmp776, tmp777, tmp778, tmp779, tmp780, tmp781, tmp782, tmp783, tmp784, tmp785, tmp786, tmp787, tmp788, tmp789, tmp790, tmp791, tmp792, tmp793, tmp794, tmp795, tmp796, tmp797, tmp798, tmp799, tmp800, tmp801, tmp802, tmp803, tmp804, tmp805, tmp806, tmp807, tmp808, tmp809, tmp810, tmp811, tmp812, tmp813, tmp814, tmp815, tmp816, tmp817, tmp818, tmp819, tmp820, tmp821, tmp822, tmp823, tmp824, tmp825, tmp826, tmp827, tmp828, tmp829, tmp830, tmp831, tmp832, tmp833, tmp834, tmp835, tmp836, tmp837, tmp838, tmp839, tmp840, tmp841, tmp842, tmp843, tmp844, tmp845, tmp846, tmp847, tmp848, tmp849, tmp850, tmp851, tmp852, tmp853, tmp854, tmp855, tmp856, tmp857, tmp858, tmp859, tmp860, tmp861, tmp862, tmp863, tmp864, tmp865, tmp866, tmp867, tmp868, tmp869, tmp870, tmp871, tmp872, tmp873, tmp874, tmp875, tmp876, tmp877, tmp878, tmp879, tmp880, tmp881, tmp882, tmp883, tmp884, tmp885, tmp886, tmp887, tmp888, tmp889, tmp890, tmp891, tmp892, tmp893, tmp894, tmp895, tmp896, tmp897, tmp898, tmp899, tmp900, tmp901, tmp902, tmp903, tmp904, tmp905, tmp906, tmp907, tmp908, tmp909, tmp910, tmp911, tmp912, tmp913, tmp914, tmp915, tmp916, tmp917, tmp918, tmp919, tmp920, tmp921, tmp922, tmp923, tmp924, tmp925, tmp926, tmp927, tmp928, tmp929, tmp930, tmp931, tmp932, tmp933, tmp934, tmp935, tmp936, tmp937, tmp938, tmp939, tmp940, tmp941, tmp942, tmp943, tmp944, tmp945, tmp946, tmp947, tmp948, tmp949, tmp950, tmp951, tmp952, tmp953, tmp954, tmp955, tmp956, tmp957, tmp958, tmp959, tmp960, tmp961, tmp962, tmp963, tmp964, tmp965, tmp966, tmp967, tmp968, tmp969, tmp970, tmp971, tmp972, tmp973, tmp974, tmp975, tmp976, tmp977, tmp978, tmp979, tmp980, tmp981, tmp982, tmp983, tmp984, tmp985, tmp986, tmp987, tmp988, tmp989, tmp990, tmp991, tmp992, tmp993, tmp994, tmp995, tmp996, tmp997, tmp998, tmp999, tmp1000, tmp1001, tmp1002, tmp1003, tmp1004, tmp1005, tmp1006, tmp1007, tmp1008, tmp1009, tmp1010, tmp1011, tmp1012, tmp1013, tmp1014, tmp1015, tmp1016, tmp1017, tmp1018, tmp1019, tmp1020, tmp1021, tmp1022, tmp1023, tmp1024, tmp1025, tmp1026, tmp1027, tmp1028, tmp1029, tmp1030, tmp1031, tmp1032, tmp1033, tmp1034, tmp1035, tmp1036, tmp1037, tmp1038, tmp1039, tmp1040, tmp1041, tmp1042, tmp1043, tmp1044, tmp1045, tmp1046, tmp1047, tmp1048, tmp1049, tmp1050, tmp1051, tmp1052, tmp1053, tmp1054, tmp1055, tmp1056, tmp1057, tmp1058, tmp1059, tmp1060, tmp1061, tmp1062, tmp1063, tmp1064, tmp1065, tmp1066, tmp1067, tmp1068, tmp1069, tmp1070, tmp1071, tmp1072, tmp1073, tmp1074, tmp1075, tmp1076, tmp1077, tmp1078, tmp1079, tmp1080, tmp1081, tmp1082, tmp1083, tmp1084, tmp1085, tmp1086, tmp1087, tmp1088, tmp1089, tmp1090, tmp1091, tmp1092, tmp1093, tmp1094, tmp1095, tmp1096, tmp1097, tmp1098, tmp1099, tmp1100, tmp1101, tmp1102, tmp1103, tmp1104, tmp1105, tmp1106, tmp1107, tmp1108, tmp1109, tmp1110, tmp1111, tmp1112, tmp1113, tmp1114, tmp1115, tmp1116, tmp1117, tmp1118, tmp1119, tmp1120, tmp1121, tmp1122, tmp1123, tmp1124, tmp1125, tmp1126, tmp1127, tmp1128, tmp1129, tmp1130, tmp1131, tmp1132, tmp1133, tmp1134, tmp1135, tmp1136, tmp1137, tmp1138, tmp1139, tmp1140, tmp1141, tmp1142, tmp1143, tmp1144, tmp1145, tmp1146, tmp1147, tmp1148, tmp1149, tmp1150, tmp1151, tmp1152, tmp1153, tmp1154, tmp1155, tmp1156, tmp1157, tmp1158, tmp1159, tmp1160, tmp1161, tmp1162, tmp1163, tmp1164, tmp1165, tmp1166, tmp1167, tmp1168, tmp1169, tmp1170, tmp1171, tmp1172, tmp1173, tmp1174, tmp1175, tmp1176, tmp1177, tmp1178, tmp1179, tmp1180, tmp1181, tmp1182, tmp1183, tmp1184, tmp1185, tmp1186, tmp1187, tmp1188, tmp1189, tmp1190, tmp1191, tmp1192, tmp1193, tmp1194, tmp1195, tmp1196, tmp1197, tmp1198, tmp1199, tmp1200, tmp1201, tmp1202, tmp1203, tmp1204, tmp1205, tmp1206, tmp1207, tmp1208, tmp1209, tmp1210, tmp1211, tmp1212, tmp1213, tmp1214, tmp1215, tmp1216, tmp1217, tmp1218, tmp1219, tmp1220, tmp1221, tmp1222, tmp1223, tmp1224, tmp1225, tmp1226, tmp1227, tmp1228, tmp1229, tmp1230, tmp1231, tmp1232, tmp1233, tmp1234, tmp1235, tmp1236, tmp1237, tmp1238, tmp1239, tmp1240, tmp1241, tmp1242, tmp1243, tmp1244, tmp1245, tmp1246, tmp1247, tmp1248, tmp1249, tmp1250, tmp1251, tmp1252, tmp1253, tmp1254, tmp1255, tmp1256, tmp1257, tmp1258, tmp1259, tmp1260, tmp1261, tmp1262, tmp1263, tmp1264, tmp1265, tmp1266, tmp1267, tmp1268, tmp1269, tmp1270, tmp1271, tmp1272, tmp1273, tmp1274, tmp1275; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getEnemyHero';\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 264, row: 7, col: 2}]); tmp4 = function () {\n var i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 81, row: 2, col: 8}, {ofs: 90, row: 2, col: 17}]); i = 0; _aether.logStatement([{ofs: 81, row: 2, col: 8}, {ofs: 90, row: 2, col: 17}], _aether._userInfo, false);\n tmp6 = i;\n tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp11 = 'enemies';\n _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}]); tmp8 = tmp10[tmp11]; _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}], _aether._userInfo, false);\n tmp9 = 'length';\n _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}]); tmp7 = tmp8[tmp9]; _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}]); tmp5 = tmp6 < tmp7; _aether.logStatement([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n tmp20: {\n while (tmp5) {\n tmp21: {\n tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp31 = 'enemies';\n _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 147, row: 3, col: 23}]); tmp28 = tmp30[tmp31]; _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 147, row: 3, col: 23}], _aether._userInfo, false);\n tmp29 = i;\n _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 150, row: 3, col: 26}]); tmp26 = tmp28[tmp29]; _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 150, row: 3, col: 26}], _aether._userInfo, false);\n tmp27 = 'type';\n _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 155, row: 3, col: 31}]); tmp24 = tmp26[tmp27]; _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 155, row: 3, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 160, row: 3, col: 36}, {ofs: 169, row: 3, col: 45}]); tmp25 = 'brawler'; _aether.logStatement([{ofs: 160, row: 3, col: 36}, {ofs: 169, row: 3, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 169, row: 3, col: 45}]); tmp23 = tmp24 === tmp25; _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 169, row: 3, col: 45}], _aether._userInfo, false);\n if (tmp23) {\n _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 206, row: 3, col: 82}]); tmp22 = tmp23; _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n } else {\n tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp39 = 'enemies';\n _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 185, row: 3, col: 61}]); tmp36 = tmp38[tmp39]; _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 185, row: 3, col: 61}], _aether._userInfo, false);\n tmp37 = i;\n _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 188, row: 3, col: 64}]); tmp34 = tmp36[tmp37]; _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 188, row: 3, col: 64}], _aether._userInfo, false);\n tmp35 = 'type';\n _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 193, row: 3, col: 69}]); tmp32 = tmp34[tmp35]; _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 193, row: 3, col: 69}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 198, row: 3, col: 74}, {ofs: 206, row: 3, col: 82}]); tmp33 = 'shaman'; _aether.logStatement([{ofs: 198, row: 3, col: 74}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 206, row: 3, col: 82}]); tmp22 = tmp32 === tmp33; _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n }\n if (tmp22) {\n tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp44 = 'enemies';\n _aether.logStatementStart([{ofs: 229, row: 4, col: 19}, {ofs: 241, row: 4, col: 31}]); tmp41 = tmp43[tmp44]; _aether.logStatement([{ofs: 229, row: 4, col: 19}, {ofs: 241, row: 4, col: 31}], _aether._userInfo, false);\n tmp42 = i;\n _aether.logStatementStart([{ofs: 229, row: 4, col: 19}, {ofs: 244, row: 4, col: 34}]); tmp40 = tmp41[tmp42]; _aether.logStatement([{ofs: 229, row: 4, col: 19}, {ofs: 244, row: 4, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp40);\n } else {\n ;\n }\n }\n tmp18 = i;\n tmp19 = 1;\n i = tmp18 + tmp19;\n tmp12 = i;\n tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp17 = 'enemies';\n _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}]); tmp14 = tmp16[tmp17]; _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}], _aether._userInfo, false);\n tmp15 = 'length';\n _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}]); tmp13 = tmp14[tmp15]; _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}]); tmp5 = tmp12 < tmp13; _aether.logStatement([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 264, row: 7, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 263, row: 7, col: 1}]); tmp2[tmp3] = tmp4; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 263, row: 7, col: 1}], _aether._userInfo, false);\n tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp46 = 'getEnemyBase';\n _aether.logStatementStart([{ofs: 266, row: 9, col: 0}, {ofs: 450, row: 15, col: 2}]); tmp47 = function () {\n var i, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 307, row: 10, col: 8}, {ofs: 316, row: 10, col: 17}]); i = 0; _aether.logStatement([{ofs: 307, row: 10, col: 8}, {ofs: 316, row: 10, col: 17}], _aether._userInfo, false);\n tmp49 = i;\n tmp53 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp54 = 'enemies';\n _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}]); tmp51 = tmp53[tmp54]; _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}], _aether._userInfo, false);\n tmp52 = 'length';\n _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}]); tmp50 = tmp51[tmp52]; _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}]); tmp48 = tmp49 < tmp50; _aether.logStatement([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n tmp63: {\n while (tmp48) {\n tmp64: {\n tmp72 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp73 = 'enemies';\n _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 373, row: 11, col: 23}]); tmp70 = tmp72[tmp73]; _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 373, row: 11, col: 23}], _aether._userInfo, false);\n tmp71 = i;\n _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 376, row: 11, col: 26}]); tmp68 = tmp70[tmp71]; _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 376, row: 11, col: 26}], _aether._userInfo, false);\n tmp69 = 'type';\n _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 381, row: 11, col: 31}]); tmp66 = tmp68[tmp69]; _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 381, row: 11, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 386, row: 11, col: 36}, {ofs: 392, row: 11, col: 42}]); tmp67 = 'base'; _aether.logStatement([{ofs: 386, row: 11, col: 36}, {ofs: 392, row: 11, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 392, row: 11, col: 42}]); tmp65 = tmp66 === tmp67; _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 392, row: 11, col: 42}], _aether._userInfo, false);\n if (tmp65) {\n tmp77 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp78 = 'enemies';\n _aether.logStatementStart([{ofs: 415, row: 12, col: 19}, {ofs: 427, row: 12, col: 31}]); tmp75 = tmp77[tmp78]; _aether.logStatement([{ofs: 415, row: 12, col: 19}, {ofs: 427, row: 12, col: 31}], _aether._userInfo, false);\n tmp76 = i;\n _aether.logStatementStart([{ofs: 415, row: 12, col: 19}, {ofs: 430, row: 12, col: 34}]); tmp74 = tmp75[tmp76]; _aether.logStatement([{ofs: 415, row: 12, col: 19}, {ofs: 430, row: 12, col: 34}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp74);\n } else {\n ;\n }\n }\n tmp61 = i;\n tmp62 = 1;\n i = tmp61 + tmp62;\n tmp55 = i;\n tmp59 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp60 = 'enemies';\n _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}]); tmp57 = tmp59[tmp60]; _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}], _aether._userInfo, false);\n tmp58 = 'length';\n _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}]); tmp56 = tmp57[tmp58]; _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}]); tmp48 = tmp55 < tmp56; _aether.logStatement([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n }\n }\n return;\n }; _aether.logStatement([{ofs: 266, row: 9, col: 0}, {ofs: 450, row: 15, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 266, row: 9, col: 0}, {ofs: 449, row: 15, col: 1}]); tmp45[tmp46] = tmp47; _aether.logStatement([{ofs: 266, row: 9, col: 0}, {ofs: 449, row: 15, col: 1}], _aether._userInfo, false);\n tmp79 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp80 = 'isOpponentBaseRushing';\n _aether.logStatementStart([{ofs: 452, row: 17, col: 0}, {ofs: 1149, row: 34, col: 2}]); tmp81 = function () {\n var count, i, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 620, row: 21, col: 4}, {ofs: 634, row: 21, col: 18}]); count = 0; _aether.logStatement([{ofs: 620, row: 21, col: 4}, {ofs: 634, row: 21, col: 18}], _aether._userInfo, false);\n tmp85 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp86 = 'enemyHero';\n _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 656, row: 22, col: 21}]); tmp84 = tmp85[tmp86]; _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 656, row: 22, col: 21}], _aether._userInfo, false);\n if (tmp84) {\n tmp89 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp90 = 'enemyHero';\n _aether.logStatementStart([{ofs: 660, row: 22, col: 25}, {ofs: 674, row: 22, col: 39}]); tmp87 = tmp89[tmp90]; _aether.logStatement([{ofs: 660, row: 22, col: 25}, {ofs: 674, row: 22, col: 39}], _aether._userInfo, false);\n tmp88 = 'target';\n _aether.logStatementStart([{ofs: 660, row: 22, col: 25}, {ofs: 681, row: 22, col: 46}]); tmp83 = tmp87[tmp88]; _aether.logStatement([{ofs: 660, row: 22, col: 25}, {ofs: 681, row: 22, col: 46}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 681, row: 22, col: 46}]); tmp83 = tmp84; _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 681, row: 22, col: 46}], _aether._userInfo, false);\n }\n if (tmp83) {\n tmp98 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp99 = 'enemyHero';\n _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 700, row: 22, col: 65}]); tmp96 = tmp98[tmp99]; _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 700, row: 22, col: 65}], _aether._userInfo, false);\n tmp97 = 'target';\n _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 707, row: 22, col: 72}]); tmp94 = tmp96[tmp97]; _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 707, row: 22, col: 72}], _aether._userInfo, false);\n tmp95 = 'type';\n _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 712, row: 22, col: 77}]); tmp92 = tmp94[tmp95]; _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 712, row: 22, col: 77}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 717, row: 22, col: 82}, {ofs: 723, row: 22, col: 88}]); tmp93 = 'base'; _aether.logStatement([{ofs: 717, row: 22, col: 82}, {ofs: 723, row: 22, col: 88}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 723, row: 22, col: 88}]); tmp91 = tmp92 === tmp93; _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 723, row: 22, col: 88}], _aether._userInfo, false);\n if (tmp91) {\n _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 766, row: 22, col: 131}]); tmp82 = tmp91; _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n } else {\n tmp106 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp107 = 'enemyHero';\n _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 741, row: 22, col: 106}]); tmp104 = tmp106[tmp107]; _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 741, row: 22, col: 106}], _aether._userInfo, false);\n tmp105 = 'target';\n _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 748, row: 22, col: 113}]); tmp102 = tmp104[tmp105]; _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 748, row: 22, col: 113}], _aether._userInfo, false);\n tmp103 = 'type';\n _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 753, row: 22, col: 118}]); tmp100 = tmp102[tmp103]; _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 753, row: 22, col: 118}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 758, row: 22, col: 123}, {ofs: 766, row: 22, col: 131}]); tmp101 = 'knight'; _aether.logStatement([{ofs: 758, row: 22, col: 123}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 766, row: 22, col: 131}]); tmp82 = tmp100 === tmp101; _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 767, row: 22, col: 132}]); tmp82 = tmp83; _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 767, row: 22, col: 132}], _aether._userInfo, false);\n }\n if (tmp82) {\n _aether.logStatementStart([{ofs: 786, row: 23, col: 15}, {ofs: 790, row: 23, col: 19}]); tmp108 = true; _aether.logStatement([{ofs: 786, row: 23, col: 15}, {ofs: 790, row: 23, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp108);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 806, row: 25, col: 8}, {ofs: 815, row: 25, col: 17}]); i = 1; _aether.logStatement([{ofs: 806, row: 25, col: 8}, {ofs: 815, row: 25, col: 17}], _aether._userInfo, false);\n tmp110 = i;\n tmp114 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp115 = 'enemies';\n _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}]); tmp112 = tmp114[tmp115]; _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}], _aether._userInfo, false);\n tmp113 = 'length';\n _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}]); tmp111 = tmp112[tmp113]; _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}]); tmp109 = tmp110 < tmp111; _aether.logStatement([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n tmp124: {\n while (tmp109) {\n tmp125: {\n tmp132 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp133 = 'enemies';\n _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 872, row: 26, col: 23}]); tmp130 = tmp132[tmp133]; _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 872, row: 26, col: 23}], _aether._userInfo, false);\n tmp131 = i;\n _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 875, row: 26, col: 26}]); tmp128 = tmp130[tmp131]; _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 875, row: 26, col: 26}], _aether._userInfo, false);\n tmp129 = 'target';\n _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 882, row: 26, col: 33}]); tmp127 = tmp128[tmp129]; _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 882, row: 26, col: 33}], _aether._userInfo, false);\n if (tmp127) {\n tmp143 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp144 = 'enemies';\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 899, row: 26, col: 50}]); tmp141 = tmp143[tmp144]; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 899, row: 26, col: 50}], _aether._userInfo, false);\n tmp142 = i;\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 902, row: 26, col: 53}]); tmp139 = tmp141[tmp142]; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 902, row: 26, col: 53}], _aether._userInfo, false);\n tmp140 = 'target';\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 909, row: 26, col: 60}]); tmp137 = tmp139[tmp140]; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 909, row: 26, col: 60}], _aether._userInfo, false);\n tmp138 = 'type';\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 914, row: 26, col: 65}]); tmp135 = tmp137[tmp138]; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 914, row: 26, col: 65}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 919, row: 26, col: 70}, {ofs: 925, row: 26, col: 76}]); tmp136 = 'base'; _aether.logStatement([{ofs: 919, row: 26, col: 70}, {ofs: 925, row: 26, col: 76}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 925, row: 26, col: 76}]); tmp134 = tmp135 === tmp136; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 925, row: 26, col: 76}], _aether._userInfo, false);\n if (tmp134) {\n _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 969, row: 26, col: 120}]); tmp126 = tmp134; _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n } else {\n tmp153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp154 = 'enemies';\n _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 941, row: 26, col: 92}]); tmp151 = tmp153[tmp154]; _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 941, row: 26, col: 92}], _aether._userInfo, false);\n tmp152 = i;\n _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 944, row: 26, col: 95}]); tmp149 = tmp151[tmp152]; _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 944, row: 26, col: 95}], _aether._userInfo, false);\n tmp150 = 'target';\n _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 951, row: 26, col: 102}]); tmp147 = tmp149[tmp150]; _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 951, row: 26, col: 102}], _aether._userInfo, false);\n tmp148 = 'type';\n _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 956, row: 26, col: 107}]); tmp145 = tmp147[tmp148]; _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 956, row: 26, col: 107}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 961, row: 26, col: 112}, {ofs: 969, row: 26, col: 120}]); tmp146 = 'knight'; _aether.logStatement([{ofs: 961, row: 26, col: 112}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 969, row: 26, col: 120}]); tmp126 = tmp145 === tmp146; _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 970, row: 26, col: 121}]); tmp126 = tmp127; _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 970, row: 26, col: 121}], _aether._userInfo, false);\n }\n if (tmp126) {\n _aether.logStatementStart([{ofs: 986, row: 27, col: 12}, {ofs: 997, row: 27, col: 23}]); tmp155 = 1; _aether.logStatement([{ofs: 986, row: 27, col: 12}, {ofs: 997, row: 27, col: 23}], _aether._userInfo, false);\n tmp156 = count;\n tmp157 = tmp155;\n count = tmp156 + tmp157;\n } else {\n ;\n }\n }\n tmp122 = i;\n tmp123 = 1;\n i = tmp122 + tmp123;\n tmp116 = i;\n tmp120 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp121 = 'enemies';\n _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}]); tmp118 = tmp120[tmp121]; _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}], _aether._userInfo, false);\n tmp119 = 'length';\n _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}]); tmp117 = tmp118[tmp119]; _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}]); tmp109 = tmp116 < tmp117; _aether.logStatement([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n }\n }\n tmp164 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp165 = 'enemies';\n _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1033, row: 30, col: 19}]); tmp162 = tmp164[tmp165]; _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1033, row: 30, col: 19}], _aether._userInfo, false);\n tmp163 = 'length';\n _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1040, row: 30, col: 26}]); tmp160 = tmp162[tmp163]; _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1040, row: 30, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1044, row: 30, col: 30}, {ofs: 1045, row: 30, col: 31}]); tmp161 = 3; _aether.logStatement([{ofs: 1044, row: 30, col: 30}, {ofs: 1045, row: 30, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1045, row: 30, col: 31}]); tmp159 = tmp160 >= tmp161; _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1045, row: 30, col: 31}], _aether._userInfo, false);\n if (tmp159) {\n tmp168 = 'Math';\n tmp169 = tmp168 in __global;\n if (tmp169) {\n tmp166 = __global[tmp168];\n } else {\n tmp170 = 'ReferenceError';\n tmp171 = __global[tmp170];\n tmp172 = new tmp171();\n throw tmp172;\n }\n tmp167 = 'ceil';\n tmp174 = count;\n tmp182 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp183 = 'enemies';\n _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1081, row: 30, col: 67}]); tmp180 = tmp182[tmp183]; _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1081, row: 30, col: 67}], _aether._userInfo, false);\n tmp181 = 'length';\n _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1088, row: 30, col: 74}]); tmp178 = tmp180[tmp181]; _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1088, row: 30, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1091, row: 30, col: 77}, {ofs: 1092, row: 30, col: 78}]); tmp179 = 1; _aether.logStatement([{ofs: 1091, row: 30, col: 77}, {ofs: 1092, row: 30, col: 78}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1092, row: 30, col: 78}]); tmp176 = tmp178 - tmp179; _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1092, row: 30, col: 78}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1096, row: 30, col: 82}, {ofs: 1097, row: 30, col: 83}]); tmp177 = 3; _aether.logStatement([{ofs: 1096, row: 30, col: 82}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1068, row: 30, col: 54}, {ofs: 1097, row: 30, col: 83}]); tmp175 = tmp176 / tmp177; _aether.logStatement([{ofs: 1068, row: 30, col: 54}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1059, row: 30, col: 45}, {ofs: 1097, row: 30, col: 83}]); tmp173 = tmp174 >= tmp175; _aether.logStatement([{ofs: 1059, row: 30, col: 45}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1049, row: 30, col: 35}, {ofs: 1098, row: 30, col: 84}]); tmp158 = _aether.createAPIClone(_aether, tmp166[tmp167](_aether.restoreAPIClone(_aether, tmp173))); _aether.logStatement([{ofs: 1049, row: 30, col: 35}, {ofs: 1098, row: 30, col: 84}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1098, row: 30, col: 84}]); tmp158 = tmp159; _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1098, row: 30, col: 84}], _aether._userInfo, false);\n }\n if (tmp158) {\n _aether.logStatementStart([{ofs: 1117, row: 31, col: 15}, {ofs: 1121, row: 31, col: 19}]); tmp184 = true; _aether.logStatement([{ofs: 1117, row: 31, col: 15}, {ofs: 1121, row: 31, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp184);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 1140, row: 33, col: 11}, {ofs: 1145, row: 33, col: 16}]); tmp185 = false; _aether.logStatement([{ofs: 1140, row: 33, col: 11}, {ofs: 1145, row: 33, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp185);\n }; _aether.logStatement([{ofs: 452, row: 17, col: 0}, {ofs: 1149, row: 34, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 452, row: 17, col: 0}, {ofs: 1148, row: 34, col: 1}]); tmp79[tmp80] = tmp81; _aether.logStatement([{ofs: 452, row: 17, col: 0}, {ofs: 1148, row: 34, col: 1}], _aether._userInfo, false);\n tmp186 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp187 = 'findTerrifyUnit';\n _aether.logStatementStart([{ofs: 1151, row: 36, col: 0}, {ofs: 1780, row: 57, col: 2}]); tmp188 = function () {\n var unit, unitSize, i, tempUnitSize, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 1192, row: 38, col: 4}, {ofs: 1208, row: 38, col: 20}]); unit = null; _aether.logStatement([{ofs: 1192, row: 38, col: 4}, {ofs: 1208, row: 38, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1213, row: 39, col: 4}, {ofs: 1230, row: 39, col: 21}]); unitSize = 0; _aether.logStatement([{ofs: 1213, row: 39, col: 4}, {ofs: 1230, row: 39, col: 21}], _aether._userInfo, false);\n tmp191 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp192 = 'enemyHero';\n _aether.logStatementStart([{ofs: 1378, row: 45, col: 7}, {ofs: 1392, row: 45, col: 21}]); tmp190 = tmp191[tmp192]; _aether.logStatement([{ofs: 1378, row: 45, col: 7}, {ofs: 1392, row: 45, col: 21}], _aether._userInfo, false);\n if (tmp190) {\n tmp197 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp198 = 'enemyHero';\n _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1410, row: 45, col: 39}]); tmp195 = tmp197[tmp198]; _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1410, row: 45, col: 39}], _aether._userInfo, false);\n tmp196 = 'type';\n _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1415, row: 45, col: 44}]); tmp193 = tmp195[tmp196]; _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1415, row: 45, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1420, row: 45, col: 49}, {ofs: 1428, row: 45, col: 57}]); tmp194 = 'shaman'; _aether.logStatement([{ofs: 1420, row: 45, col: 49}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1428, row: 45, col: 57}]); tmp189 = tmp193 === tmp194; _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1378, row: 45, col: 7}, {ofs: 1428, row: 45, col: 57}]); tmp189 = tmp190; _aether.logStatement([{ofs: 1378, row: 45, col: 7}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n }\n if (tmp189) {\n tmp199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp200 = 'terrifyClumpMinSize';\n _aether.logStatementStart([{ofs: 1440, row: 46, col: 8}, {ofs: 1469, row: 46, col: 37}]); tmp201 = 5; _aether.logStatement([{ofs: 1440, row: 46, col: 8}, {ofs: 1469, row: 46, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1440, row: 46, col: 8}, {ofs: 1468, row: 46, col: 36}]); tmp199[tmp200] = tmp201; _aether.logStatement([{ofs: 1440, row: 46, col: 8}, {ofs: 1468, row: 46, col: 36}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 1485, row: 49, col: 8}, {ofs: 1494, row: 49, col: 17}]); i = 1; _aether.logStatement([{ofs: 1485, row: 49, col: 8}, {ofs: 1494, row: 49, col: 17}], _aether._userInfo, false);\n tmp203 = i;\n tmp207 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp208 = 'enemies';\n _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}]); tmp205 = tmp207[tmp208]; _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}], _aether._userInfo, false);\n tmp206 = 'length';\n _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}]); tmp204 = tmp205[tmp206]; _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}]); tmp202 = tmp203 < tmp204; _aether.logStatement([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n tmp217: {\n while (tmp202) {\n tmp218: {\n tmp219 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp220 = 'getClumpSize';\n tmp224 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp225 = 'enemies';\n _aether.logStatementStart([{ofs: 1573, row: 50, col: 45}, {ofs: 1585, row: 50, col: 57}]); tmp222 = tmp224[tmp225]; _aether.logStatement([{ofs: 1573, row: 50, col: 45}, {ofs: 1585, row: 50, col: 57}], _aether._userInfo, false);\n tmp223 = i;\n _aether.logStatementStart([{ofs: 1573, row: 50, col: 45}, {ofs: 1588, row: 50, col: 60}]); tmp221 = tmp222[tmp223]; _aether.logStatement([{ofs: 1573, row: 50, col: 45}, {ofs: 1588, row: 50, col: 60}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1536, row: 50, col: 8}, {ofs: 1590, row: 50, col: 62}]); tempUnitSize = _aether.createAPIClone(_aether, tmp219[tmp220](_aether.restoreAPIClone(_aether, tmp221))); _aether.logStatement([{ofs: 1536, row: 50, col: 8}, {ofs: 1590, row: 50, col: 62}], _aether._userInfo, false);\n tmp228 = tempUnitSize;\n tmp229 = unitSize;\n _aether.logStatementStart([{ofs: 1602, row: 51, col: 11}, {ofs: 1625, row: 51, col: 34}]); tmp227 = tmp228 > tmp229; _aether.logStatement([{ofs: 1602, row: 51, col: 11}, {ofs: 1625, row: 51, col: 34}], _aether._userInfo, false);\n if (tmp227) {\n tmp230 = tempUnitSize;\n tmp232 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp233 = 'terrifyClumpMinSize';\n _aether.logStatementStart([{ofs: 1644, row: 51, col: 53}, {ofs: 1668, row: 51, col: 77}]); tmp231 = tmp232[tmp233]; _aether.logStatement([{ofs: 1644, row: 51, col: 53}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1629, row: 51, col: 38}, {ofs: 1668, row: 51, col: 77}]); tmp226 = tmp230 > tmp231; _aether.logStatement([{ofs: 1629, row: 51, col: 38}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 1602, row: 51, col: 11}, {ofs: 1668, row: 51, col: 77}]); tmp226 = tmp227; _aether.logStatement([{ofs: 1602, row: 51, col: 11}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n }\n if (tmp226) {\n tmp236 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp237 = 'enemies';\n _aether.logStatementStart([{ofs: 1691, row: 52, col: 19}, {ofs: 1703, row: 52, col: 31}]); tmp234 = tmp236[tmp237]; _aether.logStatement([{ofs: 1691, row: 52, col: 19}, {ofs: 1703, row: 52, col: 31}], _aether._userInfo, false);\n tmp235 = i;\n _aether.logStatementStart([{ofs: 1684, row: 52, col: 12}, {ofs: 1707, row: 52, col: 35}]); unit = tmp234[tmp235]; _aether.logStatement([{ofs: 1684, row: 52, col: 12}, {ofs: 1707, row: 52, col: 35}], _aether._userInfo, false);\n unitSize = tempUnitSize;\n } else {\n ;\n }\n }\n tmp215 = i;\n tmp216 = 1;\n i = tmp215 + tmp216;\n tmp209 = i;\n tmp213 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp214 = 'enemies';\n _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}]); tmp211 = tmp213[tmp214]; _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}], _aether._userInfo, false);\n tmp212 = 'length';\n _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}]); tmp210 = tmp211[tmp212]; _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}]); tmp202 = tmp209 < tmp210; _aether.logStatement([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n }\n }\n tmp238 = unit;\n return _aether.restoreAPIClone(_aether, tmp238);\n }; _aether.logStatement([{ofs: 1151, row: 36, col: 0}, {ofs: 1780, row: 57, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1151, row: 36, col: 0}, {ofs: 1779, row: 57, col: 1}]); tmp186[tmp187] = tmp188; _aether.logStatement([{ofs: 1151, row: 36, col: 0}, {ofs: 1779, row: 57, col: 1}], _aether._userInfo, false);\n tmp239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp240 = 'getClumpSize';\n _aether.logStatementStart([{ofs: 1782, row: 59, col: 0}, {ofs: 2001, row: 68, col: 2}]); tmp241 = function (unit) {\n var count, i, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272; unit = _aether.createAPIClone(_aether, unit); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 1824, row: 61, col: 4}, {ofs: 1838, row: 61, col: 18}]); count = 0; _aether.logStatement([{ofs: 1824, row: 61, col: 4}, {ofs: 1838, row: 61, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1847, row: 62, col: 8}, {ofs: 1856, row: 62, col: 17}]); i = 1; _aether.logStatement([{ofs: 1847, row: 62, col: 8}, {ofs: 1856, row: 62, col: 17}], _aether._userInfo, false);\n tmp243 = i;\n tmp247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp248 = 'enemies';\n _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}]); tmp245 = tmp247[tmp248]; _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}], _aether._userInfo, false);\n tmp246 = 'length';\n _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}]); tmp244 = tmp245[tmp246]; _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}]); tmp242 = tmp243 < tmp244; _aether.logStatement([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n tmp257: {\n while (tmp242) {\n tmp258: {\n tmp262 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp263 = 'distance';\n tmp267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp268 = 'enemies';\n _aether.logStatementStart([{ofs: 1915, row: 63, col: 25}, {ofs: 1927, row: 63, col: 37}]); tmp265 = tmp267[tmp268]; _aether.logStatement([{ofs: 1915, row: 63, col: 25}, {ofs: 1927, row: 63, col: 37}], _aether._userInfo, false);\n tmp266 = i;\n _aether.logStatementStart([{ofs: 1915, row: 63, col: 25}, {ofs: 1930, row: 63, col: 40}]); tmp264 = tmp265[tmp266]; _aether.logStatement([{ofs: 1915, row: 63, col: 25}, {ofs: 1930, row: 63, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1901, row: 63, col: 11}, {ofs: 1931, row: 63, col: 41}]); tmp260 = _aether.createAPIClone(_aether, tmp262[tmp263](_aether.restoreAPIClone(_aether, tmp264))); _aether.logStatement([{ofs: 1901, row: 63, col: 11}, {ofs: 1931, row: 63, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1935, row: 63, col: 45}, {ofs: 1937, row: 63, col: 47}]); tmp261 = 30; _aether.logStatement([{ofs: 1935, row: 63, col: 45}, {ofs: 1937, row: 63, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1901, row: 63, col: 11}, {ofs: 1937, row: 63, col: 47}]); tmp259 = tmp260 <= tmp261; _aether.logStatement([{ofs: 1901, row: 63, col: 11}, {ofs: 1937, row: 63, col: 47}], _aether._userInfo, false);\n if (tmp259) {\n _aether.logStatementStart([{ofs: 1953, row: 64, col: 12}, {ofs: 1964, row: 64, col: 23}]); tmp269 = 1; _aether.logStatement([{ofs: 1953, row: 64, col: 12}, {ofs: 1964, row: 64, col: 23}], _aether._userInfo, false);\n tmp270 = count;\n tmp271 = tmp269;\n count = tmp270 + tmp271;\n } else {\n ;\n }\n }\n tmp255 = i;\n tmp256 = 1;\n i = tmp255 + tmp256;\n tmp249 = i;\n tmp253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp254 = 'enemies';\n _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}]); tmp251 = tmp253[tmp254]; _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}], _aether._userInfo, false);\n tmp252 = 'length';\n _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}]); tmp250 = tmp251[tmp252]; _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}]); tmp242 = tmp249 < tmp250; _aether.logStatement([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n }\n }\n tmp272 = count;\n return _aether.restoreAPIClone(_aether, tmp272);\n }; _aether.logStatement([{ofs: 1782, row: 59, col: 0}, {ofs: 2001, row: 68, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1782, row: 59, col: 0}, {ofs: 2000, row: 68, col: 1}]); tmp239[tmp240] = tmp241; _aether.logStatement([{ofs: 1782, row: 59, col: 0}, {ofs: 2000, row: 68, col: 1}], _aether._userInfo, false);\n tmp273 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp274 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 2003, row: 70, col: 0}, {ofs: 2716, row: 88, col: 2}]); tmp275 = function () {\n var tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp279 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp280 = 'distance';\n tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp283 = 'enemyBase';\n _aether.logStatementStart([{ofs: 2331, row: 77, col: 21}, {ofs: 2345, row: 77, col: 35}]); tmp281 = tmp282[tmp283]; _aether.logStatement([{ofs: 2331, row: 77, col: 21}, {ofs: 2345, row: 77, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2317, row: 77, col: 7}, {ofs: 2346, row: 77, col: 36}]); tmp277 = _aether.createAPIClone(_aether, tmp279[tmp280](_aether.restoreAPIClone(_aether, tmp281))); _aether.logStatement([{ofs: 2317, row: 77, col: 7}, {ofs: 2346, row: 77, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2350, row: 77, col: 40}, {ofs: 2352, row: 77, col: 42}]); tmp278 = 30; _aether.logStatement([{ofs: 2350, row: 77, col: 40}, {ofs: 2352, row: 77, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2317, row: 77, col: 7}, {ofs: 2352, row: 77, col: 42}]); tmp276 = tmp277 >= tmp278; _aether.logStatement([{ofs: 2317, row: 77, col: 7}, {ofs: 2352, row: 77, col: 42}], _aether._userInfo, false);\n if (tmp276) {\n tmp284 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp285 = 'say';\n _aether.logStatementStart([{ofs: 2373, row: 78, col: 17}, {ofs: 2385, row: 78, col: 29}]); tmp286 = 'follow me!'; _aether.logStatement([{ofs: 2373, row: 78, col: 17}, {ofs: 2385, row: 78, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2364, row: 78, col: 8}, {ofs: 2386, row: 78, col: 30}]); tmp287 = _aether.createAPIClone(_aether, tmp284[tmp285](_aether.restoreAPIClone(_aether, tmp286))); _aether.logStatement([{ofs: 2364, row: 78, col: 8}, {ofs: 2386, row: 78, col: 30}], _aether._userInfo, false);\n tmp288 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp289 = 'move';\n tmp297 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp298 = 'enemyBase';\n _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2424, row: 79, col: 36}]); tmp295 = tmp297[tmp298]; _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2424, row: 79, col: 36}], _aether._userInfo, false);\n tmp296 = 'pos';\n _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2428, row: 79, col: 40}]); tmp293 = tmp295[tmp296]; _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2428, row: 79, col: 40}], _aether._userInfo, false);\n tmp294 = 'x';\n _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2430, row: 79, col: 42}]); tmp291 = tmp293[tmp294]; _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2430, row: 79, col: 42}], _aether._userInfo, false);\n tmp303 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp304 = 'enemyBase';\n _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2449, row: 79, col: 61}]); tmp301 = tmp303[tmp304]; _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2449, row: 79, col: 61}], _aether._userInfo, false);\n tmp302 = 'pos';\n _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2453, row: 79, col: 65}]); tmp299 = tmp301[tmp302]; _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2453, row: 79, col: 65}], _aether._userInfo, false);\n tmp300 = 'y';\n _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2455, row: 79, col: 67}]); tmp292 = tmp299[tmp300]; _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2455, row: 79, col: 67}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2406, row: 79, col: 18}, {ofs: 2456, row: 79, col: 68}]); tmp290 = {\n x: tmp291,\n y: tmp292\n }; _aether.logStatement([{ofs: 2406, row: 79, col: 18}, {ofs: 2456, row: 79, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2396, row: 79, col: 8}, {ofs: 2457, row: 79, col: 69}]); tmp305 = _aether.createAPIClone(_aether, tmp288[tmp289](_aether.restoreAPIClone(_aether, tmp290))); _aether.logStatement([{ofs: 2396, row: 79, col: 8}, {ofs: 2457, row: 79, col: 69}], _aether._userInfo, false);\n } else {\n tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp307 = 'say';\n _aether.logStatementStart([{ofs: 2493, row: 82, col: 17}, {ofs: 2502, row: 82, col: 26}]); tmp308 = 'Attack!'; _aether.logStatement([{ofs: 2493, row: 82, col: 17}, {ofs: 2502, row: 82, col: 26}], _aether._userInfo, false);\n tmp313 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp314 = 'enemies';\n _aether.logStatementStart([{ofs: 2513, row: 82, col: 37}, {ofs: 2525, row: 82, col: 49}]); tmp311 = tmp313[tmp314]; _aether.logStatement([{ofs: 2513, row: 82, col: 37}, {ofs: 2525, row: 82, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2526, row: 82, col: 50}, {ofs: 2527, row: 82, col: 51}]); tmp312 = 0; _aether.logStatement([{ofs: 2526, row: 82, col: 50}, {ofs: 2527, row: 82, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2513, row: 82, col: 37}, {ofs: 2528, row: 82, col: 52}]); tmp310 = tmp311[tmp312]; _aether.logStatement([{ofs: 2513, row: 82, col: 37}, {ofs: 2528, row: 82, col: 52}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2504, row: 82, col: 28}, {ofs: 2529, row: 82, col: 53}]); tmp309 = { target: tmp310 }; _aether.logStatement([{ofs: 2504, row: 82, col: 28}, {ofs: 2529, row: 82, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2484, row: 82, col: 8}, {ofs: 2530, row: 82, col: 54}]); tmp315 = _aether.createAPIClone(_aether, tmp306[tmp307](_aether.restoreAPIClone(_aether, tmp308), _aether.restoreAPIClone(_aether, tmp309))); _aether.logStatement([{ofs: 2484, row: 82, col: 8}, {ofs: 2530, row: 82, col: 54}], _aether._userInfo, false);\n tmp316 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp317 = 'attack';\n tmp321 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp322 = 'enemies';\n _aether.logStatementStart([{ofs: 2552, row: 83, col: 20}, {ofs: 2564, row: 83, col: 32}]); tmp319 = tmp321[tmp322]; _aether.logStatement([{ofs: 2552, row: 83, col: 20}, {ofs: 2564, row: 83, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2565, row: 83, col: 33}, {ofs: 2566, row: 83, col: 34}]); tmp320 = 0; _aether.logStatement([{ofs: 2565, row: 83, col: 33}, {ofs: 2566, row: 83, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2552, row: 83, col: 20}, {ofs: 2567, row: 83, col: 35}]); tmp318 = tmp319[tmp320]; _aether.logStatement([{ofs: 2552, row: 83, col: 20}, {ofs: 2567, row: 83, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2540, row: 83, col: 8}, {ofs: 2568, row: 83, col: 36}]); tmp323 = _aether.createAPIClone(_aether, tmp316[tmp317](_aether.restoreAPIClone(_aether, tmp318))); _aether.logStatement([{ofs: 2540, row: 83, col: 8}, {ofs: 2568, row: 83, col: 36}], _aether._userInfo, false);\n }\n return;\n }; _aether.logStatement([{ofs: 2003, row: 70, col: 0}, {ofs: 2716, row: 88, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2003, row: 70, col: 0}, {ofs: 2715, row: 88, col: 1}]); tmp273[tmp274] = tmp275; _aether.logStatement([{ofs: 2003, row: 70, col: 0}, {ofs: 2715, row: 88, col: 1}], _aether._userInfo, false);\n tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp325 = 'recalculateBaseRace';\n _aether.logStatementStart([{ofs: 2718, row: 90, col: 0}, {ofs: 3302, row: 108, col: 2}]); tmp326 = function () {\n var count, i, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp336, tmp337, tmp338, tmp339, tmp340, tmp341, tmp344, tmp345, tmp346, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370, tmp371, tmp372, tmp373, tmp374, tmp375; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 2957, row: 96, col: 4}, {ofs: 2971, row: 96, col: 18}]); count = 0; _aether.logStatement([{ofs: 2957, row: 96, col: 4}, {ofs: 2971, row: 96, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2980, row: 97, col: 8}, {ofs: 2989, row: 97, col: 17}]); i = 1; _aether.logStatement([{ofs: 2980, row: 97, col: 8}, {ofs: 2989, row: 97, col: 17}], _aether._userInfo, false);\n tmp328 = i;\n tmp332 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp333 = 'enemies';\n _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}]); tmp330 = tmp332[tmp333]; _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}], _aether._userInfo, false);\n tmp331 = 'length';\n _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}]); tmp329 = tmp330[tmp331]; _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}]); tmp327 = tmp328 < tmp329; _aether.logStatement([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n tmp342: {\n while (tmp327) {\n tmp343: {\n tmp350 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp351 = 'enemies';\n _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3046, row: 98, col: 23}]); tmp348 = tmp350[tmp351]; _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3046, row: 98, col: 23}], _aether._userInfo, false);\n tmp349 = i;\n _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3049, row: 98, col: 26}]); tmp346 = tmp348[tmp349]; _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3049, row: 98, col: 26}], _aether._userInfo, false);\n tmp347 = 'target';\n _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3056, row: 98, col: 33}]); tmp345 = tmp346[tmp347]; _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3056, row: 98, col: 33}], _aether._userInfo, false);\n if (tmp345) {\n tmp360 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp361 = 'enemies';\n _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3072, row: 98, col: 49}]); tmp358 = tmp360[tmp361]; _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3072, row: 98, col: 49}], _aether._userInfo, false);\n tmp359 = i;\n _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3075, row: 98, col: 52}]); tmp356 = tmp358[tmp359]; _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3075, row: 98, col: 52}], _aether._userInfo, false);\n tmp357 = 'target';\n _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3082, row: 98, col: 59}]); tmp354 = tmp356[tmp357]; _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3082, row: 98, col: 59}], _aether._userInfo, false);\n tmp355 = 'type';\n _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3087, row: 98, col: 64}]); tmp352 = tmp354[tmp355]; _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3087, row: 98, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3092, row: 98, col: 69}, {ofs: 3098, row: 98, col: 75}]); tmp353 = 'base'; _aether.logStatement([{ofs: 3092, row: 98, col: 69}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3098, row: 98, col: 75}]); tmp344 = tmp352 === tmp353; _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3098, row: 98, col: 75}]); tmp344 = tmp345; _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n }\n if (tmp344) {\n _aether.logStatementStart([{ofs: 3114, row: 99, col: 12}, {ofs: 3125, row: 99, col: 23}]); tmp362 = 1; _aether.logStatement([{ofs: 3114, row: 99, col: 12}, {ofs: 3125, row: 99, col: 23}], _aether._userInfo, false);\n tmp363 = count;\n tmp364 = tmp362;\n count = tmp363 + tmp364;\n } else {\n ;\n }\n }\n tmp340 = i;\n tmp341 = 1;\n i = tmp340 + tmp341;\n tmp334 = i;\n tmp338 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp339 = 'enemies';\n _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}]); tmp336 = tmp338[tmp339]; _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}], _aether._userInfo, false);\n tmp337 = 'length';\n _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}]); tmp335 = tmp336[tmp337]; _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}]); tmp327 = tmp334 < tmp335; _aether.logStatement([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n }\n }\n tmp366 = count;\n tmp372 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp373 = 'enemies';\n _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3239, row: 104, col: 29}]); tmp370 = tmp372[tmp373]; _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3239, row: 104, col: 29}], _aether._userInfo, false);\n tmp371 = 'length';\n _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3246, row: 104, col: 36}]); tmp368 = tmp370[tmp371]; _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3246, row: 104, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3249, row: 104, col: 39}, {ofs: 3250, row: 104, col: 40}]); tmp369 = 1; _aether.logStatement([{ofs: 3249, row: 104, col: 39}, {ofs: 3250, row: 104, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3250, row: 104, col: 40}]); tmp367 = tmp368 - tmp369; _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3250, row: 104, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3217, row: 104, col: 7}, {ofs: 3251, row: 104, col: 41}]); tmp365 = tmp366 >= tmp367; _aether.logStatement([{ofs: 3217, row: 104, col: 7}, {ofs: 3251, row: 104, col: 41}], _aether._userInfo, false);\n if (tmp365) {\n _aether.logStatementStart([{ofs: 3270, row: 105, col: 15}, {ofs: 3274, row: 105, col: 19}]); tmp374 = true; _aether.logStatement([{ofs: 3270, row: 105, col: 15}, {ofs: 3274, row: 105, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp374);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 3293, row: 107, col: 11}, {ofs: 3298, row: 107, col: 16}]); tmp375 = false; _aether.logStatement([{ofs: 3293, row: 107, col: 11}, {ofs: 3298, row: 107, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp375);\n }; _aether.logStatement([{ofs: 2718, row: 90, col: 0}, {ofs: 3302, row: 108, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 2718, row: 90, col: 0}, {ofs: 3301, row: 108, col: 1}]); tmp324[tmp325] = tmp326; _aether.logStatement([{ofs: 2718, row: 90, col: 0}, {ofs: 3301, row: 108, col: 1}], _aether._userInfo, false);\n tmp376 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp377 = 'isOpponentHeroRushing';\n _aether.logStatementStart([{ofs: 3304, row: 110, col: 0}, {ofs: 3639, row: 123, col: 2}]); tmp378 = function () {\n var count, i, tmp379, tmp380, tmp381, tmp382, tmp383, tmp384, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392, tmp393, tmp396, tmp397, tmp398, tmp399, tmp400, tmp401, tmp402, tmp403, tmp404, tmp405, tmp406, tmp407, tmp408, tmp409, tmp410, tmp411, tmp412, tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419, tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 3355, row: 112, col: 4}, {ofs: 3369, row: 112, col: 18}]); count = 0; _aether.logStatement([{ofs: 3355, row: 112, col: 4}, {ofs: 3369, row: 112, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3378, row: 113, col: 8}, {ofs: 3387, row: 113, col: 17}]); i = 1; _aether.logStatement([{ofs: 3378, row: 113, col: 8}, {ofs: 3387, row: 113, col: 17}], _aether._userInfo, false);\n tmp380 = i;\n tmp384 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp385 = 'enemies';\n _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}]); tmp382 = tmp384[tmp385]; _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}], _aether._userInfo, false);\n tmp383 = 'length';\n _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}]); tmp381 = tmp382[tmp383]; _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}]); tmp379 = tmp380 < tmp381; _aether.logStatement([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n tmp394: {\n while (tmp379) {\n tmp395: {\n tmp402 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp403 = 'enemies';\n _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3444, row: 114, col: 23}]); tmp400 = tmp402[tmp403]; _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3444, row: 114, col: 23}], _aether._userInfo, false);\n tmp401 = i;\n _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3447, row: 114, col: 26}]); tmp398 = tmp400[tmp401]; _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3447, row: 114, col: 26}], _aether._userInfo, false);\n tmp399 = 'target';\n _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3454, row: 114, col: 33}]); tmp397 = tmp398[tmp399]; _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3454, row: 114, col: 33}], _aether._userInfo, false);\n if (tmp397) {\n tmp412 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp413 = 'enemies';\n _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3470, row: 114, col: 49}]); tmp410 = tmp412[tmp413]; _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3470, row: 114, col: 49}], _aether._userInfo, false);\n tmp411 = i;\n _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3473, row: 114, col: 52}]); tmp408 = tmp410[tmp411]; _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3473, row: 114, col: 52}], _aether._userInfo, false);\n tmp409 = 'target';\n _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3480, row: 114, col: 59}]); tmp406 = tmp408[tmp409]; _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3480, row: 114, col: 59}], _aether._userInfo, false);\n tmp407 = 'type';\n _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3485, row: 114, col: 64}]); tmp404 = tmp406[tmp407]; _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3485, row: 114, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3490, row: 114, col: 69}, {ofs: 3498, row: 114, col: 77}]); tmp405 = 'knight'; _aether.logStatement([{ofs: 3490, row: 114, col: 69}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3498, row: 114, col: 77}]); tmp396 = tmp404 === tmp405; _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3498, row: 114, col: 77}]); tmp396 = tmp397; _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n }\n if (tmp396) {\n _aether.logStatementStart([{ofs: 3514, row: 115, col: 12}, {ofs: 3525, row: 115, col: 23}]); tmp414 = 1; _aether.logStatement([{ofs: 3514, row: 115, col: 12}, {ofs: 3525, row: 115, col: 23}], _aether._userInfo, false);\n tmp415 = count;\n tmp416 = tmp414;\n count = tmp415 + tmp416;\n } else {\n ;\n }\n }\n tmp392 = i;\n tmp393 = 1;\n i = tmp392 + tmp393;\n tmp386 = i;\n tmp390 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp391 = 'enemies';\n _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}]); tmp388 = tmp390[tmp391]; _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}], _aether._userInfo, false);\n tmp389 = 'length';\n _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}]); tmp387 = tmp388[tmp389]; _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}]); tmp379 = tmp386 < tmp387; _aether.logStatement([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n }\n }\n tmp418 = count;\n tmp424 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp425 = 'enemies';\n _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3576, row: 119, col: 29}]); tmp422 = tmp424[tmp425]; _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3576, row: 119, col: 29}], _aether._userInfo, false);\n tmp423 = 'length';\n _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3583, row: 119, col: 36}]); tmp420 = tmp422[tmp423]; _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3583, row: 119, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3586, row: 119, col: 39}, {ofs: 3587, row: 119, col: 40}]); tmp421 = 1; _aether.logStatement([{ofs: 3586, row: 119, col: 39}, {ofs: 3587, row: 119, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3587, row: 119, col: 40}]); tmp419 = tmp420 - tmp421; _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3587, row: 119, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3554, row: 119, col: 7}, {ofs: 3588, row: 119, col: 41}]); tmp417 = tmp418 == tmp419; _aether.logStatement([{ofs: 3554, row: 119, col: 7}, {ofs: 3588, row: 119, col: 41}], _aether._userInfo, false);\n if (tmp417) {\n _aether.logStatementStart([{ofs: 3607, row: 120, col: 15}, {ofs: 3611, row: 120, col: 19}]); tmp426 = true; _aether.logStatement([{ofs: 3607, row: 120, col: 15}, {ofs: 3611, row: 120, col: 19}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp426);\n } else {\n ;\n }\n _aether.logStatementStart([{ofs: 3630, row: 122, col: 11}, {ofs: 3635, row: 122, col: 16}]); tmp427 = false; _aether.logStatement([{ofs: 3630, row: 122, col: 11}, {ofs: 3635, row: 122, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp427);\n }; _aether.logStatement([{ofs: 3304, row: 110, col: 0}, {ofs: 3639, row: 123, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3304, row: 110, col: 0}, {ofs: 3638, row: 123, col: 1}]); tmp376[tmp377] = tmp378; _aether.logStatement([{ofs: 3304, row: 110, col: 0}, {ofs: 3638, row: 123, col: 1}], _aether._userInfo, false);\n tmp428 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp429 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 3641, row: 125, col: 0}, {ofs: 4238, row: 149, col: 2}]); tmp430 = function () {\n var ranged, melee, i, tmp431, tmp432, tmp433, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440, tmp441, tmp442, tmp443, tmp444, tmp445, tmp448, tmp449, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485, tmp486, tmp487, tmp488, tmp489, tmp490, tmp491, tmp492, tmp493; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 3746, row: 129, col: 4}, {ofs: 3761, row: 129, col: 19}]); ranged = 0; _aether.logStatement([{ofs: 3746, row: 129, col: 4}, {ofs: 3761, row: 129, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3766, row: 130, col: 4}, {ofs: 3780, row: 130, col: 18}]); melee = 0; _aether.logStatement([{ofs: 3766, row: 130, col: 4}, {ofs: 3780, row: 130, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3789, row: 131, col: 8}, {ofs: 3798, row: 131, col: 17}]); i = 2; _aether.logStatement([{ofs: 3789, row: 131, col: 8}, {ofs: 3798, row: 131, col: 17}], _aether._userInfo, false);\n tmp432 = i;\n tmp436 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp437 = 'enemies';\n _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}]); tmp434 = tmp436[tmp437]; _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}], _aether._userInfo, false);\n tmp435 = 'length';\n _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}]); tmp433 = tmp434[tmp435]; _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}]); tmp431 = tmp432 < tmp433; _aether.logStatement([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n tmp446: {\n while (tmp431) {\n tmp447: {\n tmp455 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp456 = 'enemies';\n _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3855, row: 132, col: 23}]); tmp453 = tmp455[tmp456]; _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3855, row: 132, col: 23}], _aether._userInfo, false);\n tmp454 = i;\n _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3858, row: 132, col: 26}]); tmp451 = tmp453[tmp454]; _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3858, row: 132, col: 26}], _aether._userInfo, false);\n tmp452 = 'type';\n _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3863, row: 132, col: 31}]); tmp449 = tmp451[tmp452]; _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3863, row: 132, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3868, row: 132, col: 36}, {ofs: 3877, row: 132, col: 45}]); tmp450 = 'thrower'; _aether.logStatement([{ofs: 3868, row: 132, col: 36}, {ofs: 3877, row: 132, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3877, row: 132, col: 45}]); tmp448 = tmp449 === tmp450; _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3877, row: 132, col: 45}], _aether._userInfo, false);\n if (tmp448) {\n _aether.logStatementStart([{ofs: 3893, row: 133, col: 12}, {ofs: 3905, row: 133, col: 24}]); tmp457 = 1; _aether.logStatement([{ofs: 3893, row: 133, col: 12}, {ofs: 3905, row: 133, col: 24}], _aether._userInfo, false);\n tmp458 = ranged;\n tmp459 = tmp457;\n ranged = tmp458 + tmp459;\n } else {\n tmp467 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp468 = 'enemies';\n _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3944, row: 135, col: 28}]); tmp465 = tmp467[tmp468]; _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3944, row: 135, col: 28}], _aether._userInfo, false);\n tmp466 = i;\n _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3947, row: 135, col: 31}]); tmp463 = tmp465[tmp466]; _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3947, row: 135, col: 31}], _aether._userInfo, false);\n tmp464 = 'type';\n _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3952, row: 135, col: 36}]); tmp461 = tmp463[tmp464]; _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3952, row: 135, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3957, row: 135, col: 41}, {ofs: 3967, row: 135, col: 51}]); tmp462 = 'munchkin'; _aether.logStatement([{ofs: 3957, row: 135, col: 41}, {ofs: 3967, row: 135, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3967, row: 135, col: 51}]); tmp460 = tmp461 === tmp462; _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3967, row: 135, col: 51}], _aether._userInfo, false);\n if (tmp460) {\n _aether.logStatementStart([{ofs: 3983, row: 136, col: 12}, {ofs: 3994, row: 136, col: 23}]); tmp469 = 1; _aether.logStatement([{ofs: 3983, row: 136, col: 12}, {ofs: 3994, row: 136, col: 23}], _aether._userInfo, false);\n tmp470 = melee;\n tmp471 = tmp469;\n melee = tmp470 + tmp471;\n } else {\n ;\n }\n }\n }\n tmp444 = i;\n tmp445 = 1;\n i = tmp444 + tmp445;\n tmp438 = i;\n tmp442 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp443 = 'enemies';\n _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}]); tmp440 = tmp442[tmp443]; _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}], _aether._userInfo, false);\n tmp441 = 'length';\n _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}]); tmp439 = tmp440[tmp441]; _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}]); tmp431 = tmp438 < tmp439; _aether.logStatement([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n }\n }\n tmp474 = melee;\n _aether.logStatementStart([{ofs: 4026, row: 139, col: 15}, {ofs: 4027, row: 139, col: 16}]); tmp475 = 0; _aether.logStatement([{ofs: 4026, row: 139, col: 15}, {ofs: 4027, row: 139, col: 16}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4018, row: 139, col: 7}, {ofs: 4027, row: 139, col: 16}]); tmp473 = tmp474 > tmp475; _aether.logStatement([{ofs: 4018, row: 139, col: 7}, {ofs: 4027, row: 139, col: 16}], _aether._userInfo, false);\n if (tmp473) {\n tmp476 = ranged;\n _aether.logStatementStart([{ofs: 4042, row: 139, col: 31}, {ofs: 4043, row: 139, col: 32}]); tmp477 = 0; _aether.logStatement([{ofs: 4042, row: 139, col: 31}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4031, row: 139, col: 20}, {ofs: 4043, row: 139, col: 32}]); tmp472 = tmp476 === tmp477; _aether.logStatement([{ofs: 4031, row: 139, col: 20}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4018, row: 139, col: 7}, {ofs: 4043, row: 139, col: 32}]); tmp472 = tmp473; _aether.logStatement([{ofs: 4018, row: 139, col: 7}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n }\n if (tmp472) {\n _aether.logStatementStart([{ofs: 4062, row: 140, col: 15}, {ofs: 4063, row: 140, col: 16}]); tmp478 = 1; _aether.logStatement([{ofs: 4062, row: 140, col: 15}, {ofs: 4063, row: 140, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp478);\n } else {\n tmp481 = ranged;\n _aether.logStatementStart([{ofs: 4092, row: 142, col: 21}, {ofs: 4093, row: 142, col: 22}]); tmp482 = 0; _aether.logStatement([{ofs: 4092, row: 142, col: 21}, {ofs: 4093, row: 142, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4083, row: 142, col: 12}, {ofs: 4093, row: 142, col: 22}]); tmp480 = tmp481 > tmp482; _aether.logStatement([{ofs: 4083, row: 142, col: 12}, {ofs: 4093, row: 142, col: 22}], _aether._userInfo, false);\n if (tmp480) {\n tmp483 = melee;\n _aether.logStatementStart([{ofs: 4107, row: 142, col: 36}, {ofs: 4108, row: 142, col: 37}]); tmp484 = 0; _aether.logStatement([{ofs: 4107, row: 142, col: 36}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4097, row: 142, col: 26}, {ofs: 4108, row: 142, col: 37}]); tmp479 = tmp483 === tmp484; _aether.logStatement([{ofs: 4097, row: 142, col: 26}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4083, row: 142, col: 12}, {ofs: 4108, row: 142, col: 37}]); tmp479 = tmp480; _aether.logStatement([{ofs: 4083, row: 142, col: 12}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n }\n if (tmp479) {\n _aether.logStatementStart([{ofs: 4127, row: 143, col: 15}, {ofs: 4128, row: 143, col: 16}]); tmp485 = 2; _aether.logStatement([{ofs: 4127, row: 143, col: 15}, {ofs: 4128, row: 143, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp485);\n } else {\n tmp488 = ranged;\n _aether.logStatementStart([{ofs: 4157, row: 145, col: 21}, {ofs: 4158, row: 145, col: 22}]); tmp489 = 0; _aether.logStatement([{ofs: 4157, row: 145, col: 21}, {ofs: 4158, row: 145, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4148, row: 145, col: 12}, {ofs: 4158, row: 145, col: 22}]); tmp487 = tmp488 > tmp489; _aether.logStatement([{ofs: 4148, row: 145, col: 12}, {ofs: 4158, row: 145, col: 22}], _aether._userInfo, false);\n if (tmp487) {\n tmp490 = melee;\n _aether.logStatementStart([{ofs: 4170, row: 145, col: 34}, {ofs: 4171, row: 145, col: 35}]); tmp491 = 0; _aether.logStatement([{ofs: 4170, row: 145, col: 34}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4162, row: 145, col: 26}, {ofs: 4171, row: 145, col: 35}]); tmp486 = tmp490 > tmp491; _aether.logStatement([{ofs: 4162, row: 145, col: 26}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 4148, row: 145, col: 12}, {ofs: 4171, row: 145, col: 35}]); tmp486 = tmp487; _aether.logStatement([{ofs: 4148, row: 145, col: 12}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n }\n if (tmp486) {\n _aether.logStatementStart([{ofs: 4190, row: 146, col: 15}, {ofs: 4191, row: 146, col: 16}]); tmp492 = 3; _aether.logStatement([{ofs: 4190, row: 146, col: 15}, {ofs: 4191, row: 146, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp492);\n } else {\n ;\n }\n }\n }\n _aether.logStatementStart([{ofs: 4210, row: 148, col: 11}, {ofs: 4211, row: 148, col: 12}]); tmp493 = 0; _aether.logStatement([{ofs: 4210, row: 148, col: 11}, {ofs: 4211, row: 148, col: 12}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp493);\n }; _aether.logStatement([{ofs: 3641, row: 125, col: 0}, {ofs: 4238, row: 149, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 3641, row: 125, col: 0}, {ofs: 4237, row: 149, col: 1}]); tmp428[tmp429] = tmp430; _aether.logStatement([{ofs: 3641, row: 125, col: 0}, {ofs: 4237, row: 149, col: 1}], _aether._userInfo, false);\n tmp494 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp495 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 4240, row: 151, col: 0}, {ofs: 5566, row: 200, col: 2}]); tmp496 = function () {\n var tharin, base, other, i, tmp497, tmp498, tmp499, tmp500, tmp501, tmp502, tmp503, tmp504, tmp505, tmp506, tmp507, tmp508, tmp509, tmp510, tmp511, tmp512, tmp513, tmp514, tmp515, tmp516, tmp517, tmp518, tmp519, tmp520, tmp521, tmp524, tmp525, tmp526, tmp527, tmp528, tmp529, tmp530, tmp531, tmp532, tmp533, tmp534, tmp535, tmp536, tmp537, tmp538, tmp539, tmp540, tmp541, tmp542, tmp543, tmp544, tmp545, tmp546, tmp547, tmp548, tmp549, tmp550, tmp551, tmp552, tmp553, tmp554, tmp555, tmp556, tmp557, tmp558, tmp559, tmp560, tmp561, tmp562, tmp563, tmp564, tmp565, tmp566, tmp567, tmp568, tmp569, tmp570, tmp571, tmp572, tmp573, tmp574, tmp575, tmp576, tmp577, tmp578, tmp579, tmp580, tmp581, tmp582, tmp583, tmp584, tmp585, tmp586, tmp587, tmp588, tmp589, tmp590, tmp591, tmp592, tmp593, tmp594, tmp595, tmp596, tmp597, tmp598, tmp599, tmp600, tmp601, tmp602, tmp603, tmp604, tmp605, tmp606, tmp607, tmp608, tmp609, tmp610, tmp611, tmp612, tmp613, tmp614, tmp615, tmp616, tmp617, tmp618, tmp619, tmp620, tmp621, tmp622; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 4421, row: 157, col: 4}, {ofs: 4436, row: 157, col: 19}]); tharin = 0; _aether.logStatement([{ofs: 4421, row: 157, col: 4}, {ofs: 4436, row: 157, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4441, row: 158, col: 4}, {ofs: 4454, row: 158, col: 17}]); base = 0; _aether.logStatement([{ofs: 4441, row: 158, col: 4}, {ofs: 4454, row: 158, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4459, row: 159, col: 4}, {ofs: 4473, row: 159, col: 18}]); other = 0; _aether.logStatement([{ofs: 4459, row: 159, col: 4}, {ofs: 4473, row: 159, col: 18}], _aether._userInfo, false);\n tmp497 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp498 = 'terrifyCooldown';\n _aether.logStatementStart([{ofs: 4522, row: 162, col: 4}, {ofs: 4550, row: 162, col: 32}]); tmp499 = true; _aether.logStatement([{ofs: 4522, row: 162, col: 4}, {ofs: 4550, row: 162, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4522, row: 162, col: 4}, {ofs: 4549, row: 162, col: 31}]); tmp497[tmp498] = tmp499; _aether.logStatement([{ofs: 4522, row: 162, col: 4}, {ofs: 4549, row: 162, col: 31}], _aether._userInfo, false);\n tmp500 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp501 = 'terrifyUnitCount';\n tmp505 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp506 = 'enemies';\n _aether.logStatementStart([{ofs: 4579, row: 163, col: 28}, {ofs: 4591, row: 163, col: 40}]); tmp503 = tmp505[tmp506]; _aether.logStatement([{ofs: 4579, row: 163, col: 28}, {ofs: 4591, row: 163, col: 40}], _aether._userInfo, false);\n tmp504 = 'length';\n _aether.logStatementStart([{ofs: 4555, row: 163, col: 4}, {ofs: 4599, row: 163, col: 48}]); tmp502 = tmp503[tmp504]; _aether.logStatement([{ofs: 4555, row: 163, col: 4}, {ofs: 4599, row: 163, col: 48}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4555, row: 163, col: 4}, {ofs: 4598, row: 163, col: 47}]); tmp500[tmp501] = tmp502; _aether.logStatement([{ofs: 4555, row: 163, col: 4}, {ofs: 4598, row: 163, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4609, row: 165, col: 8}, {ofs: 4618, row: 165, col: 17}]); i = 0; _aether.logStatement([{ofs: 4609, row: 165, col: 8}, {ofs: 4618, row: 165, col: 17}], _aether._userInfo, false);\n tmp508 = i;\n tmp512 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp513 = 'enemies';\n _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}]); tmp510 = tmp512[tmp513]; _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}], _aether._userInfo, false);\n tmp511 = 'length';\n _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}]); tmp509 = tmp510[tmp511]; _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}]); tmp507 = tmp508 < tmp509; _aether.logStatement([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n tmp522: {\n while (tmp507) {\n tmp523: {\n tmp529 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp530 = 'enemies';\n _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4675, row: 166, col: 23}]); tmp527 = tmp529[tmp530]; _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4675, row: 166, col: 23}], _aether._userInfo, false);\n tmp528 = i;\n _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4678, row: 166, col: 26}]); tmp525 = tmp527[tmp528]; _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4678, row: 166, col: 26}], _aether._userInfo, false);\n tmp526 = 'target';\n _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4685, row: 166, col: 33}]); tmp524 = tmp525[tmp526]; _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4685, row: 166, col: 33}], _aether._userInfo, false);\n if (tmp524) {\n tmp540 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp541 = 'enemies';\n _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4716, row: 167, col: 27}]); tmp538 = tmp540[tmp541]; _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4716, row: 167, col: 27}], _aether._userInfo, false);\n tmp539 = i;\n _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4719, row: 167, col: 30}]); tmp536 = tmp538[tmp539]; _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4719, row: 167, col: 30}], _aether._userInfo, false);\n tmp537 = 'target';\n _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4726, row: 167, col: 37}]); tmp534 = tmp536[tmp537]; _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4726, row: 167, col: 37}], _aether._userInfo, false);\n tmp535 = 'type';\n _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4731, row: 167, col: 42}]); tmp532 = tmp534[tmp535]; _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4731, row: 167, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4736, row: 167, col: 47}, {ofs: 4744, row: 167, col: 55}]); tmp533 = 'knight'; _aether.logStatement([{ofs: 4736, row: 167, col: 47}, {ofs: 4744, row: 167, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4744, row: 167, col: 55}]); tmp531 = tmp532 === tmp533; _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4744, row: 167, col: 55}], _aether._userInfo, false);\n if (tmp531) {\n _aether.logStatementStart([{ofs: 4764, row: 168, col: 16}, {ofs: 4776, row: 168, col: 28}]); tmp542 = 1; _aether.logStatement([{ofs: 4764, row: 168, col: 16}, {ofs: 4776, row: 168, col: 28}], _aether._userInfo, false);\n tmp543 = tharin;\n tmp544 = tmp542;\n tharin = tmp543 + tmp544;\n } else {\n tmp554 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp555 = 'enemies';\n _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4823, row: 170, col: 32}]); tmp552 = tmp554[tmp555]; _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4823, row: 170, col: 32}], _aether._userInfo, false);\n tmp553 = i;\n _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4826, row: 170, col: 35}]); tmp550 = tmp552[tmp553]; _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4826, row: 170, col: 35}], _aether._userInfo, false);\n tmp551 = 'target';\n _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4833, row: 170, col: 42}]); tmp548 = tmp550[tmp551]; _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4833, row: 170, col: 42}], _aether._userInfo, false);\n tmp549 = 'type';\n _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4838, row: 170, col: 47}]); tmp546 = tmp548[tmp549]; _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4838, row: 170, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4843, row: 170, col: 52}, {ofs: 4849, row: 170, col: 58}]); tmp547 = 'base'; _aether.logStatement([{ofs: 4843, row: 170, col: 52}, {ofs: 4849, row: 170, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4849, row: 170, col: 58}]); tmp545 = tmp546 === tmp547; _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4849, row: 170, col: 58}], _aether._userInfo, false);\n if (tmp545) {\n _aether.logStatementStart([{ofs: 4869, row: 171, col: 16}, {ofs: 4879, row: 171, col: 26}]); tmp556 = 1; _aether.logStatement([{ofs: 4869, row: 171, col: 16}, {ofs: 4879, row: 171, col: 26}], _aether._userInfo, false);\n tmp557 = base;\n tmp558 = tmp556;\n base = tmp557 + tmp558;\n } else {\n _aether.logStatementStart([{ofs: 4929, row: 174, col: 16}, {ofs: 4940, row: 174, col: 27}]); tmp559 = 1; _aether.logStatement([{ofs: 4929, row: 174, col: 16}, {ofs: 4940, row: 174, col: 27}], _aether._userInfo, false);\n tmp560 = other;\n tmp561 = tmp559;\n other = tmp560 + tmp561;\n }\n }\n } else {\n tmp567 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp568 = 'enemies';\n _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 4993, row: 177, col: 28}]); tmp565 = tmp567[tmp568]; _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 4993, row: 177, col: 28}], _aether._userInfo, false);\n tmp566 = i;\n _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 4996, row: 177, col: 31}]); tmp563 = tmp565[tmp566]; _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 4996, row: 177, col: 31}], _aether._userInfo, false);\n tmp564 = 'action';\n _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 5003, row: 177, col: 38}]); tmp562 = tmp563[tmp564]; _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 5003, row: 177, col: 38}], _aether._userInfo, false);\n if (tmp562) {\n _aether.logStatementStart([{ofs: 5019, row: 178, col: 12}, {ofs: 5030, row: 178, col: 23}]); tmp569 = 1; _aether.logStatement([{ofs: 5019, row: 178, col: 12}, {ofs: 5030, row: 178, col: 23}], _aether._userInfo, false);\n tmp570 = other;\n tmp571 = tmp569;\n other = tmp570 + tmp571;\n } else {\n ;\n }\n }\n }\n tmp520 = i;\n tmp521 = 1;\n i = tmp520 + tmp521;\n tmp514 = i;\n tmp518 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp519 = 'enemies';\n _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}]); tmp516 = tmp518[tmp519]; _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}], _aether._userInfo, false);\n tmp517 = 'length';\n _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}]); tmp515 = tmp516[tmp517]; _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}]); tmp507 = tmp514 < tmp515; _aether.logStatement([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n }\n }\n tmp575 = base;\n _aether.logStatementStart([{ofs: 5061, row: 181, col: 14}, {ofs: 5062, row: 181, col: 15}]); tmp576 = 0; _aether.logStatement([{ofs: 5061, row: 181, col: 14}, {ofs: 5062, row: 181, col: 15}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5062, row: 181, col: 15}]); tmp574 = tmp575 > tmp576; _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5062, row: 181, col: 15}], _aether._userInfo, false);\n if (tmp574) {\n tmp577 = tharin;\n _aether.logStatementStart([{ofs: 5077, row: 181, col: 30}, {ofs: 5078, row: 181, col: 31}]); tmp578 = 0; _aether.logStatement([{ofs: 5077, row: 181, col: 30}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5066, row: 181, col: 19}, {ofs: 5078, row: 181, col: 31}]); tmp573 = tmp577 === tmp578; _aether.logStatement([{ofs: 5066, row: 181, col: 19}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5078, row: 181, col: 31}]); tmp573 = tmp574; _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n }\n if (tmp573) {\n tmp579 = other;\n _aether.logStatementStart([{ofs: 5092, row: 181, col: 45}, {ofs: 5093, row: 181, col: 46}]); tmp580 = 0; _aether.logStatement([{ofs: 5092, row: 181, col: 45}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5082, row: 181, col: 35}, {ofs: 5093, row: 181, col: 46}]); tmp572 = tmp579 === tmp580; _aether.logStatement([{ofs: 5082, row: 181, col: 35}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5093, row: 181, col: 46}]); tmp572 = tmp573; _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n }\n if (tmp572) {\n _aether.logStatementStart([{ofs: 5112, row: 182, col: 15}, {ofs: 5113, row: 182, col: 16}]); tmp581 = 1; _aether.logStatement([{ofs: 5112, row: 182, col: 15}, {ofs: 5113, row: 182, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp581);\n } else {\n tmp585 = tharin;\n _aether.logStatementStart([{ofs: 5142, row: 184, col: 21}, {ofs: 5143, row: 184, col: 22}]); tmp586 = 0; _aether.logStatement([{ofs: 5142, row: 184, col: 21}, {ofs: 5143, row: 184, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5143, row: 184, col: 22}]); tmp584 = tmp585 > tmp586; _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5143, row: 184, col: 22}], _aether._userInfo, false);\n if (tmp584) {\n tmp587 = base;\n _aether.logStatementStart([{ofs: 5156, row: 184, col: 35}, {ofs: 5157, row: 184, col: 36}]); tmp588 = 0; _aether.logStatement([{ofs: 5156, row: 184, col: 35}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5147, row: 184, col: 26}, {ofs: 5157, row: 184, col: 36}]); tmp583 = tmp587 === tmp588; _aether.logStatement([{ofs: 5147, row: 184, col: 26}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5157, row: 184, col: 36}]); tmp583 = tmp584; _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n }\n if (tmp583) {\n tmp589 = other;\n _aether.logStatementStart([{ofs: 5171, row: 184, col: 50}, {ofs: 5172, row: 184, col: 51}]); tmp590 = 0; _aether.logStatement([{ofs: 5171, row: 184, col: 50}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5161, row: 184, col: 40}, {ofs: 5172, row: 184, col: 51}]); tmp582 = tmp589 === tmp590; _aether.logStatement([{ofs: 5161, row: 184, col: 40}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5172, row: 184, col: 51}]); tmp582 = tmp583; _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n }\n if (tmp582) {\n _aether.logStatementStart([{ofs: 5191, row: 185, col: 15}, {ofs: 5192, row: 185, col: 16}]); tmp591 = 2; _aether.logStatement([{ofs: 5191, row: 185, col: 15}, {ofs: 5192, row: 185, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp591);\n } else {\n tmp595 = tharin;\n _aether.logStatementStart([{ofs: 5221, row: 187, col: 21}, {ofs: 5222, row: 187, col: 22}]); tmp596 = 0; _aether.logStatement([{ofs: 5221, row: 187, col: 21}, {ofs: 5222, row: 187, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5222, row: 187, col: 22}]); tmp594 = tmp595 > tmp596; _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5222, row: 187, col: 22}], _aether._userInfo, false);\n if (tmp594) {\n tmp597 = base;\n _aether.logStatementStart([{ofs: 5233, row: 187, col: 33}, {ofs: 5234, row: 187, col: 34}]); tmp598 = 0; _aether.logStatement([{ofs: 5233, row: 187, col: 33}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5226, row: 187, col: 26}, {ofs: 5234, row: 187, col: 34}]); tmp593 = tmp597 > tmp598; _aether.logStatement([{ofs: 5226, row: 187, col: 26}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5234, row: 187, col: 34}]); tmp593 = tmp594; _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n }\n if (tmp593) {\n tmp599 = other;\n _aether.logStatementStart([{ofs: 5248, row: 187, col: 48}, {ofs: 5249, row: 187, col: 49}]); tmp600 = 0; _aether.logStatement([{ofs: 5248, row: 187, col: 48}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5238, row: 187, col: 38}, {ofs: 5249, row: 187, col: 49}]); tmp592 = tmp599 === tmp600; _aether.logStatement([{ofs: 5238, row: 187, col: 38}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5249, row: 187, col: 49}]); tmp592 = tmp593; _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n }\n if (tmp592) {\n _aether.logStatementStart([{ofs: 5268, row: 188, col: 15}, {ofs: 5269, row: 188, col: 16}]); tmp601 = 3; _aether.logStatement([{ofs: 5268, row: 188, col: 15}, {ofs: 5269, row: 188, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp601);\n } else {\n tmp604 = other;\n _aether.logStatementStart([{ofs: 5297, row: 190, col: 20}, {ofs: 5298, row: 190, col: 21}]); tmp605 = 0; _aether.logStatement([{ofs: 5297, row: 190, col: 20}, {ofs: 5298, row: 190, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5289, row: 190, col: 12}, {ofs: 5298, row: 190, col: 21}]); tmp603 = tmp604 > tmp605; _aether.logStatement([{ofs: 5289, row: 190, col: 12}, {ofs: 5298, row: 190, col: 21}], _aether._userInfo, false);\n if (tmp603) {\n tmp607 = tharin;\n _aether.logStatementStart([{ofs: 5312, row: 190, col: 35}, {ofs: 5313, row: 190, col: 36}]); tmp608 = 0; _aether.logStatement([{ofs: 5312, row: 190, col: 35}, {ofs: 5313, row: 190, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5303, row: 190, col: 26}, {ofs: 5313, row: 190, col: 36}]); tmp606 = tmp607 > tmp608; _aether.logStatement([{ofs: 5303, row: 190, col: 26}, {ofs: 5313, row: 190, col: 36}], _aether._userInfo, false);\n if (tmp606) {\n _aether.logStatementStart([{ofs: 5303, row: 190, col: 26}, {ofs: 5325, row: 190, col: 48}]); tmp602 = tmp606; _aether.logStatement([{ofs: 5303, row: 190, col: 26}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n } else {\n tmp609 = base;\n _aether.logStatementStart([{ofs: 5324, row: 190, col: 47}, {ofs: 5325, row: 190, col: 48}]); tmp610 = 0; _aether.logStatement([{ofs: 5324, row: 190, col: 47}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5317, row: 190, col: 40}, {ofs: 5325, row: 190, col: 48}]); tmp602 = tmp609 > tmp610; _aether.logStatement([{ofs: 5317, row: 190, col: 40}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 5289, row: 190, col: 12}, {ofs: 5326, row: 190, col: 49}]); tmp602 = tmp603; _aether.logStatement([{ofs: 5289, row: 190, col: 12}, {ofs: 5326, row: 190, col: 49}], _aether._userInfo, false);\n }\n if (tmp602) {\n _aether.logStatementStart([{ofs: 5345, row: 191, col: 15}, {ofs: 5346, row: 191, col: 16}]); tmp611 = 4; _aether.logStatement([{ofs: 5345, row: 191, col: 15}, {ofs: 5346, row: 191, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp611);\n } else {\n tmp615 = other;\n _aether.logStatementStart([{ofs: 5374, row: 193, col: 20}, {ofs: 5375, row: 193, col: 21}]); tmp616 = 0; _aether.logStatement([{ofs: 5374, row: 193, col: 20}, {ofs: 5375, row: 193, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5375, row: 193, col: 21}]); tmp614 = tmp615 > tmp616; _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5375, row: 193, col: 21}], _aether._userInfo, false);\n if (tmp614) {\n tmp617 = tharin;\n _aether.logStatementStart([{ofs: 5390, row: 193, col: 36}, {ofs: 5391, row: 193, col: 37}]); tmp618 = 0; _aether.logStatement([{ofs: 5390, row: 193, col: 36}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5379, row: 193, col: 25}, {ofs: 5391, row: 193, col: 37}]); tmp613 = tmp617 === tmp618; _aether.logStatement([{ofs: 5379, row: 193, col: 25}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5391, row: 193, col: 37}]); tmp613 = tmp614; _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n }\n if (tmp613) {\n tmp619 = base;\n _aether.logStatementStart([{ofs: 5404, row: 193, col: 50}, {ofs: 5405, row: 193, col: 51}]); tmp620 = 0; _aether.logStatement([{ofs: 5404, row: 193, col: 50}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5395, row: 193, col: 41}, {ofs: 5405, row: 193, col: 51}]); tmp612 = tmp619 === tmp620; _aether.logStatement([{ofs: 5395, row: 193, col: 41}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5405, row: 193, col: 51}]); tmp612 = tmp613; _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n }\n if (tmp612) {\n _aether.logStatementStart([{ofs: 5424, row: 194, col: 15}, {ofs: 5425, row: 194, col: 16}]); tmp621 = 5; _aether.logStatement([{ofs: 5424, row: 194, col: 15}, {ofs: 5425, row: 194, col: 16}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp621);\n } else {\n ;\n }\n }\n }\n }\n }\n _aether.logStatementStart([{ofs: 5561, row: 199, col: 11}, {ofs: 5562, row: 199, col: 12}]); tmp622 = 0; _aether.logStatement([{ofs: 5561, row: 199, col: 11}, {ofs: 5562, row: 199, col: 12}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp622);\n }; _aether.logStatement([{ofs: 4240, row: 151, col: 0}, {ofs: 5566, row: 200, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 4240, row: 151, col: 0}, {ofs: 5565, row: 200, col: 1}]); tmp494[tmp495] = tmp496; _aether.logStatement([{ofs: 4240, row: 151, col: 0}, {ofs: 5565, row: 200, col: 1}], _aether._userInfo, false);\n tmp623 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp624 = 'friends';\n tmp626 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp627 = 'getFriends';\n _aether.logStatementStart([{ofs: 5568, row: 202, col: 0}, {ofs: 5601, row: 202, col: 33}]); tmp625 = _aether.createAPIClone(_aether, tmp626[tmp627]()); _aether.logStatement([{ofs: 5568, row: 202, col: 0}, {ofs: 5601, row: 202, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5568, row: 202, col: 0}, {ofs: 5600, row: 202, col: 32}]); tmp623[tmp624] = tmp625; _aether.logStatement([{ofs: 5568, row: 202, col: 0}, {ofs: 5600, row: 202, col: 32}], _aether._userInfo, false);\n tmp628 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp629 = 'enemies';\n tmp631 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp632 = 'getEnemies';\n _aether.logStatementStart([{ofs: 5602, row: 203, col: 0}, {ofs: 5635, row: 203, col: 33}]); tmp630 = _aether.createAPIClone(_aether, tmp631[tmp632]()); _aether.logStatement([{ofs: 5602, row: 203, col: 0}, {ofs: 5635, row: 203, col: 33}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5602, row: 203, col: 0}, {ofs: 5634, row: 203, col: 32}]); tmp628[tmp629] = tmp630; _aether.logStatement([{ofs: 5602, row: 203, col: 0}, {ofs: 5634, row: 203, col: 32}], _aether._userInfo, false);\n tmp633 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp634 = 'terrifyClumpMinSize';\n _aether.logStatementStart([{ofs: 5826, row: 211, col: 0}, {ofs: 5855, row: 211, col: 29}]); tmp635 = 3; _aether.logStatement([{ofs: 5826, row: 211, col: 0}, {ofs: 5855, row: 211, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 5826, row: 211, col: 0}, {ofs: 5854, row: 211, col: 28}]); tmp633[tmp634] = tmp635; _aether.logStatement([{ofs: 5826, row: 211, col: 0}, {ofs: 5854, row: 211, col: 28}], _aether._userInfo, false);\n tmp638 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp639 = 'enemyBase';\n _aether.logStatementStart([{ofs: 6007, row: 217, col: 4}, {ofs: 6021, row: 217, col: 18}]); tmp637 = tmp638[tmp639]; _aether.logStatement([{ofs: 6007, row: 217, col: 4}, {ofs: 6021, row: 217, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6006, row: 217, col: 3}, {ofs: 6021, row: 217, col: 18}]); tmp636 = !tmp637; _aether.logStatement([{ofs: 6006, row: 217, col: 3}, {ofs: 6021, row: 217, col: 18}], _aether._userInfo, false);\n if (tmp636) {\n tmp640 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp641 = 'enemyBase';\n tmp643 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp644 = 'getEnemyBase';\n _aether.logStatementStart([{ofs: 6029, row: 218, col: 4}, {ofs: 6066, row: 218, col: 41}]); tmp642 = _aether.createAPIClone(_aether, tmp643[tmp644]()); _aether.logStatement([{ofs: 6029, row: 218, col: 4}, {ofs: 6066, row: 218, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6029, row: 218, col: 4}, {ofs: 6065, row: 218, col: 40}]); tmp640[tmp641] = tmp642; _aether.logStatement([{ofs: 6029, row: 218, col: 4}, {ofs: 6065, row: 218, col: 40}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp647 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp648 = 'enemyHero';\n _aether.logStatementStart([{ofs: 6073, row: 220, col: 4}, {ofs: 6087, row: 220, col: 18}]); tmp646 = tmp647[tmp648]; _aether.logStatement([{ofs: 6073, row: 220, col: 4}, {ofs: 6087, row: 220, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6072, row: 220, col: 3}, {ofs: 6087, row: 220, col: 18}]); tmp645 = !tmp646; _aether.logStatement([{ofs: 6072, row: 220, col: 3}, {ofs: 6087, row: 220, col: 18}], _aether._userInfo, false);\n if (tmp645) {\n tmp649 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp650 = 'enemyHero';\n tmp652 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp653 = 'getEnemyHero';\n _aether.logStatementStart([{ofs: 6095, row: 221, col: 4}, {ofs: 6132, row: 221, col: 41}]); tmp651 = _aether.createAPIClone(_aether, tmp652[tmp653]()); _aether.logStatement([{ofs: 6095, row: 221, col: 4}, {ofs: 6132, row: 221, col: 41}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6095, row: 221, col: 4}, {ofs: 6131, row: 221, col: 40}]); tmp649[tmp650] = tmp651; _aether.logStatement([{ofs: 6095, row: 221, col: 4}, {ofs: 6131, row: 221, col: 40}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp660 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp661 = 'enemies';\n _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6243, row: 225, col: 15}]); tmp658 = tmp660[tmp661]; _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6243, row: 225, col: 15}], _aether._userInfo, false);\n tmp659 = 'length';\n _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6250, row: 225, col: 22}]); tmp656 = tmp658[tmp659]; _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6250, row: 225, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6255, row: 225, col: 27}, {ofs: 6256, row: 225, col: 28}]); tmp657 = 2; _aether.logStatement([{ofs: 6255, row: 225, col: 27}, {ofs: 6256, row: 225, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6256, row: 225, col: 28}]); tmp655 = tmp656 === tmp657; _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6256, row: 225, col: 28}], _aether._userInfo, false);\n if (tmp655) {\n tmp669 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp670 = 'enemies';\n _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6273, row: 225, col: 45}]); tmp667 = tmp669[tmp670]; _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6273, row: 225, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6274, row: 225, col: 46}, {ofs: 6275, row: 225, col: 47}]); tmp668 = 1; _aether.logStatement([{ofs: 6274, row: 225, col: 46}, {ofs: 6275, row: 225, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6276, row: 225, col: 48}]); tmp665 = tmp667[tmp668]; _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6276, row: 225, col: 48}], _aether._userInfo, false);\n tmp666 = 'type';\n _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6281, row: 225, col: 53}]); tmp663 = tmp665[tmp666]; _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6281, row: 225, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6286, row: 225, col: 58}, {ofs: 6296, row: 225, col: 68}]); tmp664 = 'munchkin'; _aether.logStatement([{ofs: 6286, row: 225, col: 58}, {ofs: 6296, row: 225, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6296, row: 225, col: 68}]); tmp662 = tmp663 === tmp664; _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6296, row: 225, col: 68}], _aether._userInfo, false);\n if (tmp662) {\n _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6334, row: 225, col: 106}]); tmp654 = tmp662; _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n } else {\n tmp677 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp678 = 'enemies';\n _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6312, row: 225, col: 84}]); tmp675 = tmp677[tmp678]; _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6312, row: 225, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6313, row: 225, col: 85}, {ofs: 6314, row: 225, col: 86}]); tmp676 = 1; _aether.logStatement([{ofs: 6313, row: 225, col: 85}, {ofs: 6314, row: 225, col: 86}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6315, row: 225, col: 87}]); tmp673 = tmp675[tmp676]; _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6315, row: 225, col: 87}], _aether._userInfo, false);\n tmp674 = 'type';\n _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6320, row: 225, col: 92}]); tmp671 = tmp673[tmp674]; _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6320, row: 225, col: 92}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6325, row: 225, col: 97}, {ofs: 6334, row: 225, col: 106}]); tmp672 = 'thrower'; _aether.logStatement([{ofs: 6325, row: 225, col: 97}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6334, row: 225, col: 106}]); tmp654 = tmp671 === tmp672; _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6335, row: 225, col: 107}]); tmp654 = tmp655; _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6335, row: 225, col: 107}], _aether._userInfo, false);\n }\n if (tmp654) {\n tmp679 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp680 = 'baseRace';\n _aether.logStatementStart([{ofs: 6343, row: 226, col: 4}, {ofs: 6364, row: 226, col: 25}]); tmp681 = true; _aether.logStatement([{ofs: 6343, row: 226, col: 4}, {ofs: 6364, row: 226, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6343, row: 226, col: 4}, {ofs: 6363, row: 226, col: 24}]); tmp679[tmp680] = tmp681; _aether.logStatement([{ofs: 6343, row: 226, col: 4}, {ofs: 6363, row: 226, col: 24}], _aether._userInfo, false);\n tmp682 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp683 = 'notHeroFirst';\n _aether.logStatementStart([{ofs: 6369, row: 227, col: 4}, {ofs: 6394, row: 227, col: 29}]); tmp684 = true; _aether.logStatement([{ofs: 6369, row: 227, col: 4}, {ofs: 6394, row: 227, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6369, row: 227, col: 4}, {ofs: 6393, row: 227, col: 28}]); tmp682[tmp683] = tmp684; _aether.logStatement([{ofs: 6369, row: 227, col: 4}, {ofs: 6393, row: 227, col: 28}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp688 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp689 = 'notHeroFirst';\n _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6417, row: 229, col: 20}]); tmp687 = tmp688[tmp689]; _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6417, row: 229, col: 20}], _aether._userInfo, false);\n if (tmp687) {\n tmp694 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp695 = 'enemies';\n _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6433, row: 229, col: 36}]); tmp692 = tmp694[tmp695]; _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6433, row: 229, col: 36}], _aether._userInfo, false);\n tmp693 = 'length';\n _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6440, row: 229, col: 43}]); tmp690 = tmp692[tmp693]; _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6440, row: 229, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6445, row: 229, col: 48}, {ofs: 6446, row: 229, col: 49}]); tmp691 = 3; _aether.logStatement([{ofs: 6445, row: 229, col: 48}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6446, row: 229, col: 49}]); tmp686 = tmp690 === tmp691; _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6446, row: 229, col: 49}]); tmp686 = tmp687; _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n }\n if (tmp686) {\n tmp703 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp704 = 'enemies';\n _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6463, row: 229, col: 66}]); tmp701 = tmp703[tmp704]; _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6463, row: 229, col: 66}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6464, row: 229, col: 67}, {ofs: 6465, row: 229, col: 68}]); tmp702 = 1; _aether.logStatement([{ofs: 6464, row: 229, col: 67}, {ofs: 6465, row: 229, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6466, row: 229, col: 69}]); tmp699 = tmp701[tmp702]; _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6466, row: 229, col: 69}], _aether._userInfo, false);\n tmp700 = 'type';\n _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6471, row: 229, col: 74}]); tmp697 = tmp699[tmp700]; _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6471, row: 229, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6476, row: 229, col: 79}, {ofs: 6486, row: 229, col: 89}]); tmp698 = 'munchkin'; _aether.logStatement([{ofs: 6476, row: 229, col: 79}, {ofs: 6486, row: 229, col: 89}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6486, row: 229, col: 89}]); tmp696 = tmp697 === tmp698; _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6486, row: 229, col: 89}], _aether._userInfo, false);\n if (tmp696) {\n _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6524, row: 229, col: 127}]); tmp685 = tmp696; _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n } else {\n tmp711 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp712 = 'enemies';\n _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6502, row: 229, col: 105}]); tmp709 = tmp711[tmp712]; _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6502, row: 229, col: 105}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6503, row: 229, col: 106}, {ofs: 6504, row: 229, col: 107}]); tmp710 = 1; _aether.logStatement([{ofs: 6503, row: 229, col: 106}, {ofs: 6504, row: 229, col: 107}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6505, row: 229, col: 108}]); tmp707 = tmp709[tmp710]; _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6505, row: 229, col: 108}], _aether._userInfo, false);\n tmp708 = 'type';\n _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6510, row: 229, col: 113}]); tmp705 = tmp707[tmp708]; _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6510, row: 229, col: 113}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6515, row: 229, col: 118}, {ofs: 6524, row: 229, col: 127}]); tmp706 = 'thrower'; _aether.logStatement([{ofs: 6515, row: 229, col: 118}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6524, row: 229, col: 127}]); tmp685 = tmp705 === tmp706; _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6525, row: 229, col: 128}]); tmp685 = tmp686; _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6525, row: 229, col: 128}], _aether._userInfo, false);\n }\n if (tmp685) {\n tmp713 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp714 = 'notHeroSecond';\n _aether.logStatementStart([{ofs: 6808, row: 235, col: 4}, {ofs: 6834, row: 235, col: 30}]); tmp715 = true; _aether.logStatement([{ofs: 6808, row: 235, col: 4}, {ofs: 6834, row: 235, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 6808, row: 235, col: 4}, {ofs: 6833, row: 235, col: 29}]); tmp713[tmp714] = tmp715; _aether.logStatement([{ofs: 6808, row: 235, col: 4}, {ofs: 6833, row: 235, col: 29}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp721 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp722 = 'earlyJump';\n _aether.logStatementStart([{ofs: 7003, row: 243, col: 4}, {ofs: 7017, row: 243, col: 18}]); tmp720 = tmp721[tmp722]; _aether.logStatement([{ofs: 7003, row: 243, col: 4}, {ofs: 7017, row: 243, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7017, row: 243, col: 18}]); tmp719 = !tmp720; _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7017, row: 243, col: 18}], _aether._userInfo, false);\n if (tmp719) {\n tmp723 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp724 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7021, row: 243, col: 22}, {ofs: 7035, row: 243, col: 36}]); tmp718 = tmp723[tmp724]; _aether.logStatement([{ofs: 7021, row: 243, col: 22}, {ofs: 7035, row: 243, col: 36}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7035, row: 243, col: 36}]); tmp718 = tmp719; _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7035, row: 243, col: 36}], _aether._userInfo, false);\n }\n if (tmp718) {\n tmp727 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp728 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7039, row: 243, col: 40}, {ofs: 7053, row: 243, col: 54}]); tmp725 = tmp727[tmp728]; _aether.logStatement([{ofs: 7039, row: 243, col: 40}, {ofs: 7053, row: 243, col: 54}], _aether._userInfo, false);\n tmp726 = 'action';\n _aether.logStatementStart([{ofs: 7039, row: 243, col: 40}, {ofs: 7060, row: 243, col: 61}]); tmp717 = tmp725[tmp726]; _aether.logStatement([{ofs: 7039, row: 243, col: 40}, {ofs: 7060, row: 243, col: 61}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7060, row: 243, col: 61}]); tmp717 = tmp718; _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7060, row: 243, col: 61}], _aether._userInfo, false);\n }\n if (tmp717) {\n tmp731 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp732 = 'now';\n _aether.logStatementStart([{ofs: 7064, row: 243, col: 65}, {ofs: 7074, row: 243, col: 75}]); tmp729 = _aether.createAPIClone(_aether, tmp731[tmp732]()); _aether.logStatement([{ofs: 7064, row: 243, col: 65}, {ofs: 7074, row: 243, col: 75}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7078, row: 243, col: 79}, {ofs: 7079, row: 243, col: 80}]); tmp730 = 1; _aether.logStatement([{ofs: 7078, row: 243, col: 79}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7064, row: 243, col: 65}, {ofs: 7079, row: 243, col: 80}]); tmp716 = tmp729 <= tmp730; _aether.logStatement([{ofs: 7064, row: 243, col: 65}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7079, row: 243, col: 80}]); tmp716 = tmp717; _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n }\n if (tmp716) {\n tmp733 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp734 = 'say';\n _aether.logStatementStart([{ofs: 7096, row: 244, col: 13}, {ofs: 7107, row: 244, col: 24}]); tmp735 = 'follow me'; _aether.logStatement([{ofs: 7096, row: 244, col: 13}, {ofs: 7107, row: 244, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7087, row: 244, col: 4}, {ofs: 7108, row: 244, col: 25}]); tmp736 = _aether.createAPIClone(_aether, tmp733[tmp734](_aether.restoreAPIClone(_aether, tmp735))); _aether.logStatement([{ofs: 7087, row: 244, col: 4}, {ofs: 7108, row: 244, col: 25}], _aether._userInfo, false);\n tmp742 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp743 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7131, row: 245, col: 21}]); tmp740 = tmp742[tmp743]; _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7131, row: 245, col: 21}], _aether._userInfo, false);\n tmp741 = 'action';\n _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7138, row: 245, col: 28}]); tmp738 = tmp740[tmp741]; _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7138, row: 245, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7143, row: 245, col: 33}, {ofs: 7149, row: 245, col: 39}]); tmp739 = 'jump'; _aether.logStatement([{ofs: 7143, row: 245, col: 33}, {ofs: 7149, row: 245, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7149, row: 245, col: 39}]); tmp737 = tmp738 === tmp739; _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7149, row: 245, col: 39}], _aether._userInfo, false);\n if (tmp737) {\n tmp744 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp745 = 'earlyJump';\n _aether.logStatementStart([{ofs: 7161, row: 246, col: 8}, {ofs: 7183, row: 246, col: 30}]); tmp746 = true; _aether.logStatement([{ofs: 7161, row: 246, col: 8}, {ofs: 7183, row: 246, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7161, row: 246, col: 8}, {ofs: 7182, row: 246, col: 29}]); tmp744[tmp745] = tmp746; _aether.logStatement([{ofs: 7161, row: 246, col: 8}, {ofs: 7182, row: 246, col: 29}], _aether._userInfo, false);\n tmp747 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp748 = 'baseRace';\n _aether.logStatementStart([{ofs: 7192, row: 247, col: 8}, {ofs: 7213, row: 247, col: 29}]); tmp749 = true; _aether.logStatement([{ofs: 7192, row: 247, col: 8}, {ofs: 7213, row: 247, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7192, row: 247, col: 8}, {ofs: 7212, row: 247, col: 28}]); tmp747[tmp748] = tmp749; _aether.logStatement([{ofs: 7192, row: 247, col: 8}, {ofs: 7212, row: 247, col: 28}], _aether._userInfo, false);\n } else {\n ;\n }\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp758 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp759 = 'midJump';\n _aether.logStatementStart([{ofs: 7265, row: 253, col: 4}, {ofs: 7277, row: 253, col: 16}]); tmp757 = tmp758[tmp759]; _aether.logStatement([{ofs: 7265, row: 253, col: 4}, {ofs: 7277, row: 253, col: 16}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7277, row: 253, col: 16}]); tmp756 = !tmp757; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7277, row: 253, col: 16}], _aether._userInfo, false);\n if (tmp756) {\n tmp762 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp763 = 'getCooldown';\n _aether.logStatementStart([{ofs: 7298, row: 253, col: 37}, {ofs: 7307, row: 253, col: 46}]); tmp764 = 'terrify'; _aether.logStatement([{ofs: 7298, row: 253, col: 37}, {ofs: 7307, row: 253, col: 46}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7281, row: 253, col: 20}, {ofs: 7308, row: 253, col: 47}]); tmp760 = _aether.createAPIClone(_aether, tmp762[tmp763](_aether.restoreAPIClone(_aether, tmp764))); _aether.logStatement([{ofs: 7281, row: 253, col: 20}, {ofs: 7308, row: 253, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7313, row: 253, col: 52}, {ofs: 7314, row: 253, col: 53}]); tmp761 = 0; _aether.logStatement([{ofs: 7313, row: 253, col: 52}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7281, row: 253, col: 20}, {ofs: 7314, row: 253, col: 53}]); tmp755 = tmp760 === tmp761; _aether.logStatement([{ofs: 7281, row: 253, col: 20}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7314, row: 253, col: 53}]); tmp755 = tmp756; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n }\n if (tmp755) {\n tmp765 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp766 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7318, row: 253, col: 57}, {ofs: 7332, row: 253, col: 71}]); tmp754 = tmp765[tmp766]; _aether.logStatement([{ofs: 7318, row: 253, col: 57}, {ofs: 7332, row: 253, col: 71}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7332, row: 253, col: 71}]); tmp754 = tmp755; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7332, row: 253, col: 71}], _aether._userInfo, false);\n }\n if (tmp754) {\n tmp769 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp770 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7336, row: 253, col: 75}, {ofs: 7350, row: 253, col: 89}]); tmp767 = tmp769[tmp770]; _aether.logStatement([{ofs: 7336, row: 253, col: 75}, {ofs: 7350, row: 253, col: 89}], _aether._userInfo, false);\n tmp768 = 'action';\n _aether.logStatementStart([{ofs: 7336, row: 253, col: 75}, {ofs: 7357, row: 253, col: 96}]); tmp753 = tmp767[tmp768]; _aether.logStatement([{ofs: 7336, row: 253, col: 75}, {ofs: 7357, row: 253, col: 96}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7357, row: 253, col: 96}]); tmp753 = tmp754; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7357, row: 253, col: 96}], _aether._userInfo, false);\n }\n if (tmp753) {\n tmp775 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp776 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7375, row: 253, col: 114}]); tmp773 = tmp775[tmp776]; _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7375, row: 253, col: 114}], _aether._userInfo, false);\n tmp774 = 'action';\n _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7382, row: 253, col: 121}]); tmp771 = tmp773[tmp774]; _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7382, row: 253, col: 121}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7387, row: 253, col: 126}, {ofs: 7393, row: 253, col: 132}]); tmp772 = 'jump'; _aether.logStatement([{ofs: 7387, row: 253, col: 126}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7393, row: 253, col: 132}]); tmp752 = tmp771 === tmp772; _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7393, row: 253, col: 132}]); tmp752 = tmp753; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n }\n if (tmp752) {\n tmp779 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp780 = 'distance';\n tmp782 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp783 = 'enemyHero';\n _aether.logStatementStart([{ofs: 7411, row: 253, col: 150}, {ofs: 7425, row: 253, col: 164}]); tmp781 = tmp782[tmp783]; _aether.logStatement([{ofs: 7411, row: 253, col: 150}, {ofs: 7425, row: 253, col: 164}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7397, row: 253, col: 136}, {ofs: 7426, row: 253, col: 165}]); tmp777 = _aether.createAPIClone(_aether, tmp779[tmp780](_aether.restoreAPIClone(_aether, tmp781))); _aether.logStatement([{ofs: 7397, row: 253, col: 136}, {ofs: 7426, row: 253, col: 165}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7430, row: 253, col: 169}, {ofs: 7432, row: 253, col: 171}]); tmp778 = 30; _aether.logStatement([{ofs: 7430, row: 253, col: 169}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7397, row: 253, col: 136}, {ofs: 7432, row: 253, col: 171}]); tmp751 = tmp777 >= tmp778; _aether.logStatement([{ofs: 7397, row: 253, col: 136}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7432, row: 253, col: 171}]); tmp751 = tmp752; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n }\n if (tmp751) {\n tmp786 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp787 = 'now';\n _aether.logStatementStart([{ofs: 7436, row: 253, col: 175}, {ofs: 7446, row: 253, col: 185}]); tmp784 = _aether.createAPIClone(_aether, tmp786[tmp787]()); _aether.logStatement([{ofs: 7436, row: 253, col: 175}, {ofs: 7446, row: 253, col: 185}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7449, row: 253, col: 188}, {ofs: 7450, row: 253, col: 189}]); tmp785 = 2; _aether.logStatement([{ofs: 7449, row: 253, col: 188}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7436, row: 253, col: 175}, {ofs: 7450, row: 253, col: 189}]); tmp750 = tmp784 > tmp785; _aether.logStatement([{ofs: 7436, row: 253, col: 175}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7450, row: 253, col: 189}]); tmp750 = tmp751; _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n }\n if (tmp750) {\n tmp788 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp789 = 'midJump';\n _aether.logStatementStart([{ofs: 7458, row: 254, col: 4}, {ofs: 7478, row: 254, col: 24}]); tmp790 = true; _aether.logStatement([{ofs: 7458, row: 254, col: 4}, {ofs: 7478, row: 254, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7458, row: 254, col: 4}, {ofs: 7477, row: 254, col: 23}]); tmp788[tmp789] = tmp790; _aether.logStatement([{ofs: 7458, row: 254, col: 4}, {ofs: 7477, row: 254, col: 23}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp793 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp794 = 'baseRace';\n _aether.logStatementStart([{ofs: 7490, row: 257, col: 4}, {ofs: 7503, row: 257, col: 17}]); tmp792 = tmp793[tmp794]; _aether.logStatement([{ofs: 7490, row: 257, col: 4}, {ofs: 7503, row: 257, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7489, row: 257, col: 3}, {ofs: 7503, row: 257, col: 17}]); tmp791 = !tmp792; _aether.logStatement([{ofs: 7489, row: 257, col: 3}, {ofs: 7503, row: 257, col: 17}], _aether._userInfo, false);\n if (tmp791) {\n tmp795 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp796 = 'baseRace';\n tmp798 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp799 = 'isOpponentBaseRushing';\n _aether.logStatementStart([{ofs: 7511, row: 258, col: 4}, {ofs: 7556, row: 258, col: 49}]); tmp797 = _aether.createAPIClone(_aether, tmp798[tmp799]()); _aether.logStatement([{ofs: 7511, row: 258, col: 4}, {ofs: 7556, row: 258, col: 49}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7511, row: 258, col: 4}, {ofs: 7555, row: 258, col: 48}]); tmp795[tmp796] = tmp797; _aether.logStatement([{ofs: 7511, row: 258, col: 4}, {ofs: 7555, row: 258, col: 48}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp803 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp804 = 'startedRushing';\n _aether.logStatementStart([{ofs: 7564, row: 261, col: 4}, {ofs: 7583, row: 261, col: 23}]); tmp802 = tmp803[tmp804]; _aether.logStatement([{ofs: 7564, row: 261, col: 4}, {ofs: 7583, row: 261, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7563, row: 261, col: 3}, {ofs: 7583, row: 261, col: 23}]); tmp801 = !tmp802; _aether.logStatement([{ofs: 7563, row: 261, col: 3}, {ofs: 7583, row: 261, col: 23}], _aether._userInfo, false);\n if (tmp801) {\n tmp806 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp807 = 'baseRace';\n _aether.logStatementStart([{ofs: 7588, row: 261, col: 28}, {ofs: 7601, row: 261, col: 41}]); tmp805 = tmp806[tmp807]; _aether.logStatement([{ofs: 7588, row: 261, col: 28}, {ofs: 7601, row: 261, col: 41}], _aether._userInfo, false);\n if (tmp805) {\n _aether.logStatementStart([{ofs: 7588, row: 261, col: 28}, {ofs: 7619, row: 261, col: 59}]); tmp800 = tmp805; _aether.logStatement([{ofs: 7588, row: 261, col: 28}, {ofs: 7619, row: 261, col: 59}], _aether._userInfo, false);\n } else {\n tmp808 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp809 = 'earlyJump';\n _aether.logStatementStart([{ofs: 7605, row: 261, col: 45}, {ofs: 7619, row: 261, col: 59}]); tmp800 = tmp808[tmp809]; _aether.logStatement([{ofs: 7605, row: 261, col: 45}, {ofs: 7619, row: 261, col: 59}], _aether._userInfo, false);\n }\n } else {\n _aether.logStatementStart([{ofs: 7563, row: 261, col: 3}, {ofs: 7620, row: 261, col: 60}]); tmp800 = tmp801; _aether.logStatement([{ofs: 7563, row: 261, col: 3}, {ofs: 7620, row: 261, col: 60}], _aether._userInfo, false);\n }\n if (tmp800) {\n tmp815 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp816 = 'friends';\n _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7643, row: 262, col: 19}]); tmp813 = tmp815[tmp816]; _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7643, row: 262, col: 19}], _aether._userInfo, false);\n tmp814 = 'length';\n _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7650, row: 262, col: 26}]); tmp811 = tmp813[tmp814]; _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7650, row: 262, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7654, row: 262, col: 30}, {ofs: 7655, row: 262, col: 31}]); tmp812 = 2; _aether.logStatement([{ofs: 7654, row: 262, col: 30}, {ofs: 7655, row: 262, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7655, row: 262, col: 31}]); tmp810 = tmp811 >= tmp812; _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7655, row: 262, col: 31}], _aether._userInfo, false);\n if (tmp810) {\n tmp820 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp821 = 'getCooldown';\n _aether.logStatementStart([{ofs: 7724, row: 263, col: 28}, {ofs: 7732, row: 263, col: 36}]); tmp822 = 'warcry'; _aether.logStatement([{ofs: 7724, row: 263, col: 28}, {ofs: 7732, row: 263, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7707, row: 263, col: 11}, {ofs: 7733, row: 263, col: 37}]); tmp818 = _aether.createAPIClone(_aether, tmp820[tmp821](_aether.restoreAPIClone(_aether, tmp822))); _aether.logStatement([{ofs: 7707, row: 263, col: 11}, {ofs: 7733, row: 263, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7738, row: 263, col: 42}, {ofs: 7739, row: 263, col: 43}]); tmp819 = 0; _aether.logStatement([{ofs: 7738, row: 263, col: 42}, {ofs: 7739, row: 263, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7707, row: 263, col: 11}, {ofs: 7739, row: 263, col: 43}]); tmp817 = tmp818 === tmp819; _aether.logStatement([{ofs: 7707, row: 263, col: 11}, {ofs: 7739, row: 263, col: 43}], _aether._userInfo, false);\n if (tmp817) {\n tmp823 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp824 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 7755, row: 264, col: 12}, {ofs: 7783, row: 264, col: 40}]); tmp825 = _aether.createAPIClone(_aether, tmp823[tmp824]()); _aether.logStatement([{ofs: 7755, row: 264, col: 12}, {ofs: 7783, row: 264, col: 40}], _aether._userInfo, false);\n tmp826 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp827 = 'warcry';\n _aether.logStatementStart([{ofs: 7797, row: 265, col: 12}, {ofs: 7810, row: 265, col: 25}]); tmp828 = _aether.createAPIClone(_aether, tmp826[tmp827]()); _aether.logStatement([{ofs: 7797, row: 265, col: 12}, {ofs: 7810, row: 265, col: 25}], _aether._userInfo, false);\n tmp829 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp830 = 'startedRushing';\n _aether.logStatementStart([{ofs: 7824, row: 266, col: 12}, {ofs: 7851, row: 266, col: 39}]); tmp831 = true; _aether.logStatement([{ofs: 7824, row: 266, col: 12}, {ofs: 7851, row: 266, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7824, row: 266, col: 12}, {ofs: 7850, row: 266, col: 38}]); tmp829[tmp830] = tmp831; _aether.logStatement([{ofs: 7824, row: 266, col: 12}, {ofs: 7850, row: 266, col: 38}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n tmp832 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp833 = 'say';\n _aether.logStatementStart([{ofs: 7955, row: 271, col: 17}, {ofs: 7966, row: 271, col: 28}]); tmp834 = 'follow me'; _aether.logStatement([{ofs: 7955, row: 271, col: 17}, {ofs: 7966, row: 271, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 7946, row: 271, col: 8}, {ofs: 7967, row: 271, col: 29}]); tmp835 = _aether.createAPIClone(_aether, tmp832[tmp833](_aether.restoreAPIClone(_aether, tmp834))); _aether.logStatement([{ofs: 7946, row: 271, col: 8}, {ofs: 7967, row: 271, col: 29}], _aether._userInfo, false);\n tmp836 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp837 = 'shield';\n _aether.logStatementStart([{ofs: 7977, row: 272, col: 8}, {ofs: 7990, row: 272, col: 21}]); tmp838 = _aether.createAPIClone(_aether, tmp836[tmp837]()); _aether.logStatement([{ofs: 7977, row: 272, col: 8}, {ofs: 7990, row: 272, col: 21}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n }\n } else {\n tmp841 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp842 = 'startedRushing';\n _aether.logStatementStart([{ofs: 8025, row: 276, col: 9}, {ofs: 8044, row: 276, col: 28}]); tmp840 = tmp841[tmp842]; _aether.logStatement([{ofs: 8025, row: 276, col: 9}, {ofs: 8044, row: 276, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8024, row: 276, col: 8}, {ofs: 8044, row: 276, col: 28}]); tmp839 = !tmp840; _aether.logStatement([{ofs: 8024, row: 276, col: 8}, {ofs: 8044, row: 276, col: 28}], _aether._userInfo, false);\n if (tmp839) {\n tmp848 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp849 = 'friends';\n _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8067, row: 277, col: 19}]); tmp846 = tmp848[tmp849]; _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8067, row: 277, col: 19}], _aether._userInfo, false);\n tmp847 = 'length';\n _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8074, row: 277, col: 26}]); tmp844 = tmp846[tmp847]; _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8074, row: 277, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8078, row: 277, col: 30}, {ofs: 8079, row: 277, col: 31}]); tmp845 = 3; _aether.logStatement([{ofs: 8078, row: 277, col: 30}, {ofs: 8079, row: 277, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8079, row: 277, col: 31}]); tmp843 = tmp844 >= tmp845; _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8079, row: 277, col: 31}], _aether._userInfo, false);\n if (tmp843) {\n tmp853 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp854 = 'getCooldown';\n _aether.logStatementStart([{ofs: 8147, row: 278, col: 28}, {ofs: 8155, row: 278, col: 36}]); tmp855 = 'warcry'; _aether.logStatement([{ofs: 8147, row: 278, col: 28}, {ofs: 8155, row: 278, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8130, row: 278, col: 11}, {ofs: 8156, row: 278, col: 37}]); tmp851 = _aether.createAPIClone(_aether, tmp853[tmp854](_aether.restoreAPIClone(_aether, tmp855))); _aether.logStatement([{ofs: 8130, row: 278, col: 11}, {ofs: 8156, row: 278, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8161, row: 278, col: 42}, {ofs: 8162, row: 278, col: 43}]); tmp852 = 0; _aether.logStatement([{ofs: 8161, row: 278, col: 42}, {ofs: 8162, row: 278, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8130, row: 278, col: 11}, {ofs: 8162, row: 278, col: 43}]); tmp850 = tmp851 === tmp852; _aether.logStatement([{ofs: 8130, row: 278, col: 11}, {ofs: 8162, row: 278, col: 43}], _aether._userInfo, false);\n if (tmp850) {\n tmp856 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp857 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 8178, row: 279, col: 12}, {ofs: 8206, row: 279, col: 40}]); tmp858 = _aether.createAPIClone(_aether, tmp856[tmp857]()); _aether.logStatement([{ofs: 8178, row: 279, col: 12}, {ofs: 8206, row: 279, col: 40}], _aether._userInfo, false);\n tmp859 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp860 = 'warcry';\n _aether.logStatementStart([{ofs: 8220, row: 280, col: 12}, {ofs: 8233, row: 280, col: 25}]); tmp861 = _aether.createAPIClone(_aether, tmp859[tmp860]()); _aether.logStatement([{ofs: 8220, row: 280, col: 12}, {ofs: 8233, row: 280, col: 25}], _aether._userInfo, false);\n tmp862 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp863 = 'startedRushing';\n _aether.logStatementStart([{ofs: 8247, row: 281, col: 12}, {ofs: 8274, row: 281, col: 39}]); tmp864 = true; _aether.logStatement([{ofs: 8247, row: 281, col: 12}, {ofs: 8274, row: 281, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8247, row: 281, col: 12}, {ofs: 8273, row: 281, col: 38}]); tmp862[tmp863] = tmp864; _aether.logStatement([{ofs: 8247, row: 281, col: 12}, {ofs: 8273, row: 281, col: 38}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n tmp865 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp866 = 'say';\n _aether.logStatementStart([{ofs: 8379, row: 286, col: 17}, {ofs: 8390, row: 286, col: 28}]); tmp867 = 'follow me'; _aether.logStatement([{ofs: 8379, row: 286, col: 17}, {ofs: 8390, row: 286, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8370, row: 286, col: 8}, {ofs: 8391, row: 286, col: 29}]); tmp868 = _aether.createAPIClone(_aether, tmp865[tmp866](_aether.restoreAPIClone(_aether, tmp867))); _aether.logStatement([{ofs: 8370, row: 286, col: 8}, {ofs: 8391, row: 286, col: 29}], _aether._userInfo, false);\n tmp869 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp870 = 'shield';\n _aether.logStatementStart([{ofs: 8401, row: 287, col: 8}, {ofs: 8414, row: 287, col: 21}]); tmp871 = _aether.createAPIClone(_aether, tmp869[tmp870]()); _aether.logStatement([{ofs: 8401, row: 287, col: 8}, {ofs: 8414, row: 287, col: 21}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n }\n } else {\n ;\n }\n }\n tmp875 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp876 = 'getCooldown';\n _aether.logStatementStart([{ofs: 8461, row: 292, col: 20}, {ofs: 8470, row: 292, col: 29}]); tmp877 = 'terrify'; _aether.logStatement([{ofs: 8461, row: 292, col: 20}, {ofs: 8470, row: 292, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8444, row: 292, col: 3}, {ofs: 8471, row: 292, col: 30}]); tmp873 = _aether.createAPIClone(_aether, tmp875[tmp876](_aether.restoreAPIClone(_aether, tmp877))); _aether.logStatement([{ofs: 8444, row: 292, col: 3}, {ofs: 8471, row: 292, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8476, row: 292, col: 35}, {ofs: 8477, row: 292, col: 36}]); tmp874 = 0; _aether.logStatement([{ofs: 8476, row: 292, col: 35}, {ofs: 8477, row: 292, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8444, row: 292, col: 3}, {ofs: 8477, row: 292, col: 36}]); tmp872 = tmp873 === tmp874; _aether.logStatement([{ofs: 8444, row: 292, col: 3}, {ofs: 8477, row: 292, col: 36}], _aether._userInfo, false);\n if (tmp872) {\n tmp886 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp887 = 'earlyJump';\n _aether.logStatementStart([{ofs: 8494, row: 294, col: 8}, {ofs: 8508, row: 294, col: 22}]); tmp885 = tmp886[tmp887]; _aether.logStatement([{ofs: 8494, row: 294, col: 8}, {ofs: 8508, row: 294, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8508, row: 294, col: 22}]); tmp884 = !tmp885; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8508, row: 294, col: 22}], _aether._userInfo, false);\n if (tmp884) {\n tmp889 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp890 = 'lateJump';\n _aether.logStatementStart([{ofs: 8513, row: 294, col: 27}, {ofs: 8526, row: 294, col: 40}]); tmp888 = tmp889[tmp890]; _aether.logStatement([{ofs: 8513, row: 294, col: 27}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8512, row: 294, col: 26}, {ofs: 8526, row: 294, col: 40}]); tmp883 = !tmp888; _aether.logStatement([{ofs: 8512, row: 294, col: 26}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8526, row: 294, col: 40}]); tmp883 = tmp884; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n }\n if (tmp883) {\n tmp891 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp892 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8530, row: 294, col: 44}, {ofs: 8544, row: 294, col: 58}]); tmp882 = tmp891[tmp892]; _aether.logStatement([{ofs: 8530, row: 294, col: 44}, {ofs: 8544, row: 294, col: 58}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8544, row: 294, col: 58}]); tmp882 = tmp883; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8544, row: 294, col: 58}], _aether._userInfo, false);\n }\n if (tmp882) {\n tmp895 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp896 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8548, row: 294, col: 62}, {ofs: 8562, row: 294, col: 76}]); tmp893 = tmp895[tmp896]; _aether.logStatement([{ofs: 8548, row: 294, col: 62}, {ofs: 8562, row: 294, col: 76}], _aether._userInfo, false);\n tmp894 = 'action';\n _aether.logStatementStart([{ofs: 8548, row: 294, col: 62}, {ofs: 8569, row: 294, col: 83}]); tmp881 = tmp893[tmp894]; _aether.logStatement([{ofs: 8548, row: 294, col: 62}, {ofs: 8569, row: 294, col: 83}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8569, row: 294, col: 83}]); tmp881 = tmp882; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8569, row: 294, col: 83}], _aether._userInfo, false);\n }\n if (tmp881) {\n tmp901 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp902 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8587, row: 294, col: 101}]); tmp899 = tmp901[tmp902]; _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8587, row: 294, col: 101}], _aether._userInfo, false);\n tmp900 = 'action';\n _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8594, row: 294, col: 108}]); tmp897 = tmp899[tmp900]; _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8594, row: 294, col: 108}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8599, row: 294, col: 113}, {ofs: 8605, row: 294, col: 119}]); tmp898 = 'jump'; _aether.logStatement([{ofs: 8599, row: 294, col: 113}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8605, row: 294, col: 119}]); tmp880 = tmp897 === tmp898; _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8605, row: 294, col: 119}]); tmp880 = tmp881; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n }\n if (tmp880) {\n tmp905 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp906 = 'distance';\n tmp908 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp909 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8623, row: 294, col: 137}, {ofs: 8637, row: 294, col: 151}]); tmp907 = tmp908[tmp909]; _aether.logStatement([{ofs: 8623, row: 294, col: 137}, {ofs: 8637, row: 294, col: 151}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8609, row: 294, col: 123}, {ofs: 8638, row: 294, col: 152}]); tmp903 = _aether.createAPIClone(_aether, tmp905[tmp906](_aether.restoreAPIClone(_aether, tmp907))); _aether.logStatement([{ofs: 8609, row: 294, col: 123}, {ofs: 8638, row: 294, col: 152}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8642, row: 294, col: 156}, {ofs: 8644, row: 294, col: 158}]); tmp904 = 20; _aether.logStatement([{ofs: 8642, row: 294, col: 156}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8609, row: 294, col: 123}, {ofs: 8644, row: 294, col: 158}]); tmp879 = tmp903 <= tmp904; _aether.logStatement([{ofs: 8609, row: 294, col: 123}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8644, row: 294, col: 158}]); tmp879 = tmp880; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n }\n if (tmp879) {\n tmp912 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp913 = 'now';\n _aether.logStatementStart([{ofs: 8648, row: 294, col: 162}, {ofs: 8658, row: 294, col: 172}]); tmp910 = _aether.createAPIClone(_aether, tmp912[tmp913]()); _aether.logStatement([{ofs: 8648, row: 294, col: 162}, {ofs: 8658, row: 294, col: 172}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8661, row: 294, col: 175}, {ofs: 8662, row: 294, col: 176}]); tmp911 = 1; _aether.logStatement([{ofs: 8661, row: 294, col: 175}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8648, row: 294, col: 162}, {ofs: 8662, row: 294, col: 176}]); tmp878 = tmp910 > tmp911; _aether.logStatement([{ofs: 8648, row: 294, col: 162}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8662, row: 294, col: 176}]); tmp878 = tmp879; _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n }\n if (tmp878) {\n tmp914 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp915 = 'lateJump';\n _aether.logStatementStart([{ofs: 8674, row: 295, col: 8}, {ofs: 8695, row: 295, col: 29}]); tmp916 = true; _aether.logStatement([{ofs: 8674, row: 295, col: 8}, {ofs: 8695, row: 295, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8674, row: 295, col: 8}, {ofs: 8694, row: 295, col: 28}]); tmp914[tmp915] = tmp916; _aether.logStatement([{ofs: 8674, row: 295, col: 8}, {ofs: 8694, row: 295, col: 28}], _aether._userInfo, false);\n tmp917 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp918 = 'move';\n tmp924 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp925 = 'pos';\n _aether.logStatementStart([{ofs: 8717, row: 296, col: 21}, {ofs: 8725, row: 296, col: 29}]); tmp922 = tmp924[tmp925]; _aether.logStatement([{ofs: 8717, row: 296, col: 21}, {ofs: 8725, row: 296, col: 29}], _aether._userInfo, false);\n tmp923 = 'x';\n _aether.logStatementStart([{ofs: 8717, row: 296, col: 21}, {ofs: 8727, row: 296, col: 31}]); tmp920 = tmp922[tmp923]; _aether.logStatement([{ofs: 8717, row: 296, col: 21}, {ofs: 8727, row: 296, col: 31}], _aether._userInfo, false);\n tmp930 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp931 = 'pos';\n _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8739, row: 296, col: 43}]); tmp928 = tmp930[tmp931]; _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8739, row: 296, col: 43}], _aether._userInfo, false);\n tmp929 = 'y';\n _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8741, row: 296, col: 45}]); tmp926 = tmp928[tmp929]; _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8741, row: 296, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8742, row: 296, col: 46}, {ofs: 8743, row: 296, col: 47}]); tmp927 = 1; _aether.logStatement([{ofs: 8742, row: 296, col: 46}, {ofs: 8743, row: 296, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8743, row: 296, col: 47}]); tmp921 = tmp926 - tmp927; _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8743, row: 296, col: 47}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8714, row: 296, col: 18}, {ofs: 8744, row: 296, col: 48}]); tmp919 = {\n x: tmp920,\n y: tmp921\n }; _aether.logStatement([{ofs: 8714, row: 296, col: 18}, {ofs: 8744, row: 296, col: 48}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8704, row: 296, col: 8}, {ofs: 8745, row: 296, col: 49}]); tmp932 = _aether.createAPIClone(_aether, tmp917[tmp918](_aether.restoreAPIClone(_aether, tmp919))); _aether.logStatement([{ofs: 8704, row: 296, col: 8}, {ofs: 8745, row: 296, col: 49}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n tmp934 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp935 = 'lateJump';\n _aether.logStatementStart([{ofs: 8781, row: 299, col: 12}, {ofs: 8794, row: 299, col: 25}]); tmp933 = tmp934[tmp935]; _aether.logStatement([{ofs: 8781, row: 299, col: 12}, {ofs: 8794, row: 299, col: 25}], _aether._userInfo, false);\n if (tmp933) {\n tmp939 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp940 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8823, row: 300, col: 25}]); tmp938 = tmp939[tmp940]; _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8823, row: 300, col: 25}], _aether._userInfo, false);\n if (tmp938) {\n tmp943 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp944 = 'distance';\n tmp946 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp947 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8841, row: 300, col: 43}, {ofs: 8855, row: 300, col: 57}]); tmp945 = tmp946[tmp947]; _aether.logStatement([{ofs: 8841, row: 300, col: 43}, {ofs: 8855, row: 300, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8827, row: 300, col: 29}, {ofs: 8856, row: 300, col: 58}]); tmp941 = _aether.createAPIClone(_aether, tmp943[tmp944](_aether.restoreAPIClone(_aether, tmp945))); _aether.logStatement([{ofs: 8827, row: 300, col: 29}, {ofs: 8856, row: 300, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8860, row: 300, col: 62}, {ofs: 8862, row: 300, col: 64}]); tmp942 = 10; _aether.logStatement([{ofs: 8860, row: 300, col: 62}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8827, row: 300, col: 29}, {ofs: 8862, row: 300, col: 64}]); tmp937 = tmp941 >= tmp942; _aether.logStatement([{ofs: 8827, row: 300, col: 29}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8862, row: 300, col: 64}]); tmp937 = tmp938; _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n }\n if (tmp937) {\n tmp952 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp953 = 'pos';\n _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8874, row: 300, col: 76}]); tmp950 = tmp952[tmp953]; _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8874, row: 300, col: 76}], _aether._userInfo, false);\n tmp951 = 'x';\n _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8876, row: 300, col: 78}]); tmp948 = tmp950[tmp951]; _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8876, row: 300, col: 78}], _aether._userInfo, false);\n tmp958 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp959 = 'enemyHero';\n _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8893, row: 300, col: 95}]); tmp956 = tmp958[tmp959]; _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8893, row: 300, col: 95}], _aether._userInfo, false);\n tmp957 = 'pos';\n _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8897, row: 300, col: 99}]); tmp954 = tmp956[tmp957]; _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8897, row: 300, col: 99}], _aether._userInfo, false);\n tmp955 = 'x';\n _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8899, row: 300, col: 101}]); tmp949 = tmp954[tmp955]; _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8899, row: 300, col: 101}]); tmp936 = tmp948 > tmp949; _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8899, row: 300, col: 101}]); tmp936 = tmp937; _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n }\n if (tmp936) {\n tmp960 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp961 = 'terrifyTargets';\n tmp963 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp964 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 8915, row: 301, col: 12}, {ofs: 8962, row: 301, col: 59}]); tmp962 = _aether.createAPIClone(_aether, tmp963[tmp964]()); _aether.logStatement([{ofs: 8915, row: 301, col: 12}, {ofs: 8962, row: 301, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 8915, row: 301, col: 12}, {ofs: 8961, row: 301, col: 58}]); tmp960[tmp961] = tmp962; _aether.logStatement([{ofs: 8915, row: 301, col: 12}, {ofs: 8961, row: 301, col: 58}], _aether._userInfo, false);\n tmp965 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp966 = 'terrify';\n _aether.logStatementStart([{ofs: 8975, row: 302, col: 12}, {ofs: 8989, row: 302, col: 26}]); tmp967 = _aether.createAPIClone(_aether, tmp965[tmp966]()); _aether.logStatement([{ofs: 8975, row: 302, col: 12}, {ofs: 8989, row: 302, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n ;\n }\n }\n tmp972 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp973 = 'health';\n _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9295, row: 312, col: 18}]); tmp970 = tmp972[tmp973]; _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9295, row: 312, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9299, row: 312, col: 22}, {ofs: 9302, row: 312, col: 25}]); tmp971 = 100; _aether.logStatement([{ofs: 9299, row: 312, col: 22}, {ofs: 9302, row: 312, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9302, row: 312, col: 25}]); tmp969 = tmp970 <= tmp971; _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9302, row: 312, col: 25}], _aether._userInfo, false);\n if (tmp969) {\n _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9342, row: 312, col: 65}]); tmp968 = tmp969; _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9342, row: 312, col: 65}], _aether._userInfo, false);\n } else {\n tmp977 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp978 = 'now';\n _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9317, row: 312, col: 40}]); tmp975 = _aether.createAPIClone(_aether, tmp977[tmp978]()); _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9317, row: 312, col: 40}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9320, row: 312, col: 43}, {ofs: 9322, row: 312, col: 45}]); tmp976 = 10; _aether.logStatement([{ofs: 9320, row: 312, col: 43}, {ofs: 9322, row: 312, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9322, row: 312, col: 45}]); tmp974 = tmp975 > tmp976; _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9322, row: 312, col: 45}], _aether._userInfo, false);\n if (tmp974) {\n tmp983 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp984 = 'pos';\n _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9334, row: 312, col: 57}]); tmp981 = tmp983[tmp984]; _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9334, row: 312, col: 57}], _aether._userInfo, false);\n tmp982 = 'x';\n _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9336, row: 312, col: 59}]); tmp979 = tmp981[tmp982]; _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9336, row: 312, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9339, row: 312, col: 62}, {ofs: 9341, row: 312, col: 64}]); tmp980 = 65; _aether.logStatement([{ofs: 9339, row: 312, col: 62}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9341, row: 312, col: 64}]); tmp968 = tmp979 > tmp980; _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9341, row: 312, col: 64}]); tmp968 = tmp974; _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n }\n }\n if (tmp968) {\n tmp985 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp986 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 9354, row: 313, col: 8}, {ofs: 9382, row: 313, col: 36}]); tmp987 = _aether.createAPIClone(_aether, tmp985[tmp986]()); _aether.logStatement([{ofs: 9354, row: 313, col: 8}, {ofs: 9382, row: 313, col: 36}], _aether._userInfo, false);\n tmp988 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp989 = 'terrifyTargets';\n tmp991 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp992 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 9392, row: 314, col: 8}, {ofs: 9439, row: 314, col: 55}]); tmp990 = _aether.createAPIClone(_aether, tmp991[tmp992]()); _aether.logStatement([{ofs: 9392, row: 314, col: 8}, {ofs: 9439, row: 314, col: 55}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9392, row: 314, col: 8}, {ofs: 9438, row: 314, col: 54}]); tmp988[tmp989] = tmp990; _aether.logStatement([{ofs: 9392, row: 314, col: 8}, {ofs: 9438, row: 314, col: 54}], _aether._userInfo, false);\n tmp993 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp994 = 'terrify';\n _aether.logStatementStart([{ofs: 9448, row: 315, col: 8}, {ofs: 9462, row: 315, col: 22}]); tmp995 = _aether.createAPIClone(_aether, tmp993[tmp994]()); _aether.logStatement([{ofs: 9448, row: 315, col: 8}, {ofs: 9462, row: 315, col: 22}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n tmp997 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp998 = 'earlyJump';\n _aether.logStatementStart([{ofs: 9498, row: 318, col: 12}, {ofs: 9512, row: 318, col: 26}]); tmp996 = tmp997[tmp998]; _aether.logStatement([{ofs: 9498, row: 318, col: 12}, {ofs: 9512, row: 318, col: 26}], _aether._userInfo, false);\n if (tmp996) {\n tmp1002 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1003 = 'enemyHero';\n _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9917, row: 324, col: 25}]); tmp1001 = tmp1002[tmp1003]; _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9917, row: 324, col: 25}], _aether._userInfo, false);\n if (tmp1001) {\n tmp1006 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1007 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 9921, row: 324, col: 29}, {ofs: 9950, row: 324, col: 58}]); tmp1004 = _aether.createAPIClone(_aether, tmp1006[tmp1007]()); _aether.logStatement([{ofs: 9921, row: 324, col: 29}, {ofs: 9950, row: 324, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9955, row: 324, col: 63}, {ofs: 9956, row: 324, col: 64}]); tmp1005 = 1; _aether.logStatement([{ofs: 9955, row: 324, col: 63}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9921, row: 324, col: 29}, {ofs: 9956, row: 324, col: 64}]); tmp1000 = tmp1004 === tmp1005; _aether.logStatement([{ofs: 9921, row: 324, col: 29}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9956, row: 324, col: 64}]); tmp1000 = tmp1001; _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n }\n if (tmp1000) {\n tmp1010 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1011 = 'distance';\n tmp1013 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1014 = 'enemyHero';\n _aether.logStatementStart([{ofs: 9974, row: 324, col: 82}, {ofs: 9988, row: 324, col: 96}]); tmp1012 = tmp1013[tmp1014]; _aether.logStatement([{ofs: 9974, row: 324, col: 82}, {ofs: 9988, row: 324, col: 96}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9960, row: 324, col: 68}, {ofs: 9989, row: 324, col: 97}]); tmp1008 = _aether.createAPIClone(_aether, tmp1010[tmp1011](_aether.restoreAPIClone(_aether, tmp1012))); _aether.logStatement([{ofs: 9960, row: 324, col: 68}, {ofs: 9989, row: 324, col: 97}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9993, row: 324, col: 101}, {ofs: 9997, row: 324, col: 105}]); tmp1009 = 16.5; _aether.logStatement([{ofs: 9993, row: 324, col: 101}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 9960, row: 324, col: 68}, {ofs: 9997, row: 324, col: 105}]); tmp999 = tmp1008 <= tmp1009; _aether.logStatement([{ofs: 9960, row: 324, col: 68}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9997, row: 324, col: 105}]); tmp999 = tmp1000; _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n }\n if (tmp999) {\n tmp1015 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1016 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 10013, row: 325, col: 12}, {ofs: 10041, row: 325, col: 40}]); tmp1017 = _aether.createAPIClone(_aether, tmp1015[tmp1016]()); _aether.logStatement([{ofs: 10013, row: 325, col: 12}, {ofs: 10041, row: 325, col: 40}], _aether._userInfo, false);\n tmp1018 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1019 = 'terrifyTargets';\n tmp1021 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1022 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 10055, row: 326, col: 12}, {ofs: 10102, row: 326, col: 59}]); tmp1020 = _aether.createAPIClone(_aether, tmp1021[tmp1022]()); _aether.logStatement([{ofs: 10055, row: 326, col: 12}, {ofs: 10102, row: 326, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10055, row: 326, col: 12}, {ofs: 10101, row: 326, col: 58}]); tmp1018[tmp1019] = tmp1020; _aether.logStatement([{ofs: 10055, row: 326, col: 12}, {ofs: 10101, row: 326, col: 58}], _aether._userInfo, false);\n tmp1023 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1024 = 'terrify';\n _aether.logStatementStart([{ofs: 10115, row: 327, col: 12}, {ofs: 10129, row: 327, col: 26}]); tmp1025 = _aether.createAPIClone(_aether, tmp1023[tmp1024]()); _aether.logStatement([{ofs: 10115, row: 327, col: 12}, {ofs: 10129, row: 327, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n tmp1029 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1030 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10381, row: 334, col: 30}]); tmp1028 = tmp1029[tmp1030]; _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10381, row: 334, col: 30}], _aether._userInfo, false);\n if (tmp1028) {\n tmp1033 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1034 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 10385, row: 334, col: 34}, {ofs: 10414, row: 334, col: 63}]); tmp1031 = _aether.createAPIClone(_aether, tmp1033[tmp1034]()); _aether.logStatement([{ofs: 10385, row: 334, col: 34}, {ofs: 10414, row: 334, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10419, row: 334, col: 68}, {ofs: 10420, row: 334, col: 69}]); tmp1032 = 2; _aether.logStatement([{ofs: 10419, row: 334, col: 68}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10385, row: 334, col: 34}, {ofs: 10420, row: 334, col: 69}]); tmp1027 = tmp1031 === tmp1032; _aether.logStatement([{ofs: 10385, row: 334, col: 34}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10420, row: 334, col: 69}]); tmp1027 = tmp1028; _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n }\n if (tmp1027) {\n tmp1037 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1038 = 'distance';\n tmp1040 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1041 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10438, row: 334, col: 87}, {ofs: 10452, row: 334, col: 101}]); tmp1039 = tmp1040[tmp1041]; _aether.logStatement([{ofs: 10438, row: 334, col: 87}, {ofs: 10452, row: 334, col: 101}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10424, row: 334, col: 73}, {ofs: 10453, row: 334, col: 102}]); tmp1035 = _aether.createAPIClone(_aether, tmp1037[tmp1038](_aether.restoreAPIClone(_aether, tmp1039))); _aether.logStatement([{ofs: 10424, row: 334, col: 73}, {ofs: 10453, row: 334, col: 102}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10457, row: 334, col: 106}, {ofs: 10459, row: 334, col: 108}]); tmp1036 = 12; _aether.logStatement([{ofs: 10457, row: 334, col: 106}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10424, row: 334, col: 73}, {ofs: 10459, row: 334, col: 108}]); tmp1026 = tmp1035 <= tmp1036; _aether.logStatement([{ofs: 10424, row: 334, col: 73}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10459, row: 334, col: 108}]); tmp1026 = tmp1027; _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n }\n if (tmp1026) {\n tmp1042 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1043 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 10475, row: 335, col: 12}, {ofs: 10503, row: 335, col: 40}]); tmp1044 = _aether.createAPIClone(_aether, tmp1042[tmp1043]()); _aether.logStatement([{ofs: 10475, row: 335, col: 12}, {ofs: 10503, row: 335, col: 40}], _aether._userInfo, false);\n tmp1045 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1046 = 'terrifyTargets';\n tmp1048 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1049 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 10517, row: 336, col: 12}, {ofs: 10564, row: 336, col: 59}]); tmp1047 = _aether.createAPIClone(_aether, tmp1048[tmp1049]()); _aether.logStatement([{ofs: 10517, row: 336, col: 12}, {ofs: 10564, row: 336, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10517, row: 336, col: 12}, {ofs: 10563, row: 336, col: 58}]); tmp1045[tmp1046] = tmp1047; _aether.logStatement([{ofs: 10517, row: 336, col: 12}, {ofs: 10563, row: 336, col: 58}], _aether._userInfo, false);\n tmp1050 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1051 = 'terrify';\n _aether.logStatementStart([{ofs: 10577, row: 337, col: 12}, {ofs: 10591, row: 337, col: 26}]); tmp1052 = _aether.createAPIClone(_aether, tmp1050[tmp1051]()); _aether.logStatement([{ofs: 10577, row: 337, col: 12}, {ofs: 10591, row: 337, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n tmp1056 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1057 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10653, row: 340, col: 30}]); tmp1055 = tmp1056[tmp1057]; _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10653, row: 340, col: 30}], _aether._userInfo, false);\n if (tmp1055) {\n tmp1060 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1061 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 10657, row: 340, col: 34}, {ofs: 10686, row: 340, col: 63}]); tmp1058 = _aether.createAPIClone(_aether, tmp1060[tmp1061]()); _aether.logStatement([{ofs: 10657, row: 340, col: 34}, {ofs: 10686, row: 340, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10691, row: 340, col: 68}, {ofs: 10692, row: 340, col: 69}]); tmp1059 = 3; _aether.logStatement([{ofs: 10691, row: 340, col: 68}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10657, row: 340, col: 34}, {ofs: 10692, row: 340, col: 69}]); tmp1054 = tmp1058 === tmp1059; _aether.logStatement([{ofs: 10657, row: 340, col: 34}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10692, row: 340, col: 69}]); tmp1054 = tmp1055; _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n }\n if (tmp1054) {\n tmp1064 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1065 = 'distance';\n tmp1067 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1068 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10710, row: 340, col: 87}, {ofs: 10724, row: 340, col: 101}]); tmp1066 = tmp1067[tmp1068]; _aether.logStatement([{ofs: 10710, row: 340, col: 87}, {ofs: 10724, row: 340, col: 101}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10696, row: 340, col: 73}, {ofs: 10725, row: 340, col: 102}]); tmp1062 = _aether.createAPIClone(_aether, tmp1064[tmp1065](_aether.restoreAPIClone(_aether, tmp1066))); _aether.logStatement([{ofs: 10696, row: 340, col: 73}, {ofs: 10725, row: 340, col: 102}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10729, row: 340, col: 106}, {ofs: 10731, row: 340, col: 108}]); tmp1063 = 12; _aether.logStatement([{ofs: 10729, row: 340, col: 106}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10696, row: 340, col: 73}, {ofs: 10731, row: 340, col: 108}]); tmp1053 = tmp1062 <= tmp1063; _aether.logStatement([{ofs: 10696, row: 340, col: 73}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10731, row: 340, col: 108}]); tmp1053 = tmp1054; _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n }\n if (tmp1053) {\n tmp1069 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1070 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 10747, row: 341, col: 12}, {ofs: 10775, row: 341, col: 40}]); tmp1071 = _aether.createAPIClone(_aether, tmp1069[tmp1070]()); _aether.logStatement([{ofs: 10747, row: 341, col: 12}, {ofs: 10775, row: 341, col: 40}], _aether._userInfo, false);\n tmp1072 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1073 = 'terrifyTargets';\n tmp1075 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1076 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 10789, row: 342, col: 12}, {ofs: 10836, row: 342, col: 59}]); tmp1074 = _aether.createAPIClone(_aether, tmp1075[tmp1076]()); _aether.logStatement([{ofs: 10789, row: 342, col: 12}, {ofs: 10836, row: 342, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10789, row: 342, col: 12}, {ofs: 10835, row: 342, col: 58}]); tmp1072[tmp1073] = tmp1074; _aether.logStatement([{ofs: 10789, row: 342, col: 12}, {ofs: 10835, row: 342, col: 58}], _aether._userInfo, false);\n tmp1077 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1078 = 'terrify';\n _aether.logStatementStart([{ofs: 10849, row: 343, col: 12}, {ofs: 10863, row: 343, col: 26}]); tmp1079 = _aether.createAPIClone(_aether, tmp1077[tmp1078]()); _aether.logStatement([{ofs: 10849, row: 343, col: 12}, {ofs: 10863, row: 343, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n }\n }\n } else {\n tmp1081 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1082 = 'recalculateBaseRace';\n _aether.logStatementStart([{ofs: 10913, row: 347, col: 12}, {ofs: 10939, row: 347, col: 38}]); tmp1080 = _aether.createAPIClone(_aether, tmp1081[tmp1082]()); _aether.logStatement([{ofs: 10913, row: 347, col: 12}, {ofs: 10939, row: 347, col: 38}], _aether._userInfo, false);\n if (tmp1080) {\n tmp1085 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1086 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10954, row: 348, col: 11}, {ofs: 10968, row: 348, col: 25}]); tmp1084 = tmp1085[tmp1086]; _aether.logStatement([{ofs: 10954, row: 348, col: 11}, {ofs: 10968, row: 348, col: 25}], _aether._userInfo, false);\n if (tmp1084) {\n tmp1089 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1090 = 'distance';\n tmp1092 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1093 = 'enemyHero';\n _aether.logStatementStart([{ofs: 10986, row: 348, col: 43}, {ofs: 11000, row: 348, col: 57}]); tmp1091 = tmp1092[tmp1093]; _aether.logStatement([{ofs: 10986, row: 348, col: 43}, {ofs: 11000, row: 348, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10972, row: 348, col: 29}, {ofs: 11001, row: 348, col: 58}]); tmp1087 = _aether.createAPIClone(_aether, tmp1089[tmp1090](_aether.restoreAPIClone(_aether, tmp1091))); _aether.logStatement([{ofs: 10972, row: 348, col: 29}, {ofs: 11001, row: 348, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11005, row: 348, col: 62}, {ofs: 11007, row: 348, col: 64}]); tmp1088 = 17; _aether.logStatement([{ofs: 11005, row: 348, col: 62}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 10972, row: 348, col: 29}, {ofs: 11007, row: 348, col: 64}]); tmp1083 = tmp1087 <= tmp1088; _aether.logStatement([{ofs: 10972, row: 348, col: 29}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 10954, row: 348, col: 11}, {ofs: 11007, row: 348, col: 64}]); tmp1083 = tmp1084; _aether.logStatement([{ofs: 10954, row: 348, col: 11}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n }\n if (tmp1083) {\n tmp1094 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1095 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 11023, row: 349, col: 12}, {ofs: 11051, row: 349, col: 40}]); tmp1096 = _aether.createAPIClone(_aether, tmp1094[tmp1095]()); _aether.logStatement([{ofs: 11023, row: 349, col: 12}, {ofs: 11051, row: 349, col: 40}], _aether._userInfo, false);\n tmp1097 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1098 = 'terrifyTargets';\n tmp1100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1101 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 11065, row: 350, col: 12}, {ofs: 11112, row: 350, col: 59}]); tmp1099 = _aether.createAPIClone(_aether, tmp1100[tmp1101]()); _aether.logStatement([{ofs: 11065, row: 350, col: 12}, {ofs: 11112, row: 350, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11065, row: 350, col: 12}, {ofs: 11111, row: 350, col: 58}]); tmp1097[tmp1098] = tmp1099; _aether.logStatement([{ofs: 11065, row: 350, col: 12}, {ofs: 11111, row: 350, col: 58}], _aether._userInfo, false);\n tmp1102 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1103 = 'terrify';\n _aether.logStatementStart([{ofs: 11125, row: 351, col: 12}, {ofs: 11139, row: 351, col: 26}]); tmp1104 = _aether.createAPIClone(_aether, tmp1102[tmp1103]()); _aether.logStatement([{ofs: 11125, row: 351, col: 12}, {ofs: 11139, row: 351, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n tmp1107 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1108 = 'baseRace';\n _aether.logStatementStart([{ofs: 11189, row: 355, col: 12}, {ofs: 11202, row: 355, col: 25}]); tmp1106 = tmp1107[tmp1108]; _aether.logStatement([{ofs: 11189, row: 355, col: 12}, {ofs: 11202, row: 355, col: 25}], _aether._userInfo, false);\n if (tmp1106) {\n tmp1111 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1112 = 'now';\n _aether.logStatementStart([{ofs: 11206, row: 355, col: 29}, {ofs: 11216, row: 355, col: 39}]); tmp1109 = _aether.createAPIClone(_aether, tmp1111[tmp1112]()); _aether.logStatement([{ofs: 11206, row: 355, col: 29}, {ofs: 11216, row: 355, col: 39}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11220, row: 355, col: 43}, {ofs: 11221, row: 355, col: 44}]); tmp1110 = 6; _aether.logStatement([{ofs: 11220, row: 355, col: 43}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11206, row: 355, col: 29}, {ofs: 11221, row: 355, col: 44}]); tmp1105 = tmp1109 <= tmp1110; _aether.logStatement([{ofs: 11206, row: 355, col: 29}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 11189, row: 355, col: 12}, {ofs: 11221, row: 355, col: 44}]); tmp1105 = tmp1106; _aether.logStatement([{ofs: 11189, row: 355, col: 12}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n }\n if (tmp1105) {\n tmp1115 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1116 = 'isOpponentHeroRushing';\n _aether.logStatementStart([{ofs: 11236, row: 356, col: 11}, {ofs: 11262, row: 356, col: 37}]); tmp1114 = tmp1115[tmp1116]; _aether.logStatement([{ofs: 11236, row: 356, col: 11}, {ofs: 11262, row: 356, col: 37}], _aether._userInfo, false);\n if (tmp1114) {\n tmp1119 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1120 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 11266, row: 356, col: 41}, {ofs: 11295, row: 356, col: 70}]); tmp1117 = _aether.createAPIClone(_aether, tmp1119[tmp1120]()); _aether.logStatement([{ofs: 11266, row: 356, col: 41}, {ofs: 11295, row: 356, col: 70}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11300, row: 356, col: 75}, {ofs: 11301, row: 356, col: 76}]); tmp1118 = 1; _aether.logStatement([{ofs: 11300, row: 356, col: 75}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11266, row: 356, col: 41}, {ofs: 11301, row: 356, col: 76}]); tmp1113 = tmp1117 === tmp1118; _aether.logStatement([{ofs: 11266, row: 356, col: 41}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 11236, row: 356, col: 11}, {ofs: 11301, row: 356, col: 76}]); tmp1113 = tmp1114; _aether.logStatement([{ofs: 11236, row: 356, col: 11}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n }\n if (tmp1113) {\n tmp1123 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1124 = 'enemyHero';\n _aether.logStatementStart([{ofs: 11360, row: 358, col: 15}, {ofs: 11374, row: 358, col: 29}]); tmp1122 = tmp1123[tmp1124]; _aether.logStatement([{ofs: 11360, row: 358, col: 15}, {ofs: 11374, row: 358, col: 29}], _aether._userInfo, false);\n if (tmp1122) {\n tmp1127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1128 = 'distance';\n tmp1130 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1131 = 'enemyHero';\n _aether.logStatementStart([{ofs: 11392, row: 358, col: 47}, {ofs: 11406, row: 358, col: 61}]); tmp1129 = tmp1130[tmp1131]; _aether.logStatement([{ofs: 11392, row: 358, col: 47}, {ofs: 11406, row: 358, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11378, row: 358, col: 33}, {ofs: 11407, row: 358, col: 62}]); tmp1125 = _aether.createAPIClone(_aether, tmp1127[tmp1128](_aether.restoreAPIClone(_aether, tmp1129))); _aether.logStatement([{ofs: 11378, row: 358, col: 33}, {ofs: 11407, row: 358, col: 62}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11411, row: 358, col: 66}, {ofs: 11412, row: 358, col: 67}]); tmp1126 = 5; _aether.logStatement([{ofs: 11411, row: 358, col: 66}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11378, row: 358, col: 33}, {ofs: 11412, row: 358, col: 67}]); tmp1121 = tmp1125 <= tmp1126; _aether.logStatement([{ofs: 11378, row: 358, col: 33}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 11360, row: 358, col: 15}, {ofs: 11412, row: 358, col: 67}]); tmp1121 = tmp1122; _aether.logStatement([{ofs: 11360, row: 358, col: 15}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n }\n if (tmp1121) {\n tmp1132 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1133 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 11432, row: 359, col: 16}, {ofs: 11460, row: 359, col: 44}]); tmp1134 = _aether.createAPIClone(_aether, tmp1132[tmp1133]()); _aether.logStatement([{ofs: 11432, row: 359, col: 16}, {ofs: 11460, row: 359, col: 44}], _aether._userInfo, false);\n tmp1135 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1136 = 'terrifyTargets';\n tmp1138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1139 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 11478, row: 360, col: 16}, {ofs: 11525, row: 360, col: 63}]); tmp1137 = _aether.createAPIClone(_aether, tmp1138[tmp1139]()); _aether.logStatement([{ofs: 11478, row: 360, col: 16}, {ofs: 11525, row: 360, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11478, row: 360, col: 16}, {ofs: 11524, row: 360, col: 62}]); tmp1135[tmp1136] = tmp1137; _aether.logStatement([{ofs: 11478, row: 360, col: 16}, {ofs: 11524, row: 360, col: 62}], _aether._userInfo, false);\n tmp1140 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1141 = 'terrify';\n _aether.logStatementStart([{ofs: 11542, row: 361, col: 16}, {ofs: 11556, row: 361, col: 30}]); tmp1142 = _aether.createAPIClone(_aether, tmp1140[tmp1141]()); _aether.logStatement([{ofs: 11542, row: 361, col: 16}, {ofs: 11556, row: 361, col: 30}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n ;\n }\n tmp1145 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1146 = 'isOpponentHeroRushing';\n _aether.logStatementStart([{ofs: 11673, row: 366, col: 11}, {ofs: 11699, row: 366, col: 37}]); tmp1144 = tmp1145[tmp1146]; _aether.logStatement([{ofs: 11673, row: 366, col: 11}, {ofs: 11699, row: 366, col: 37}], _aether._userInfo, false);\n if (tmp1144) {\n tmp1149 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1150 = 'doesOpponentHaveRanged';\n _aether.logStatementStart([{ofs: 11703, row: 366, col: 41}, {ofs: 11732, row: 366, col: 70}]); tmp1147 = _aether.createAPIClone(_aether, tmp1149[tmp1150]()); _aether.logStatement([{ofs: 11703, row: 366, col: 41}, {ofs: 11732, row: 366, col: 70}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11735, row: 366, col: 73}, {ofs: 11736, row: 366, col: 74}]); tmp1148 = 1; _aether.logStatement([{ofs: 11735, row: 366, col: 73}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11703, row: 366, col: 41}, {ofs: 11736, row: 366, col: 74}]); tmp1143 = tmp1147 > tmp1148; _aether.logStatement([{ofs: 11703, row: 366, col: 41}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 11673, row: 366, col: 11}, {ofs: 11736, row: 366, col: 74}]); tmp1143 = tmp1144; _aether.logStatement([{ofs: 11673, row: 366, col: 11}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n }\n if (tmp1143) {\n tmp1153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1154 = 'enemyHero';\n _aether.logStatementStart([{ofs: 11755, row: 367, col: 15}, {ofs: 11769, row: 367, col: 29}]); tmp1152 = tmp1153[tmp1154]; _aether.logStatement([{ofs: 11755, row: 367, col: 15}, {ofs: 11769, row: 367, col: 29}], _aether._userInfo, false);\n if (tmp1152) {\n tmp1157 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1158 = 'distance';\n tmp1160 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1161 = 'enemyHero';\n _aether.logStatementStart([{ofs: 11787, row: 367, col: 47}, {ofs: 11801, row: 367, col: 61}]); tmp1159 = tmp1160[tmp1161]; _aether.logStatement([{ofs: 11787, row: 367, col: 47}, {ofs: 11801, row: 367, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11773, row: 367, col: 33}, {ofs: 11802, row: 367, col: 62}]); tmp1155 = _aether.createAPIClone(_aether, tmp1157[tmp1158](_aether.restoreAPIClone(_aether, tmp1159))); _aether.logStatement([{ofs: 11773, row: 367, col: 33}, {ofs: 11802, row: 367, col: 62}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11806, row: 367, col: 66}, {ofs: 11808, row: 367, col: 68}]); tmp1156 = 17; _aether.logStatement([{ofs: 11806, row: 367, col: 66}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11773, row: 367, col: 33}, {ofs: 11808, row: 367, col: 68}]); tmp1151 = tmp1155 <= tmp1156; _aether.logStatement([{ofs: 11773, row: 367, col: 33}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 11755, row: 367, col: 15}, {ofs: 11808, row: 367, col: 68}]); tmp1151 = tmp1152; _aether.logStatement([{ofs: 11755, row: 367, col: 15}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n }\n if (tmp1151) {\n tmp1162 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1163 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 11828, row: 368, col: 16}, {ofs: 11856, row: 368, col: 44}]); tmp1164 = _aether.createAPIClone(_aether, tmp1162[tmp1163]()); _aether.logStatement([{ofs: 11828, row: 368, col: 16}, {ofs: 11856, row: 368, col: 44}], _aether._userInfo, false);\n tmp1165 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1166 = 'terrifyTargets';\n tmp1168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1169 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 11874, row: 369, col: 16}, {ofs: 11921, row: 369, col: 63}]); tmp1167 = _aether.createAPIClone(_aether, tmp1168[tmp1169]()); _aether.logStatement([{ofs: 11874, row: 369, col: 16}, {ofs: 11921, row: 369, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 11874, row: 369, col: 16}, {ofs: 11920, row: 369, col: 62}]); tmp1165[tmp1166] = tmp1167; _aether.logStatement([{ofs: 11874, row: 369, col: 16}, {ofs: 11920, row: 369, col: 62}], _aether._userInfo, false);\n tmp1170 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1171 = 'terrify';\n _aether.logStatementStart([{ofs: 11938, row: 370, col: 16}, {ofs: 11952, row: 370, col: 30}]); tmp1172 = _aether.createAPIClone(_aether, tmp1170[tmp1171]()); _aether.logStatement([{ofs: 11938, row: 370, col: 16}, {ofs: 11952, row: 370, col: 30}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n tmp1176 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1177 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12033, row: 375, col: 30}]); tmp1175 = tmp1176[tmp1177]; _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12033, row: 375, col: 30}], _aether._userInfo, false);\n if (tmp1175) {\n tmp1180 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1181 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12037, row: 375, col: 34}, {ofs: 12051, row: 375, col: 48}]); tmp1178 = tmp1180[tmp1181]; _aether.logStatement([{ofs: 12037, row: 375, col: 34}, {ofs: 12051, row: 375, col: 48}], _aether._userInfo, false);\n tmp1179 = 'target';\n _aether.logStatementStart([{ofs: 12037, row: 375, col: 34}, {ofs: 12058, row: 375, col: 55}]); tmp1174 = tmp1178[tmp1179]; _aether.logStatement([{ofs: 12037, row: 375, col: 34}, {ofs: 12058, row: 375, col: 55}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12058, row: 375, col: 55}]); tmp1174 = tmp1175; _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12058, row: 375, col: 55}], _aether._userInfo, false);\n }\n if (tmp1174) {\n tmp1188 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1189 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12076, row: 375, col: 73}]); tmp1186 = tmp1188[tmp1189]; _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12076, row: 375, col: 73}], _aether._userInfo, false);\n tmp1187 = 'target';\n _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12083, row: 375, col: 80}]); tmp1184 = tmp1186[tmp1187]; _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12083, row: 375, col: 80}], _aether._userInfo, false);\n tmp1185 = 'type';\n _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12088, row: 375, col: 85}]); tmp1182 = tmp1184[tmp1185]; _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12088, row: 375, col: 85}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12092, row: 375, col: 89}, {ofs: 12098, row: 375, col: 95}]); tmp1183 = 'base'; _aether.logStatement([{ofs: 12092, row: 375, col: 89}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12098, row: 375, col: 95}]); tmp1173 = tmp1182 != tmp1183; _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12098, row: 375, col: 95}]); tmp1173 = tmp1174; _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n }\n if (tmp1173) {\n tmp1192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1193 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12117, row: 376, col: 15}, {ofs: 12131, row: 376, col: 29}]); tmp1191 = tmp1192[tmp1193]; _aether.logStatement([{ofs: 12117, row: 376, col: 15}, {ofs: 12131, row: 376, col: 29}], _aether._userInfo, false);\n if (tmp1191) {\n tmp1196 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1197 = 'distance';\n tmp1199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1200 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12149, row: 376, col: 47}, {ofs: 12163, row: 376, col: 61}]); tmp1198 = tmp1199[tmp1200]; _aether.logStatement([{ofs: 12149, row: 376, col: 47}, {ofs: 12163, row: 376, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12135, row: 376, col: 33}, {ofs: 12164, row: 376, col: 62}]); tmp1194 = _aether.createAPIClone(_aether, tmp1196[tmp1197](_aether.restoreAPIClone(_aether, tmp1198))); _aether.logStatement([{ofs: 12135, row: 376, col: 33}, {ofs: 12164, row: 376, col: 62}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12168, row: 376, col: 66}, {ofs: 12170, row: 376, col: 68}]); tmp1195 = 18; _aether.logStatement([{ofs: 12168, row: 376, col: 66}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12135, row: 376, col: 33}, {ofs: 12170, row: 376, col: 68}]); tmp1190 = tmp1194 <= tmp1195; _aether.logStatement([{ofs: 12135, row: 376, col: 33}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 12117, row: 376, col: 15}, {ofs: 12170, row: 376, col: 68}]); tmp1190 = tmp1191; _aether.logStatement([{ofs: 12117, row: 376, col: 15}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n }\n if (tmp1190) {\n tmp1201 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1202 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 12190, row: 377, col: 16}, {ofs: 12218, row: 377, col: 44}]); tmp1203 = _aether.createAPIClone(_aether, tmp1201[tmp1202]()); _aether.logStatement([{ofs: 12190, row: 377, col: 16}, {ofs: 12218, row: 377, col: 44}], _aether._userInfo, false);\n tmp1204 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1205 = 'terrifyTargets';\n tmp1207 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1208 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 12236, row: 378, col: 16}, {ofs: 12283, row: 378, col: 63}]); tmp1206 = _aether.createAPIClone(_aether, tmp1207[tmp1208]()); _aether.logStatement([{ofs: 12236, row: 378, col: 16}, {ofs: 12283, row: 378, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12236, row: 378, col: 16}, {ofs: 12282, row: 378, col: 62}]); tmp1204[tmp1205] = tmp1206; _aether.logStatement([{ofs: 12236, row: 378, col: 16}, {ofs: 12282, row: 378, col: 62}], _aether._userInfo, false);\n tmp1209 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1210 = 'terrify';\n _aether.logStatementStart([{ofs: 12300, row: 379, col: 16}, {ofs: 12314, row: 379, col: 30}]); tmp1211 = _aether.createAPIClone(_aether, tmp1209[tmp1210]()); _aether.logStatement([{ofs: 12300, row: 379, col: 16}, {ofs: 12314, row: 379, col: 30}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n } else {\n tmp1215 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1216 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12394, row: 383, col: 30}]); tmp1214 = tmp1215[tmp1216]; _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12394, row: 383, col: 30}], _aether._userInfo, false);\n if (tmp1214) {\n tmp1219 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1220 = 'distance';\n tmp1222 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1223 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12412, row: 383, col: 48}, {ofs: 12426, row: 383, col: 62}]); tmp1221 = tmp1222[tmp1223]; _aether.logStatement([{ofs: 12412, row: 383, col: 48}, {ofs: 12426, row: 383, col: 62}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12398, row: 383, col: 34}, {ofs: 12427, row: 383, col: 63}]); tmp1217 = _aether.createAPIClone(_aether, tmp1219[tmp1220](_aether.restoreAPIClone(_aether, tmp1221))); _aether.logStatement([{ofs: 12398, row: 383, col: 34}, {ofs: 12427, row: 383, col: 63}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12431, row: 383, col: 67}, {ofs: 12433, row: 383, col: 69}]); tmp1218 = 10; _aether.logStatement([{ofs: 12431, row: 383, col: 67}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12398, row: 383, col: 34}, {ofs: 12433, row: 383, col: 69}]); tmp1213 = tmp1217 >= tmp1218; _aether.logStatement([{ofs: 12398, row: 383, col: 34}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12433, row: 383, col: 69}]); tmp1213 = tmp1214; _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n }\n if (tmp1213) {\n tmp1228 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1229 = 'pos';\n _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12445, row: 383, col: 81}]); tmp1226 = tmp1228[tmp1229]; _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12445, row: 383, col: 81}], _aether._userInfo, false);\n tmp1227 = 'x';\n _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12447, row: 383, col: 83}]); tmp1224 = tmp1226[tmp1227]; _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12447, row: 383, col: 83}], _aether._userInfo, false);\n tmp1234 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1235 = 'enemyHero';\n _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12464, row: 383, col: 100}]); tmp1232 = tmp1234[tmp1235]; _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12464, row: 383, col: 100}], _aether._userInfo, false);\n tmp1233 = 'pos';\n _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12468, row: 383, col: 104}]); tmp1230 = tmp1232[tmp1233]; _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12468, row: 383, col: 104}], _aether._userInfo, false);\n tmp1231 = 'x';\n _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12470, row: 383, col: 106}]); tmp1225 = tmp1230[tmp1231]; _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12470, row: 383, col: 106}]); tmp1212 = tmp1224 > tmp1225; _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n } else {\n _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12470, row: 383, col: 106}]); tmp1212 = tmp1213; _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n }\n if (tmp1212) {\n tmp1236 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1237 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 12486, row: 384, col: 12}, {ofs: 12514, row: 384, col: 40}]); tmp1238 = _aether.createAPIClone(_aether, tmp1236[tmp1237]()); _aether.logStatement([{ofs: 12486, row: 384, col: 12}, {ofs: 12514, row: 384, col: 40}], _aether._userInfo, false);\n tmp1239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1240 = 'terrifyTargets';\n tmp1242 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1243 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 12528, row: 385, col: 12}, {ofs: 12575, row: 385, col: 59}]); tmp1241 = _aether.createAPIClone(_aether, tmp1242[tmp1243]()); _aether.logStatement([{ofs: 12528, row: 385, col: 12}, {ofs: 12575, row: 385, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12528, row: 385, col: 12}, {ofs: 12574, row: 385, col: 58}]); tmp1239[tmp1240] = tmp1241; _aether.logStatement([{ofs: 12528, row: 385, col: 12}, {ofs: 12574, row: 385, col: 58}], _aether._userInfo, false);\n tmp1244 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1245 = 'terrify';\n _aether.logStatementStart([{ofs: 12588, row: 386, col: 12}, {ofs: 12602, row: 386, col: 26}]); tmp1246 = _aether.createAPIClone(_aether, tmp1244[tmp1245]()); _aether.logStatement([{ofs: 12588, row: 386, col: 12}, {ofs: 12602, row: 386, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n }\n }\n } else {\n tmp1247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1248 = 'findTerrifyUnit';\n _aether.logStatementStart([{ofs: 12659, row: 391, col: 8}, {ofs: 12694, row: 391, col: 43}]); tUnit = _aether.createAPIClone(_aether, tmp1247[tmp1248]()); _aether.logStatement([{ofs: 12659, row: 391, col: 8}, {ofs: 12694, row: 391, col: 43}], _aether._userInfo, false);\n tmp1249 = tUnit;\n if (tmp1249) {\n tmp1250 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1251 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 12727, row: 393, col: 12}, {ofs: 12755, row: 393, col: 40}]); tmp1252 = _aether.createAPIClone(_aether, tmp1250[tmp1251]()); _aether.logStatement([{ofs: 12727, row: 393, col: 12}, {ofs: 12755, row: 393, col: 40}], _aether._userInfo, false);\n tmp1253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1254 = 'terrifyTargets';\n tmp1256 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1257 = 'getTerrifyTargets';\n _aether.logStatementStart([{ofs: 12769, row: 394, col: 12}, {ofs: 12816, row: 394, col: 59}]); tmp1255 = _aether.createAPIClone(_aether, tmp1256[tmp1257]()); _aether.logStatement([{ofs: 12769, row: 394, col: 12}, {ofs: 12816, row: 394, col: 59}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12769, row: 394, col: 12}, {ofs: 12815, row: 394, col: 58}]); tmp1253[tmp1254] = tmp1255; _aether.logStatement([{ofs: 12769, row: 394, col: 12}, {ofs: 12815, row: 394, col: 58}], _aether._userInfo, false);\n tmp1258 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1259 = 'terrify';\n _aether.logStatementStart([{ofs: 12829, row: 395, col: 12}, {ofs: 12843, row: 395, col: 26}]); tmp1260 = _aether.createAPIClone(_aether, tmp1258[tmp1259]()); _aether.logStatement([{ofs: 12829, row: 395, col: 12}, {ofs: 12843, row: 395, col: 26}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n }\n }\n }\n }\n } else {\n ;\n }\n tmp1264 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1265 = 'getCooldown';\n _aether.logStatementStart([{ofs: 12925, row: 402, col: 20}, {ofs: 12933, row: 402, col: 28}]); tmp1266 = 'warcry'; _aether.logStatement([{ofs: 12925, row: 402, col: 20}, {ofs: 12933, row: 402, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12908, row: 402, col: 3}, {ofs: 12934, row: 402, col: 29}]); tmp1262 = _aether.createAPIClone(_aether, tmp1264[tmp1265](_aether.restoreAPIClone(_aether, tmp1266))); _aether.logStatement([{ofs: 12908, row: 402, col: 3}, {ofs: 12934, row: 402, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12939, row: 402, col: 34}, {ofs: 12940, row: 402, col: 35}]); tmp1263 = 0; _aether.logStatement([{ofs: 12939, row: 402, col: 34}, {ofs: 12940, row: 402, col: 35}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 12908, row: 402, col: 3}, {ofs: 12940, row: 402, col: 35}]); tmp1261 = tmp1262 === tmp1263; _aether.logStatement([{ofs: 12908, row: 402, col: 3}, {ofs: 12940, row: 402, col: 35}], _aether._userInfo, false);\n if (tmp1261) {\n tmp1267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1268 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 12948, row: 403, col: 4}, {ofs: 12976, row: 403, col: 32}]); tmp1269 = _aether.createAPIClone(_aether, tmp1267[tmp1268]()); _aether.logStatement([{ofs: 12948, row: 403, col: 4}, {ofs: 12976, row: 403, col: 32}], _aether._userInfo, false);\n tmp1270 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1271 = 'warcry';\n _aether.logStatementStart([{ofs: 12982, row: 404, col: 4}, {ofs: 12995, row: 404, col: 17}]); tmp1272 = _aether.createAPIClone(_aether, tmp1270[tmp1271]()); _aether.logStatement([{ofs: 12982, row: 404, col: 4}, {ofs: 12995, row: 404, col: 17}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp1273 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp1274 = 'determineSayAndAction';\n _aether.logStatementStart([{ofs: 13012, row: 408, col: 0}, {ofs: 13040, row: 408, col: 28}]); tmp1275 = _aether.createAPIClone(_aether, tmp1273[tmp1274]()); _aether.logStatement([{ofs: 13012, row: 408, col: 0}, {ofs: 13040, row: 408, col: 28}], _aether._userInfo, false);\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" }, "programmable-librarian": { - "chooseAction": "..." + "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n 'use strict'; _aether.logCallStart(_aether._userInfo); var friends, enemies, enemy, friend, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logCallEnd(); return;\n _aether.logCallEnd(); return;\n tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp3 = 'getFriends';\n _aether.logStatementStart([{ofs: 380, row: 8, col: 0}, {ofs: 412, row: 8, col: 32}]); friends = _aether.createAPIClone(_aether, tmp2[tmp3]()); _aether.logStatement([{ofs: 380, row: 8, col: 0}, {ofs: 412, row: 8, col: 32}], _aether._userInfo, false);\n tmp4 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp5 = 'getEnemies';\n _aether.logStatementStart([{ofs: 413, row: 9, col: 0}, {ofs: 445, row: 9, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp4[tmp5]()); _aether.logStatement([{ofs: 413, row: 9, col: 0}, {ofs: 445, row: 9, col: 32}], _aether._userInfo, false);\n tmp9 = enemies;\n tmp10 = 'length';\n _aether.logStatementStart([{ofs: 450, row: 10, col: 4}, {ofs: 464, row: 10, col: 18}]); tmp7 = tmp9[tmp10]; _aether.logStatement([{ofs: 450, row: 10, col: 4}, {ofs: 464, row: 10, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 469, row: 10, col: 23}, {ofs: 470, row: 10, col: 24}]); tmp8 = 0; _aether.logStatement([{ofs: 469, row: 10, col: 23}, {ofs: 470, row: 10, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 450, row: 10, col: 4}, {ofs: 470, row: 10, col: 24}]); tmp6 = tmp7 === tmp8; _aether.logStatement([{ofs: 450, row: 10, col: 4}, {ofs: 470, row: 10, col: 24}], _aether._userInfo, false);\n if (tmp6) {\n _aether.logCallEnd(); return;\n } else {\n ;\n }\n tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp12 = 'getNearest';\n tmp13 = enemies;\n _aether.logStatementStart([{ofs: 515, row: 11, col: 0}, {ofs: 552, row: 11, col: 37}]); enemy = _aether.createAPIClone(_aether, tmp11[tmp12](_aether.restoreAPIClone(_aether, tmp13))); _aether.logStatement([{ofs: 515, row: 11, col: 0}, {ofs: 552, row: 11, col: 37}], _aether._userInfo, false);\n tmp14 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp15 = 'getNearest';\n tmp16 = friends;\n _aether.logStatementStart([{ofs: 553, row: 12, col: 0}, {ofs: 591, row: 12, col: 38}]); friend = _aether.createAPIClone(_aether, tmp14[tmp15](_aether.restoreAPIClone(_aether, tmp16))); _aether.logStatement([{ofs: 553, row: 12, col: 0}, {ofs: 591, row: 12, col: 38}], _aether._userInfo, false);\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" }, "ogre-base": { "chooseAction": "if(!this.builtHero) {\n //var hero = 'ironjaw'; // An unstoppable, jumping melee hero.\n var hero = 'yugargen'; // A shrinking, growing, poisonous spellcaster.\n this.builtHero = this.build(hero);\n return;\n}\n\nvar enemies = this.getEnemies();\nvar buildOrder = null;\nvar nearest = null;\nvar nearestX = 0;\nvar enemy;\nvar inCommand = this.built[0].health <= 0 || this.built[0].action == 'move';\nvar hasHero = false;\nvar archerCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type == 'librarian') {\n buildOrder = ['thrower', 'munchkin'];\n this.say(\"Destroy \" + enemy.id, {target: enemy});\n hasHero = true;\n break;\n }\n if(enemy.type == 'knight') {\n buildOrder = ['thrower', 'thrower', 'thrower', 'thrower', 'munchkin', 'thrower', 'thrower'];\n if(enemy.action != 'shield' && (enemy.pos.x > 40 || enemy.health < 130)) {\n this.say(\"Slay \" + enemy.id, {target: enemy});\n hasHero = true;\n }\n }\n if(enemy.type == 'archer')\n ++archerCount;\n if(enemy.pos.x > nearestX && (enemy.type != 'knight' || enemy.action != 'shield')) {\n nearest = enemy;\n nearestX = enemy.pos.x;\n }\n}\nif(nearest && enemy != nearest && inCommand && hasHero) {\n this.say(\"I guess let's fight kill \" + nearest.id, {target: nearest});\n}\nif(!buildOrder)\n buildOrder = ['munchkin', 'thrower', 'munchkin'];\nif(archerCount > 1)\n buildOrder = ['munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\nthis.build(type);\n" @@ -567,294 +731,28 @@ responses = "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif(!enemy) return;\n\n\n\nif(this.now() < 12.00) {\n //if(this.now() > 5 && this.now() < 8)\n // this.say(\"Move to\", {targetPos: {x: 76, y: 48}});\n //else if(this.now() < 5)\n this.say(\"Defend!\", {targetPos: {x: 60, y: 33}});\n //this.say(\"Defend!\");\n\n if(this.distance({x:enemy.pos.x, y:enemy.pos.y}) < 6)\n this.attack(enemy);\n else\n this.move({x: 65, y: 32});\n return;\n}\n\n\n\nthis.say(\"Attack!\");\nif(!this.getCooldown('stomp')) {\n this.say(\"BaaaDOOOSH!!!\");\n this.stomp();\n return;\n}\nif(!this.getCooldown('throw') && enemy.type != 'soldier' && this.pos.x < 48) {\n this.throw(enemy);\n return;\n}\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(this.distance(enemy) > 30) continue;\n if (enemy.type === 'librarian' || enemy.type === 'tharin' || enemy.type === 'archer') {\n if(!this.getCooldown('jump')) {\n var diff = Vector.subtract(enemy.pos, this.pos);\n diff = Vector.multiply(Vector.normalize(diff), 30);\n var to = Vector.add(this.pos, diff);\n this.jumpTo(to);\n this.say(\"Obliterate \" + enemy.id, {target: enemy});\n }\n else if(!this.getCooldown('stomp')) {\n this.say(\"BaDOOSH\");\n this.stomp();\n }\n else {\n this.attack(enemy);\n }\n return;\n }\n}\n\nenemy = this.getNearest(enemies);\nif (enemy && this.distance(enemy) < 20) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}" } }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, "submittedCodeLanguage": "javascript", "playtime": 1786, "codeLanguage": "javascript" } ] -employersResponse = [ - { - "_id": "52af5b805c813fc5b9000006", - "levelID": "gridmancer", - "levelName": "Gridmancer", - "code": { - "captain-anya": { - "plan": "// Fill the empty space with the minimum number of rectangles.\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar rects = {};\n\nfunction coordString(x, y) { return x+','+y; }\nfunction fourRectsHere(x, y) { return rects[coordString(x-tileSize,y)] && rects[coordString(x,y-tileSize)] && rects[coordString(x-tileSize,y-tileSize)] && rects[coordString(x,y)]; }\n\nfor(var y = 0; y < grid.length; y += tileSize) {\n for(var x = 0; x < grid[0].length; x += tileSize) {\n var occupied = grid[y][x].length > 0;\n if(!occupied) {\n var xcord = x + tileSize / 2;\n var ycord = y + tileSize / 2;\n this.addRect(xcord, ycord, tileSize, tileSize);\n rects[coordString(xcord,ycord)] = true;\n var coord = coordString(xcord,ycord);\n // this.say(coord);\n if (fourRectsHere(xcord,ycord)) {\n delete rects[coordString(xcord,ycord)];\n delete rects[coordString(xcord-tileSize, ycord)];\n delete rects[coordString(xcord-tileSize, ycord-tileSize)];\n delete rects[coordString(xcord, ycord-tileSize)];\n this.removeRect(xcord, ycord);\n this.removeRect(xcord - tileSize, ycord);\n this.removeRect(xcord, ycord - tileSize);\n this.removeRect(xcord - tileSize, ycord - tileSize);\n this.addRect(x, y, tileSize*2, tileSize*2);\n }\n this.wait(0.1);\n }\n }\n}\n" - }, - "thoktar": { - "plan": "# Fill the empty space with the minimum number of rectangles.\n# (Rectangles should not overlap each other or walls.)\n# The grid size is 1 meter, but the smallest wall/floor tile is 4 meters.\n# Check the blue guide button at the top for more info.\n# Make sure to sign up on the home page to save your code.\n\ngrid = self.getNavGrid().grid\ntileSize = 4\nfor y in range(0,grid.length,tileSize):\n for x in range(0,grid[0].length,tileSize):\n occupied = grid[y][x].length > 0\n if not occupied:\n self.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize)\n self.wait() # Hover over the timeline to help debug!\n\n\n" - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 138, - "codeLanguage": "python" - }, - { - "_id": "53026594cd9f9595b818d651", - "team": "me", - "levelID": "brawlwood", - "levelName": "Brawlwood", - "submitted": false, - "code": { - "programmable-artillery": { - "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'munchkin') {\n targetEnemy = enemy;\n break;\n }\n}\n\nif(!targetEnemy)\n targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n this.move({x: 70, y: 70});", - "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "programmable-soldier": { - "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are low damage, high health melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n this.attack(enemy);\nelse {\n this.move({x: 70, y: 70});\n}", - "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "s-arrow-tower": { - "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \".\");\n this.attack(enemy);\n}" - }, - "programmable-archer": { - "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n this.attack(enemy);\n}\nelse\n this.move({x: 70, y: 70});", - "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "human-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n type = 'artillery';\nelse if(this.built.length % 3 === 1)\n type = 'archer';\n\n// if(this.gold >= this.buildables[type].goldCost) {\n //this.say('Unit #' + this.built.length + ' will be a ' + type);\n this.build(type);\n// }", - "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 0, - "codeLanguage": "javascript" - }, - { - "_id": "5317530cc269d400000543c7", - "submitted": false, - "code": { - "muul": { - "chooseAction": "..." - }, - "nazgareth": { - "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" - }, - "ironjaw": { - "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n if(!this.getCooldown('jump')) {\n this.jumpTo(enemy.pos);\n this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 10, y: 30});\n}" - }, - "programmable-shaman": { - "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" - }, - "programmable-thrower": { - "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" - }, - "programmable-munchkin": { - "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" - }, - "ogre-base": { - "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide at the top for more info.\n\nif(!this.builtHero) {\n // Choose your hero!\n // var heroType = 'brawler';\n var heroType = 'shaman';\n this.builtHero = this.build(heroType);\n return;\n}\n\nvar buildOrder = ['munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" - }, - "poult": { - "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" - }, - "aoliantak": { - "chooseAction": "..." - }, - "programmable-brawler": { - "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n if(!this.getCooldown('jump')) {\n this.jumpTo(enemy.pos);\n this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 10, y: 30});\n}" - } - }, - "levelID": "dungeon-arena", - "levelName": "Dungeon Arena", - "submittedCodeLanguage": "javascript", - "playtime": 0, - "codeLanguage": "javascript" - }, - { - "_id": "5358429413f1278605f03ab8", - "team": "ogres", - "levelID": "greed", - "levelName": "Greed", - "code": { - "ogre-base": { - "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peon');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n var peon = peons[peonIndex];\n var item = peon.getNearest(items);\n if (item)\n base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n type = 'peon';\nelse\n type = 'ogre';\nif (base.gold >= base.buildables[type].goldCost)\n base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info." - }, - "well": { - "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" - } - }, - "totalScore": 16.724090931727677, - "submitted": true, - "submittedCodeLanguage": "javascript", - "playtime": 3837, - "codeLanguage": "javascript" - }, - { - "_id": "53177f6da508f6e7b3463fef", - "team": "humans", - "levelID": "dungeon-arena", - "levelName": "Dungeon Arena", - "submitted": true, - "totalScore": 11.782554190268042, - "code": { - "hushbaum-1": { - "chooseAction": "..." - }, - "librarian": { - "chooseAction": "..." - }, - "tharin-1": { - "chooseAction": "var friends = this.getFriends();\nvar nearest = this.getNearest(friends);\nif(this.distance(nearest) > 5) {\n this.move(nearest.pos);\n}\nelse {\n this.warcry();\n}" - }, - "hushbaum": { - "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n if (!enemy.hasEffect('slow')) {\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 70, y: 30});\n}\n" - }, - "anya": { - "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy)\n this.attack(enemy);" - }, - "tharin": { - "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n" - }, - "programmable-librarian": { - "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});" - }, - "programmable-tharin": { - "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;" - }, - "human-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'archer', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 1, - "codeLanguage": "javascript" - }, - { - "_id": "5318b6aa7aeef7843bba3357", - "team": "ogres", - "levelID": "dungeon-arena", - "levelName": "Dungeon Arena", - "submitted": true, - "totalScore": 34.28623946920249, - "code": { - "human-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\nhero = 'tharin'; // A fierce knight with battlecry abilities.\n//hero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar type;\nif (this.built.length > 50) {\n type = this.built.length & 1 ? 'archer' : 'soldier';\n} else {\n type = 'soldier';\n}\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" - }, - "programmable-tharin": { - "chooseAction": "var enemies = this.getEnemies();\nvar target = enemies[0];\n\nif (this.now() < 0.2) {\n this.attack(target);\n this.say(\"attack\", {target: target});\n return;\n}\n\nthis.say(\"attack\", {target: target});\nthis.attack(target);\nif (this.pos.x > 40 && !this.getCooldown('terrify')) {\n this.terrify();\n return;\n} else if (!this.getCooldown('warcry')) {\n this.warcry();\n}\nthis.say(\"attack\", {target: target});" - }, - "programmable-librarian": { - "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});" - }, - "programmable-shaman": { - "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// and three spells: 'shrink', 'grow', and 'poison-cloud'.\n// Shrink: target has 2/3 health, 1.5x speed for 5s.\n// Grow: target has double health, half speed for 5s.\n// Once per match, she can cast poison cloud, which does\n// 5 poison dps for 10s to enemies in a 10m radius.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(this.canCast('shrink', enemy)) this.castShrink(enemy);\n// if(this.canCast('grow', friend)) this.castGrow(friend);\n//if(this.canCast('poison-cloud', enemy)) this.castPoisonCloud(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40}); " - }, - "programmable-brawler": { - "chooseAction": "// The Brawler is a huge melee hero with mighty mass.\n// this.throw() hurls an enemy behind him.\n// this.jumpTo() leaps to a target within 20m every 10s.\n// this.stomp() knocks everyone away, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(!this.getCooldown('jump')) this.jumpTo(enemy.pos);\n// if(!this.getCooldown('stomp')) return this.stomp();\n// if(!this.getCooldown('throw')) this.throw(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;" - }, - "ironjaw": { - "chooseAction": "// var enemies = this.getEnemies();\n// var enemy = this.getNearest(enemies);\n// if (enemy) {\n// if(!this.getCooldown('jump')) {\n// this.jumpTo(enemy.pos);\n// this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n// this.attack(enemy);\n// }\n// }\n// else {\n// this.move({x: 10, y: 30});\n// }" - }, - "nazgareth": { - "chooseAction": "// // Shamans are spellcasters with a weak magic attack\n// // plus two useful spells: 'regen' and 'shrink'.\n\n// var enemy = this.getNearestEnemy();\n// if (!enemy)\n// this.move({x: 10, y: 25});\n// else if (!enemy.hasEffect('shrink')) {\n// this.castShrink(enemy);\n// if(this.distance(enemy) <= 30)\n// this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n// this.attack(enemy);\n// }" - }, - "ogre-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// Choose your hero! You can only build one hero.\nvar hero;\n// hero = 'ironjaw'; // A leaping juggernaut hero, type 'brawler'.\nhero = 'yugargen'; // A devious spellcaster hero, type 'shaman'.\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Munchkins are weak melee units with 1.25s build cooldown.\n// Throwers are fragile, deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['munchkin', 'munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);" - }, - "muul": { - "chooseAction": "..." - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 0, - "codeLanguage": "javascript" - }, - { - "_id": "52fd11c8e5c2b9000060bd48", - "team": "ogres", - "levelID": "brawlwood", - "levelName": "Brawlwood", - "submitted": true, - "totalScore": -10.697956636178176, - "code": { - "ogre-base": { - "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\n// var type = 'munchkin';\n// if(this.built.length % 5 === 3)\n type = 'shaman';\n// else if(this.built.length % 3 === 1)\n// type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n" - }, - "programmable-munchkin": { - "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" - }, - "programmable-thrower": { - "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 10});\n}" - }, - "n-beam-tower": { - "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \"!\");\n this.attack(enemy);\n}" - }, - "programmable-shaman": { - "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.", - "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n this.castShrink(enemy);\n if(this.distance(enemy) <= 30)\n this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}" - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 0, - "codeLanguage": "javascript" - }, - { - "_id": "53570b7a1bfa9bba14b5e045", - "team": "humans", - "levelID": "greed", - "levelName": "Greed", - "code": { - "well": { - "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n var x = Math.random();\n var type = 'silver';\n if (x < 0.05) type = 'gem';\n else if (x < 0.15) type = 'gold';\n else if (x < 0.35) type = 'copper';\n this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n target.maxAcceleration = 0;\n target.addCurrentEvent('fall');\n target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n var thang = this.inventorySystem.collectors[i];\n if ((thang.type == 'peasant' || thang.type == 'peon') &&\n (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n if (thang.maxAcceleration)\n this.causeFall(thang);\n else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n thang.setExists(false);\n thang.fellAt = null;\n }\n }\n}" - }, - "human-base": { - "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peasant');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n var peon = peons[peonIndex];\n var item = peon.getNearest(items);\n if (item)\n base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n type = 'peasant';\nelse\n type = 'soldier';\nif (base.gold >= base.buildables[type].goldCost)\n base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info." - } - }, - "submitted": true, - "totalScore": 29.46867296924995, - "submittedCodeLanguage": "javascript", - "playtime": 6295, - "codeLanguage": "javascript" - }, - { - "_id": "52fd11adae7dc8000099b788", - "team": "humans", - "levelID": "brawlwood", - "levelName": "Brawlwood", - "submitted": true, - "totalScore": 14.50139221733582, - "code": { - "programmable-artillery": { - "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n enemy = enemies[i];\n if(enemy.type === 'munchkin') {\n targetEnemy = enemy;\n break;\n }\n}\n\nif(!targetEnemy)\n targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n this.move({x: 70, y: 70});", - "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "programmable-soldier": { - "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are basic, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n this.attack(enemy);\nelse {\n var targetPos = {x: 70, y: 70};\n if(this.now() < 10)\n targetPos = {x: 40, y: 40};\n this.move(targetPos);\n}", - "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "programmable-archer": { - "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nif(this.lastEnemy && !this.lastEnemy.dead) {\n this.attack(this.lastEnemy);\n return;\n}\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n this.attack(enemy);\n if(this.distance(enemy) < this.attackRange) {\n this.lastEnemy = enemy;\n }\n}\nelse\n this.move({x: 70, y: 70});", - "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "human-base": { - "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n type = 'artillery';\nelse if(this.built.length % 3 === 1)\n type = 'archer';\n\n\nif(this.gold >= this.buildables[type].goldCost) {\n //this.say('Unit #' + this.built.length + ' will be a ' + type);\n this.build(type);\n}", - "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here." - }, - "s-arrow-tower": { - "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n this.say(\"Die, \" + enemy.id + \".\");\n this.attack(enemy);\n}" - } - }, - "submittedCodeLanguage": "javascript", - "playtime": 0, - "codeLanguage": "javascript" - } -] - module.exports = -> me.isAdmin = -> false me.set('permissions', ['employer']) v = new ProfileView({}, 'joe') - jasmine.Ajax.requests.mostRecent() for url, responseBody of responses requests = jasmine.Ajax.requests.filter(url) if not requests.length @@ -862,5 +760,5 @@ module.exports = -> continue request = requests[0] request.response({status: 200, responseText: JSON.stringify(responseBody)}) -# v.$el = v.$el.find('.main-content-area') + # v.$el = v.$el.find('.main-content-area') v From 079d336881d89b480c8989065cd48c62059e02c2 Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 16:36:59 -0700 Subject: [PATCH 35/58] Stopped .nano from overriding Bootstrap's column width for component docs page. --- app/styles/docs/components.sass | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/styles/docs/components.sass b/app/styles/docs/components.sass index 73979ded2..9283eda41 100644 --- a/app/styles/docs/components.sass +++ b/app/styles/docs/components.sass @@ -15,8 +15,11 @@ .doc-name color: rgb(139, 69, 19) + .index-column + width: 25% .documentation-column + width: 75% .specialList list-style-type: none From 0e042ee61cf9bc0881d703b328c804530c4e43bb Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 17:16:32 -0700 Subject: [PATCH 36/58] Refactoring View to RootView. Refactoring some RootViews to be routed manually. --- app/lib/Router.coffee | 13 +++++++++++++ app/views/AboutView.coffee | 6 ++++++ app/views/{admin_view.coffee => AdminView.coffee} | 4 ++-- app/views/{cla_view.coffee => CLAView.coffee} | 4 ++-- app/views/CommunityView.coffee | 6 ++++++ app/views/about_view.coffee | 6 ------ app/views/account/settings_view.coffee | 4 ++-- app/views/admin/candidates_view.coffee | 4 ++-- app/views/admin/clas_view.coffee | 4 ++-- app/views/admin/employer_list_view.coffee | 4 ++-- app/views/admin/level_sessions_view.coffee | 4 ++-- app/views/admin/users_view.coffee | 4 ++-- app/views/community_view.coffee | 6 ------ ...adventurer_view.coffee => AdventurerView.coffee} | 2 +- ...ambassador_view.coffee => AmbassadorView.coffee} | 2 +- .../{archmage_view.coffee => ArchmageView.coffee} | 2 +- .../{artisan_view.coffee => ArtisanView.coffee} | 2 +- ...class_view.coffee => ContributeClassView.coffee} | 4 ++-- .../{diplomat_view.coffee => DiplomatView.coffee} | 2 +- .../MainContributeView.coffee} | 4 ++-- .../{scribe_view.coffee => ScribeView.coffee} | 2 +- app/views/editor/achievement/edit.coffee | 4 ++-- app/views/editor/article/edit.coffee | 4 ++-- app/views/editor/article/preview.coffee | 4 ++-- app/views/editor/level/edit.coffee | 4 ++-- app/views/editor/thang/edit.coffee | 4 ++-- app/views/editor_view.coffee | 4 ++-- app/views/employers_view.coffee | 4 ++-- app/views/error_view.coffee | 4 ++-- app/views/home_view.coffee | 4 ++-- app/views/kinds/SearchView.coffee | 4 ++-- app/views/legal_view.coffee | 4 ++-- app/views/not_found.coffee | 4 ++-- app/views/play/ladder_home.coffee | 4 ++-- app/views/play/level_view.coffee | 4 ++-- app/views/play/spectate_view.coffee | 4 ++-- app/views/play_view.coffee | 4 ++-- app/views/sprite_parser_test_view.coffee | 4 ++-- app/views/teachers_view.coffee | 4 ++-- 39 files changed, 87 insertions(+), 74 deletions(-) create mode 100644 app/views/AboutView.coffee rename app/views/{admin_view.coffee => AdminView.coffee} (90%) rename app/views/{cla_view.coffee => CLAView.coffee} (88%) create mode 100644 app/views/CommunityView.coffee delete mode 100644 app/views/about_view.coffee delete mode 100644 app/views/community_view.coffee rename app/views/contribute/{adventurer_view.coffee => AdventurerView.coffee} (76%) rename app/views/contribute/{ambassador_view.coffee => AmbassadorView.coffee} (76%) rename app/views/contribute/{archmage_view.coffee => ArchmageView.coffee} (95%) rename app/views/contribute/{artisan_view.coffee => ArtisanView.coffee} (92%) rename app/views/contribute/{contribute_class_view.coffee => ContributeClassView.coffee} (93%) rename app/views/contribute/{diplomat_view.coffee => DiplomatView.coffee} (75%) rename app/views/{contribute_view.coffee => contribute/MainContributeView.coffee} (56%) rename app/views/contribute/{scribe_view.coffee => ScribeView.coffee} (86%) diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee index 31fcf6a85..17dab5309 100644 --- a/app/lib/Router.coffee +++ b/app/lib/Router.coffee @@ -8,6 +8,19 @@ module.exports = class CocoRouter extends Backbone.Router Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @ routes: + 'about': go('AboutView') + 'admin': go('AdminView') + 'cla': go('CLAView') + 'community': go('CommunityView') + + 'contribute': go('contribute/MainContributeView') + 'contribute/adventurer': go('contribute/AdventurerView') + 'contribute/ambassador': go('contribute/AmbassadorView') + 'contribute/archmage': go('contribute/ArchmageView') + 'contribute/artisan': go('contribute/ArtisanView') + 'contribute/diplomat': go('contribute/DiplomatView') + 'contribute/scribe': go('contribute/ScribeView') + # every abnormal view gets listed here '': 'home' 'preview': 'home' diff --git a/app/views/AboutView.coffee b/app/views/AboutView.coffee new file mode 100644 index 000000000..b93e9bdc6 --- /dev/null +++ b/app/views/AboutView.coffee @@ -0,0 +1,6 @@ +RootView = require 'views/kinds/RootView' +template = require 'templates/about' + +module.exports = class AboutView extends RootView + id: 'about-view' + template: template diff --git a/app/views/admin_view.coffee b/app/views/AdminView.coffee similarity index 90% rename from app/views/admin_view.coffee rename to app/views/AdminView.coffee index 6b0aadcc9..5c23d2ab1 100644 --- a/app/views/admin_view.coffee +++ b/app/views/AdminView.coffee @@ -1,8 +1,8 @@ {backboneFailure, genericFailure} = require 'lib/errors' -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin' -module.exports = class AdminView extends View +module.exports = class AdminView extends RootView id: 'admin-view' template: template diff --git a/app/views/cla_view.coffee b/app/views/CLAView.coffee similarity index 88% rename from app/views/cla_view.coffee rename to app/views/CLAView.coffee index 93f03aa56..08664992f 100644 --- a/app/views/cla_view.coffee +++ b/app/views/CLAView.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/cla' {me} = require 'lib/auth' -module.exports = class CLAView extends View +module.exports = class CLAView extends RootView id: 'cla-view' template: template diff --git a/app/views/CommunityView.coffee b/app/views/CommunityView.coffee new file mode 100644 index 000000000..15d28300a --- /dev/null +++ b/app/views/CommunityView.coffee @@ -0,0 +1,6 @@ +RootView = require 'views/kinds/RootView' +template = require 'templates/community' + +module.exports = class CommunityView extends RootView + id: 'community-view' + template: template diff --git a/app/views/about_view.coffee b/app/views/about_view.coffee deleted file mode 100644 index 76988aba8..000000000 --- a/app/views/about_view.coffee +++ /dev/null @@ -1,6 +0,0 @@ -View = require 'views/kinds/RootView' -template = require 'templates/about' - -module.exports = class AboutView extends View - id: 'about-view' - template: template diff --git a/app/views/account/settings_view.coffee b/app/views/account/settings_view.coffee index 4f6622232..39a335488 100644 --- a/app/views/account/settings_view.coffee +++ b/app/views/account/settings_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/account/settings' {me} = require 'lib/auth' forms = require 'lib/forms' @@ -8,7 +8,7 @@ AuthModalView = require 'views/modal/auth_modal' WizardSettingsView = require './wizard_settings_view' JobProfileView = require './job_profile_view' -module.exports = class SettingsView extends View +module.exports = class SettingsView extends RootView id: 'account-settings-view' template: template changedFields: [] # DOM input fields diff --git a/app/views/admin/candidates_view.coffee b/app/views/admin/candidates_view.coffee index 2946b161d..c91f16efd 100644 --- a/app/views/admin/candidates_view.coffee +++ b/app/views/admin/candidates_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin/candidates' app = require 'application' User = require 'models/User' @@ -15,7 +15,7 @@ class UserRemarksCollection extends CocoCollection url: '/db/user.remark?project=contact,contactName,user' model: UserRemark -module.exports = class EmployersView extends View +module.exports = class EmployersView extends RootView id: "admin-candidates-view" template: template diff --git a/app/views/admin/clas_view.coffee b/app/views/admin/clas_view.coffee index 96828e23e..a384215ed 100644 --- a/app/views/admin/clas_view.coffee +++ b/app/views/admin/clas_view.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin/clas' -module.exports = class CLAsView extends View +module.exports = class CLAsView extends RootView id: 'admin-clas-view' template: template startsLoading: true diff --git a/app/views/admin/employer_list_view.coffee b/app/views/admin/employer_list_view.coffee index b2ec64d77..32c08cd22 100644 --- a/app/views/admin/employer_list_view.coffee +++ b/app/views/admin/employer_list_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin/employer_list' app = require 'application' User = require 'models/User' @@ -10,7 +10,7 @@ class EmployersCollection extends CocoCollection url: '/db/user/x/employers' model: User -module.exports = class EmployersView extends View +module.exports = class EmployersView extends RootView id: 'employers-view' template: template diff --git a/app/views/admin/level_sessions_view.coffee b/app/views/admin/level_sessions_view.coffee index cca854cc3..aca163686 100644 --- a/app/views/admin/level_sessions_view.coffee +++ b/app/views/admin/level_sessions_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin/level_sessions' LevelSession = require 'models/LevelSession' @@ -7,7 +7,7 @@ class LevelSessionCollection extends Backbone.Collection url: '/db/level_session/x/active' model: LevelSession -module.exports = class LevelSessionsView extends View +module.exports = class LevelSessionsView extends RootView id: 'admin-level-sessions-view' template: template diff --git a/app/views/admin/users_view.coffee b/app/views/admin/users_view.coffee index fa4aa1ba9..7ff58de72 100644 --- a/app/views/admin/users_view.coffee +++ b/app/views/admin/users_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/admin/users' User = require 'models/User' -module.exports = class UsersView extends View +module.exports = class UsersView extends RootView # TODO: Pagination, choosing filters on the page itself. id: 'admin-users-view' diff --git a/app/views/community_view.coffee b/app/views/community_view.coffee deleted file mode 100644 index 69a140269..000000000 --- a/app/views/community_view.coffee +++ /dev/null @@ -1,6 +0,0 @@ -View = require 'views/kinds/RootView' -template = require 'templates/community' - -module.exports = class CommunityView extends View - id: 'community-view' - template: template diff --git a/app/views/contribute/adventurer_view.coffee b/app/views/contribute/AdventurerView.coffee similarity index 76% rename from app/views/contribute/adventurer_view.coffee rename to app/views/contribute/AdventurerView.coffee index deda5add5..9ad6a87f4 100644 --- a/app/views/contribute/adventurer_view.coffee +++ b/app/views/contribute/AdventurerView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/adventurer' {me} = require 'lib/auth' diff --git a/app/views/contribute/ambassador_view.coffee b/app/views/contribute/AmbassadorView.coffee similarity index 76% rename from app/views/contribute/ambassador_view.coffee rename to app/views/contribute/AmbassadorView.coffee index 73c35bf96..4ac62b277 100644 --- a/app/views/contribute/ambassador_view.coffee +++ b/app/views/contribute/AmbassadorView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/ambassador' {me} = require 'lib/auth' diff --git a/app/views/contribute/archmage_view.coffee b/app/views/contribute/ArchmageView.coffee similarity index 95% rename from app/views/contribute/archmage_view.coffee rename to app/views/contribute/ArchmageView.coffee index e29a9be5c..dd21e40ae 100644 --- a/app/views/contribute/archmage_view.coffee +++ b/app/views/contribute/ArchmageView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/archmage' module.exports = class ArchmageView extends ContributeClassView diff --git a/app/views/contribute/artisan_view.coffee b/app/views/contribute/ArtisanView.coffee similarity index 92% rename from app/views/contribute/artisan_view.coffee rename to app/views/contribute/ArtisanView.coffee index 7094dba98..40aa5bba0 100644 --- a/app/views/contribute/artisan_view.coffee +++ b/app/views/contribute/ArtisanView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/artisan' {me} = require 'lib/auth' diff --git a/app/views/contribute/contribute_class_view.coffee b/app/views/contribute/ContributeClassView.coffee similarity index 93% rename from app/views/contribute/contribute_class_view.coffee rename to app/views/contribute/ContributeClassView.coffee index 3da551ffb..7b403d466 100644 --- a/app/views/contribute/contribute_class_view.coffee +++ b/app/views/contribute/ContributeClassView.coffee @@ -1,11 +1,11 @@ SignupModalView = require 'views/modal/signup_modal' -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' {me} = require 'lib/auth' contributorSignupAnonymousTemplate = require 'templates/contribute/contributor_signup_anonymous' contributorSignupTemplate = require 'templates/contribute/contributor_signup' contributorListTemplate = require 'templates/contribute/contributor_list' -module.exports = class ContributeClassView extends View +module.exports = class ContributeClassView extends RootView navPrefix: '/contribute' events: diff --git a/app/views/contribute/diplomat_view.coffee b/app/views/contribute/DiplomatView.coffee similarity index 75% rename from app/views/contribute/diplomat_view.coffee rename to app/views/contribute/DiplomatView.coffee index 00b3dd7a7..32572cce0 100644 --- a/app/views/contribute/diplomat_view.coffee +++ b/app/views/contribute/DiplomatView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/diplomat' {me} = require 'lib/auth' diff --git a/app/views/contribute_view.coffee b/app/views/contribute/MainContributeView.coffee similarity index 56% rename from app/views/contribute_view.coffee rename to app/views/contribute/MainContributeView.coffee index fa772c75a..930870110 100644 --- a/app/views/contribute_view.coffee +++ b/app/views/contribute/MainContributeView.coffee @@ -1,7 +1,7 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require 'views/contribute/ContributeClassView' template = require 'templates/contribute/contribute' -module.exports = class ContributeView extends ContributeClassView +module.exports = class MainContributeView extends ContributeClassView id: 'contribute-view' template: template navPrefix: '' diff --git a/app/views/contribute/scribe_view.coffee b/app/views/contribute/ScribeView.coffee similarity index 86% rename from app/views/contribute/scribe_view.coffee rename to app/views/contribute/ScribeView.coffee index d52d0106b..bcaa5f648 100644 --- a/app/views/contribute/scribe_view.coffee +++ b/app/views/contribute/ScribeView.coffee @@ -1,4 +1,4 @@ -ContributeClassView = require 'views/contribute/contribute_class_view' +ContributeClassView = require './ContributeClassView' template = require 'templates/contribute/scribe' {me} = require 'lib/auth' diff --git a/app/views/editor/achievement/edit.coffee b/app/views/editor/achievement/edit.coffee index ce65446dd..8f4379777 100644 --- a/app/views/editor/achievement/edit.coffee +++ b/app/views/editor/achievement/edit.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/editor/achievement/edit' Achievement = require 'models/Achievement' ConfirmModal = require 'views/modal/confirm' -module.exports = class AchievementEditView extends View +module.exports = class AchievementEditView extends RootView id: 'editor-achievement-edit-view' template: template startsLoading: true diff --git a/app/views/editor/article/edit.coffee b/app/views/editor/article/edit.coffee index ae9083a2a..70450103f 100644 --- a/app/views/editor/article/edit.coffee +++ b/app/views/editor/article/edit.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' VersionHistoryView = require './versions_view' template = require 'templates/editor/article/edit' Article = require 'models/Article' SaveVersionModal = require 'views/modal/save_version_modal' PatchesView = require 'views/editor/patches_view' -module.exports = class ArticleEditView extends View +module.exports = class ArticleEditView extends RootView id: 'editor-article-edit-view' template: template startsLoading: true diff --git a/app/views/editor/article/preview.coffee b/app/views/editor/article/preview.coffee index ef4d3455b..9426454bf 100644 --- a/app/views/editor/article/preview.coffee +++ b/app/views/editor/article/preview.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/editor/article/preview' -module.exports = class PreviewView extends View +module.exports = class PreviewView extends RootView id: 'editor-article-preview-view' template: template diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 7e893d748..d597f0bfd 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/editor/level/edit' Level = require 'models/Level' LevelSystem = require 'models/LevelSystem' @@ -18,7 +18,7 @@ PatchesView = require 'views/editor/patches_view' VersionHistoryView = require './versions_view' ErrorView = require '../../error_view' -module.exports = class EditorLevelView extends View +module.exports = class EditorLevelView extends RootView id: 'editor-level-view' template: template cache: false diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee index d21272e6a..b5ea43653 100644 --- a/app/views/editor/thang/edit.coffee +++ b/app/views/editor/thang/edit.coffee @@ -5,7 +5,7 @@ CocoSprite = require 'lib/surface/CocoSprite' Camera = require 'lib/surface/Camera' DocumentFiles = require 'collections/DocumentFiles' -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' ThangComponentEditView = require 'views/editor/components/main' VersionHistoryView = require './versions_view' ColorsTabView = require './colors_tab_view' @@ -16,7 +16,7 @@ template = require 'templates/editor/thang/edit' CENTER = {x: 200, y: 300} -module.exports = class ThangTypeEditView extends View +module.exports = class ThangTypeEditView extends RootView id: 'editor-thang-type-edit-view' template: template startsLoading: true diff --git a/app/views/editor_view.coffee b/app/views/editor_view.coffee index aafe00eb1..7536d5ebc 100644 --- a/app/views/editor_view.coffee +++ b/app/views/editor_view.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/editor' -module.exports = class EditorView extends View +module.exports = class EditorView extends RootView id: 'editor-nav-view' template: template diff --git a/app/views/employers_view.coffee b/app/views/employers_view.coffee index 03ba35c85..9bbfa1ef6 100644 --- a/app/views/employers_view.coffee +++ b/app/views/employers_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/employers' app = require 'application' User = require 'models/User' @@ -15,7 +15,7 @@ class UserRemarksCollection extends CocoCollection url: '/db/user.remark?project=contact,contactName,user' model: UserRemark -module.exports = class EmployersView extends View +module.exports = class EmployersView extends RootView id: 'employers-view' template: template diff --git a/app/views/error_view.coffee b/app/views/error_view.coffee index 3ed6db5fd..f7b0ba04b 100644 --- a/app/views/error_view.coffee +++ b/app/views/error_view.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/error' -module.exports = class ErrorView extends View +module.exports = class ErrorView extends RootView id: 'error-view' template: template diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index 40eb72e88..dcc3dee69 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/home' WizardSprite = require 'lib/surface/WizardSprite' ThangType = require 'models/ThangType' @@ -6,7 +6,7 @@ Simulator = require 'lib/simulator/Simulator' {me} = require '/lib/auth' application = require 'application' -module.exports = class HomeView extends View +module.exports = class HomeView extends RootView id: 'home-view' template: template diff --git a/app/views/kinds/SearchView.coffee b/app/views/kinds/SearchView.coffee index 91b04d4d5..7fdd4cad6 100644 --- a/app/views/kinds/SearchView.coffee +++ b/app/views/kinds/SearchView.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/kinds/search' forms = require 'lib/forms' app = require 'application' @@ -12,7 +12,7 @@ class SearchCollection extends Backbone.Collection else @url += 'true' @url += "&term=#{term}" if @term -module.exports = class SearchView extends View +module.exports = class SearchView extends RootView template: template className: 'search-view' diff --git a/app/views/legal_view.coffee b/app/views/legal_view.coffee index 09ae6f2c3..2dd36473d 100644 --- a/app/views/legal_view.coffee +++ b/app/views/legal_view.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/legal' -module.exports = class LegalView extends View +module.exports = class LegalView extends RootView id: 'legal-view' template: template diff --git a/app/views/not_found.coffee b/app/views/not_found.coffee index 95e94921b..11d94cb42 100644 --- a/app/views/not_found.coffee +++ b/app/views/not_found.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/not_found' -module.exports = class NotFoundView extends View +module.exports = class NotFoundView extends RootView id: 'not-found-view' template: template diff --git a/app/views/play/ladder_home.coffee b/app/views/play/ladder_home.coffee index 1508697c9..502bbd877 100644 --- a/app/views/play/ladder_home.coffee +++ b/app/views/play/ladder_home.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/play/ladder_home' LevelSession = require 'models/LevelSession' CocoCollection = require 'collections/CocoCollection' @@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection super() @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID" -module.exports = class LadderHomeView extends View +module.exports = class LadderHomeView extends RootView id: 'ladder-home-view' template: template diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index 3527df5e5..010479b5f 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/play/level' {me} = require 'lib/auth' ThangType = require 'models/ThangType' @@ -35,7 +35,7 @@ InfiniteLoopModal = require './level/modal/infinite_loop_modal' PROFILE_ME = false -module.exports = class PlayLevelView extends View +module.exports = class PlayLevelView extends RootView id: 'level-view' template: template cache: false diff --git a/app/views/play/spectate_view.coffee b/app/views/play/spectate_view.coffee index 340978693..de9cab929 100644 --- a/app/views/play/spectate_view.coffee +++ b/app/views/play/spectate_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/play/spectate' {me} = require 'lib/auth' ThangType = require 'models/ThangType' @@ -33,7 +33,7 @@ InfiniteLoopModal = require './level/modal/infinite_loop_modal' PROFILE_ME = false -module.exports = class SpectateLevelView extends View +module.exports = class SpectateLevelView extends RootView id: 'spectate-level-view' template: template cache: false diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index c6679a3f4..202bd32a3 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/play' LevelSession = require 'models/LevelSession' CocoCollection = require 'collections/CocoCollection' @@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection super() @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID" -module.exports = class PlayView extends View +module.exports = class PlayView extends RootView id: 'play-view' template: template diff --git a/app/views/sprite_parser_test_view.coffee b/app/views/sprite_parser_test_view.coffee index ece70743e..80369fc45 100644 --- a/app/views/sprite_parser_test_view.coffee +++ b/app/views/sprite_parser_test_view.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/editor/thang/sprite_parser_test' SpriteParser = require 'lib/sprites/SpriteParser' mixed_samples = require 'lib/sprites/parser_samples' samples = require 'lib/sprites/parser_samples_artillery' ThangType = require 'models/ThangType' -module.exports = class SpriteParserTestView extends View +module.exports = class SpriteParserTestView extends RootView id: 'sprite-parser-test-view' template: template diff --git a/app/views/teachers_view.coffee b/app/views/teachers_view.coffee index 783f1391e..25d4ec958 100644 --- a/app/views/teachers_view.coffee +++ b/app/views/teachers_view.coffee @@ -1,6 +1,6 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/teachers' -module.exports = class TeachersView extends View +module.exports = class TeachersView extends RootView id: 'teachers-view' template: template From e18b4de583b2bc6265f965f60811b2e2ddfeb85e Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 17:20:11 -0700 Subject: [PATCH 37/58] Refactoring View to CocoView. --- app/views/editor/level/add_thangs_view.coffee | 4 ++-- app/views/editor/level/component/edit.coffee | 4 ++-- app/views/editor/level/components_tab_view.coffee | 4 ++-- app/views/editor/level/scripts_tab_view.coffee | 4 ++-- app/views/editor/level/settings_tab_view.coffee | 4 ++-- app/views/editor/level/system/edit.coffee | 4 ++-- app/views/editor/level/systems_tab_view.coffee | 4 ++-- app/views/editor/level/thang/edit.coffee | 4 ++-- app/views/editor/level/thangs_tab_view.coffee | 4 ++-- app/views/play/level/control_bar_view.coffee | 4 ++-- app/views/play/level/goals_view.coffee | 4 ++-- app/views/play/level/gold_view.coffee | 4 ++-- app/views/play/level/hud_view.coffee | 4 ++-- app/views/play/level/level_chat_view.coffee | 4 ++-- app/views/play/level/level_loading_view.coffee | 4 ++-- app/views/play/level/playback_view.coffee | 4 ++-- app/views/play/level/thang_avatar_view.coffee | 4 ++-- app/views/play/level/tome/cast_button_view.coffee | 4 ++-- app/views/play/level/tome/problem_alert_view.coffee | 4 ++-- app/views/play/level/tome/spell_debug_view.coffee | 4 ++-- app/views/play/level/tome/spell_list_entry_thangs_view.coffee | 4 ++-- app/views/play/level/tome/spell_list_entry_view.coffee | 4 ++-- app/views/play/level/tome/spell_list_view.coffee | 4 ++-- app/views/play/level/tome/spell_palette_entry_view.coffee | 4 ++-- app/views/play/level/tome/spell_palette_view.coffee | 4 ++-- app/views/play/level/tome/spell_toolbar_view.coffee | 4 ++-- app/views/play/level/tome/spell_view.coffee | 4 ++-- app/views/play/level/tome/thang_list_entry_view.coffee | 4 ++-- app/views/play/level/tome/thang_list_view.coffee | 4 ++-- app/views/play/level/tome/tome_view.coffee | 4 ++-- 30 files changed, 60 insertions(+), 60 deletions(-) diff --git a/app/views/editor/level/add_thangs_view.coffee b/app/views/editor/level/add_thangs_view.coffee index 7a7070b17..e41f42967 100644 --- a/app/views/editor/level/add_thangs_view.coffee +++ b/app/views/editor/level/add_thangs_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' add_thangs_template = require 'templates/editor/level/add_thangs' ThangType = require 'models/ThangType' CocoCollection = require 'collections/CocoCollection' @@ -10,7 +10,7 @@ class ThangTypeSearchCollection extends CocoCollection addTerm: (term) -> @url += "&term=#{term}" if term -module.exports = class AddThangsView extends View +module.exports = class AddThangsView extends CocoView id: 'add-thangs-column' className: 'add-thangs-palette thangs-column' template: add_thangs_template diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee index a7bc51149..9e36530ba 100644 --- a/app/views/editor/level/component/edit.coffee +++ b/app/views/editor/level/component/edit.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/component/edit' LevelComponent = require 'models/LevelComponent' VersionHistoryView = require 'views/editor/component/versions_view' PatchesView = require 'views/editor/patches_view' SaveVersionModal = require 'views/modal/save_version_modal' -module.exports = class LevelComponentEditView extends View +module.exports = class LevelComponentEditView extends CocoView id: 'editor-level-component-edit-view' template: template editableSettings: ['name', 'description', 'system', 'codeLanguage', 'dependencies', 'propertyDocumentation', 'i18n'] diff --git a/app/views/editor/level/components_tab_view.coffee b/app/views/editor/level/components_tab_view.coffee index 27f91ae87..03c9bb2cf 100644 --- a/app/views/editor/level/components_tab_view.coffee +++ b/app/views/editor/level/components_tab_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/components_tab' LevelComponent = require 'models/LevelComponent' LevelComponentEditView = require './component/edit' @@ -8,7 +8,7 @@ class LevelComponentCollection extends Backbone.Collection url: '/db/level.component' model: LevelComponent -module.exports = class ComponentsTabView extends View +module.exports = class ComponentsTabView extends CocoView id: 'editor-level-components-tab-view' template: template className: 'tab-pane' diff --git a/app/views/editor/level/scripts_tab_view.coffee b/app/views/editor/level/scripts_tab_view.coffee index 7a3e96c65..ae6813cbf 100644 --- a/app/views/editor/level/scripts_tab_view.coffee +++ b/app/views/editor/level/scripts_tab_view.coffee @@ -1,10 +1,10 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/scripts_tab' Level = require 'models/Level' Surface = require 'lib/surface/Surface' nodes = require './treema_nodes' -module.exports = class ScriptsTabView extends View +module.exports = class ScriptsTabView extends CocoView id: 'editor-level-scripts-tab-view' template: template className: 'tab-pane' diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee index b3f99150c..ec163d84e 100644 --- a/app/views/editor/level/settings_tab_view.coffee +++ b/app/views/editor/level/settings_tab_view.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/settings_tab' Level = require 'models/Level' Surface = require 'lib/surface/Surface' nodes = require './treema_nodes' {me} = require 'lib/auth' -module.exports = class SettingsTabView extends View +module.exports = class SettingsTabView extends CocoView id: 'editor-level-settings-tab-view' className: 'tab-pane' template: template diff --git a/app/views/editor/level/system/edit.coffee b/app/views/editor/level/system/edit.coffee index f9e9646db..de5877bda 100644 --- a/app/views/editor/level/system/edit.coffee +++ b/app/views/editor/level/system/edit.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/system/edit' LevelSystem = require 'models/LevelSystem' VersionHistoryView = require 'views/editor/system/versions_view' PatchesView = require 'views/editor/patches_view' SaveVersionModal = require 'views/modal/save_version_modal' -module.exports = class LevelSystemEditView extends View +module.exports = class LevelSystemEditView extends CocoView id: 'editor-level-system-edit-view' template: template editableSettings: ['name', 'description', 'codeLanguage', 'dependencies', 'propertyDocumentation', 'i18n'] diff --git a/app/views/editor/level/systems_tab_view.coffee b/app/views/editor/level/systems_tab_view.coffee index a3b6df3f2..4b4988755 100644 --- a/app/views/editor/level/systems_tab_view.coffee +++ b/app/views/editor/level/systems_tab_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/systems_tab' Level = require 'models/Level' LevelSystem = require 'models/LevelSystem' @@ -7,7 +7,7 @@ LevelSystemNewView = require './system/new' LevelSystemAddView = require './system/add' {ThangTypeNode} = require './treema_nodes' -module.exports = class SystemsTabView extends View +module.exports = class SystemsTabView extends CocoView id: 'editor-level-systems-tab-view' template: template className: 'tab-pane' diff --git a/app/views/editor/level/thang/edit.coffee b/app/views/editor/level/thang/edit.coffee index 01eb9c1d1..4dd5b1549 100644 --- a/app/views/editor/level/thang/edit.coffee +++ b/app/views/editor/level/thang/edit.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/editor/level/thang/edit' ThangComponentEditView = require 'views/editor/components/main' ThangType = require 'models/ThangType' -module.exports = class LevelThangEditView extends View +module.exports = class LevelThangEditView extends CocoView ### In the level editor, is the bar at the top when editing a single thang. Everything below is part of the ThangComponentEditView, which is shared with the diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee index a1b92966a..2fa4cb64c 100644 --- a/app/views/editor/level/thangs_tab_view.coffee +++ b/app/views/editor/level/thangs_tab_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' AddThangsView = require './add_thangs_view' thangs_template = require 'templates/editor/level/thangs_tab' Level = require 'models/Level' @@ -24,7 +24,7 @@ class ThangTypeSearchCollection extends CocoCollection url: '/db/thang.type?project=original,name,version,slug,kind,components' model: ThangType -module.exports = class ThangsTabView extends View +module.exports = class ThangsTabView extends CocoView id: 'editor-level-thangs-tab-view' className: 'tab-pane active' template: thangs_template diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee index 7a1dd58ec..18102be0f 100644 --- a/app/views/play/level/control_bar_view.coffee +++ b/app/views/play/level/control_bar_view.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/control_bar' DocsModal = require './modal/docs_modal' MultiplayerModal = require './modal/multiplayer_modal' ReloadModal = require './modal/reload_modal' -module.exports = class ControlBarView extends View +module.exports = class ControlBarView extends CocoView id: 'control-bar-view' template: template diff --git a/app/views/play/level/goals_view.coffee b/app/views/play/level/goals_view.coffee index e55d881b8..1264ada34 100644 --- a/app/views/play/level/goals_view.coffee +++ b/app/views/play/level/goals_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/goals' {me} = require 'lib/auth' utils = require 'lib/utils' @@ -8,7 +8,7 @@ stateIconMap = success: 'icon-ok' failure: 'icon-remove' -module.exports = class GoalsView extends View +module.exports = class GoalsView extends CocoView id: 'goals-view' template: template diff --git a/app/views/play/level/gold_view.coffee b/app/views/play/level/gold_view.coffee index 42ef28572..479fe8966 100644 --- a/app/views/play/level/gold_view.coffee +++ b/app/views/play/level/gold_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/gold' teamTemplate = require 'templates/play/level/team_gold' -module.exports = class GoldView extends View +module.exports = class GoldView extends CocoView id: 'gold-view' template: template diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index 75bc68346..a730bedf9 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -1,10 +1,10 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/hud' prop_template = require 'templates/play/level/hud_prop' action_template = require 'templates/play/level/hud_action' DialogueAnimator = require './dialogue_animator' -module.exports = class HUDView extends View +module.exports = class HUDView extends CocoView id: 'thang-hud' template: template dialogueMode: false diff --git a/app/views/play/level/level_chat_view.coffee b/app/views/play/level/level_chat_view.coffee index c581563da..5c4fe650a 100644 --- a/app/views/play/level/level_chat_view.coffee +++ b/app/views/play/level/level_chat_view.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/chat' {me} = require 'lib/auth' LevelBus = require 'lib/LevelBus' -module.exports = class LevelChatView extends View +module.exports = class LevelChatView extends CocoView id: 'level-chat-view' template: template open: false diff --git a/app/views/play/level/level_loading_view.coffee b/app/views/play/level/level_loading_view.coffee index 2ed460796..6c40e9de9 100644 --- a/app/views/play/level/level_loading_view.coffee +++ b/app/views/play/level/level_loading_view.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/level_loading' -module.exports = class LevelLoadingView extends View +module.exports = class LevelLoadingView extends CocoView id: 'level-loading-view' template: template diff --git a/app/views/play/level/playback_view.coffee b/app/views/play/level/playback_view.coffee index ecaab7080..f089e3c25 100644 --- a/app/views/play/level/playback_view.coffee +++ b/app/views/play/level/playback_view.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/playback' {me} = require 'lib/auth' EditorConfigModal = require './modal/editor_config_modal' KeyboardShortcutsModal = require './modal/keyboard_shortcuts_modal' -module.exports = class PlaybackView extends View +module.exports = class PlaybackView extends CocoView id: 'playback-view' template: template diff --git a/app/views/play/level/thang_avatar_view.coffee b/app/views/play/level/thang_avatar_view.coffee index 054fb0d1a..90ea72be1 100644 --- a/app/views/play/level/thang_avatar_view.coffee +++ b/app/views/play/level/thang_avatar_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/thang_avatar' ThangType = require 'models/ThangType' -module.exports = class ThangAvatarView extends View +module.exports = class ThangAvatarView extends CocoView className: 'thang-avatar-view' template: template diff --git a/app/views/play/level/tome/cast_button_view.coffee b/app/views/play/level/tome/cast_button_view.coffee index 1eb85c79f..fe82e4c28 100644 --- a/app/views/play/level/tome/cast_button_view.coffee +++ b/app/views/play/level/tome/cast_button_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/cast_button' {me} = require 'lib/auth' -module.exports = class CastButtonView extends View +module.exports = class CastButtonView extends CocoView id: 'cast-button-view' template: template diff --git a/app/views/play/level/tome/problem_alert_view.coffee b/app/views/play/level/tome/problem_alert_view.coffee index 2a77e1632..1756b2775 100644 --- a/app/views/play/level/tome/problem_alert_view.coffee +++ b/app/views/play/level/tome/problem_alert_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/problem_alert' {me} = require 'lib/auth' -module.exports = class ProblemAlertView extends View +module.exports = class ProblemAlertView extends CocoView className: 'problem-alert' template: template diff --git a/app/views/play/level/tome/spell_debug_view.coffee b/app/views/play/level/tome/spell_debug_view.coffee index 54fceb2f5..63e01f1b7 100644 --- a/app/views/play/level/tome/spell_debug_view.coffee +++ b/app/views/play/level/tome/spell_debug_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_debug' Range = ace.require('ace/range').Range TokenIterator = ace.require('ace/token_iterator').TokenIterator @@ -9,7 +9,7 @@ serializedClasses = Ellipse: require 'lib/world/ellipse' LineSegment: require 'lib/world/line_segment' -module.exports = class DebugView extends View +module.exports = class DebugView extends CocoView className: 'spell-debug-view' template: template diff --git a/app/views/play/level/tome/spell_list_entry_thangs_view.coffee b/app/views/play/level/tome/spell_list_entry_thangs_view.coffee index 43f54f2cd..eeba83590 100644 --- a/app/views/play/level/tome/spell_list_entry_thangs_view.coffee +++ b/app/views/play/level/tome/spell_list_entry_thangs_view.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' ThangAvatarView = require 'views/play/level/thang_avatar_view' template = require 'templates/play/level/tome/spell_list_entry_thangs' -module.exports = class SpellListEntryThangsView extends View +module.exports = class SpellListEntryThangsView extends CocoView className: 'spell-list-entry-thangs-view' template: template diff --git a/app/views/play/level/tome/spell_list_entry_view.coffee b/app/views/play/level/tome/spell_list_entry_view.coffee index cd39559a8..05f18b23a 100644 --- a/app/views/play/level/tome/spell_list_entry_view.coffee +++ b/app/views/play/level/tome/spell_list_entry_view.coffee @@ -1,11 +1,11 @@ # TODO: This still needs a way to send problem states to its Thang -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' ThangAvatarView = require 'views/play/level/thang_avatar_view' SpellListEntryThangsView = require 'views/play/level/tome/spell_list_entry_thangs_view' template = require 'templates/play/level/tome/spell_list_entry' -module.exports = class SpellListEntryView extends View +module.exports = class SpellListEntryView extends CocoView tagName: 'div' #'li' className: 'spell-list-entry-view' template: template diff --git a/app/views/play/level/tome/spell_list_view.coffee b/app/views/play/level/tome/spell_list_view.coffee index f18eacb9b..9212bd04f 100644 --- a/app/views/play/level/tome/spell_list_view.coffee +++ b/app/views/play/level/tome/spell_list_view.coffee @@ -4,12 +4,12 @@ # TODO: showTopDivider should change when we reorder -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_list' {me} = require 'lib/auth' SpellListEntryView = require './spell_list_entry_view' -module.exports = class SpellListView extends View +module.exports = class SpellListView extends CocoView className: 'spell-list-view' id: 'spell-list-view' template: template diff --git a/app/views/play/level/tome/spell_palette_entry_view.coffee b/app/views/play/level/tome/spell_palette_entry_view.coffee index 1996b1972..e09116876 100644 --- a/app/views/play/level/tome/spell_palette_entry_view.coffee +++ b/app/views/play/level/tome/spell_palette_entry_view.coffee @@ -1,10 +1,10 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_palette_entry' {me} = require 'lib/auth' filters = require 'lib/image_filter' DocFormatter = require './doc_formatter' -module.exports = class SpellPaletteEntryView extends View +module.exports = class SpellPaletteEntryView extends CocoView tagName: 'div' # Could also try <code> instead of <div>, but would need to adjust colors className: 'spell-palette-entry-view' template: template diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee index 4482da630..89914fb3e 100644 --- a/app/views/play/level/tome/spell_palette_view.coffee +++ b/app/views/play/level/tome/spell_palette_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_palette' {me} = require 'lib/auth' filters = require 'lib/image_filter' @@ -8,7 +8,7 @@ EditorConfigModal = require '../modal/editor_config_modal' N_ROWS = 4 -module.exports = class SpellPaletteView extends View +module.exports = class SpellPaletteView extends CocoView id: 'spell-palette-view' template: template controlsEnabled: true diff --git a/app/views/play/level/tome/spell_toolbar_view.coffee b/app/views/play/level/tome/spell_toolbar_view.coffee index a3f86db10..39916d56c 100644 --- a/app/views/play/level/tome/spell_toolbar_view.coffee +++ b/app/views/play/level/tome/spell_toolbar_view.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_toolbar' -module.exports = class SpellToolbarView extends View +module.exports = class SpellToolbarView extends CocoView className: 'spell-toolbar-view' template: template progressHoverDelay: 500 diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index a92b708f5..3f6ec643d 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell' {me} = require 'lib/auth' filters = require 'lib/image_filter' @@ -8,7 +8,7 @@ SpellDebugView = require './spell_debug_view' SpellToolbarView = require './spell_toolbar_view' LevelComponent = require 'models/LevelComponent' -module.exports = class SpellView extends View +module.exports = class SpellView extends CocoView id: 'spell-view' className: 'shown' template: template diff --git a/app/views/play/level/tome/thang_list_entry_view.coffee b/app/views/play/level/tome/thang_list_entry_view.coffee index 79d9bfa27..06756c898 100644 --- a/app/views/play/level/tome/thang_list_entry_view.coffee +++ b/app/views/play/level/tome/thang_list_entry_view.coffee @@ -1,13 +1,13 @@ # TODO: be useful to add error indicator states to the spellsPopoverTemplate # TODO: reordering based on errors isn't working yet -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' ThangAvatarView = require 'views/play/level/thang_avatar_view' template = require 'templates/play/level/tome/thang_list_entry' spellsPopoverTemplate = require 'templates/play/level/tome/thang_list_entry_spells' {me} = require 'lib/auth' -module.exports = class ThangListEntryView extends View +module.exports = class ThangListEntryView extends CocoView tagName: 'div' #'li' className: 'thang-list-entry-view' template: template diff --git a/app/views/play/level/tome/thang_list_view.coffee b/app/views/play/level/tome/thang_list_view.coffee index a931e06e7..9f34e2977 100644 --- a/app/views/play/level/tome/thang_list_view.coffee +++ b/app/views/play/level/tome/thang_list_view.coffee @@ -1,12 +1,12 @@ # The ThangListView lives in the code area behind the SpellView, so that when you don't have a spell, you can select any Thang. # It just ha a bunch of ThangListEntryViews (which are mostly ThangAvatarViews) in a few sections. -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/thang_list' {me} = require 'lib/auth' ThangListEntryView = require './thang_list_entry_view' -module.exports = class ThangListView extends View +module.exports = class ThangListView extends CocoView className: 'thang-list-view' id: 'thang-list-view' template: template diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee index d709797e7..3ef45258c 100644 --- a/app/views/play/level/tome/tome_view.coffee +++ b/app/views/play/level/tome/tome_view.coffee @@ -27,7 +27,7 @@ # The SpellListView shows spells to which your team has read or readwrite access. # It doubles as a Thang selector, since it's there when nothing is selected. -View = require 'views/kinds/CocoView' +CocoView = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/tome' {me} = require 'lib/auth' Spell = require './spell' @@ -38,7 +38,7 @@ CastButtonView = require './cast_button_view' window.SHIM_WORKER_PATH = '/javascripts/workers/catiline_worker_shim.js' -module.exports = class TomeView extends View +module.exports = class TomeView extends CocoView id: 'tome-view' template: template controlsEnabled: true From 59b723b890ab856105bf2bc3491fb15cefd8563a Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 17:22:26 -0700 Subject: [PATCH 38/58] Refactoring View to ModalView. --- app/views/editor/level/component/new.coffee | 4 ++-- app/views/editor/level/fork_view.coffee | 4 ++-- app/views/editor/level/modal/world_select.coffee | 4 ++-- app/views/editor/level/system/add.coffee | 4 ++-- app/views/editor/level/system/new.coffee | 4 ++-- app/views/modal/auth_modal.coffee | 4 ++-- app/views/modal/contact_modal.coffee | 4 ++-- app/views/modal/diplomat_suggestion_modal.coffee | 4 ++-- app/views/modal/employer_signup_modal.coffee | 4 ++-- app/views/modal/model_modal.coffee | 4 ++-- app/views/modal/recover_modal.coffee | 4 ++-- app/views/modal/wizard_settings_modal.coffee | 4 ++-- app/views/play/ladder/play_modal.coffee | 4 ++-- app/views/play/level/modal/docs_modal.coffee | 4 ++-- app/views/play/level/modal/editor_config_modal.coffee | 4 ++-- app/views/play/level/modal/infinite_loop_modal.coffee | 4 ++-- app/views/play/level/modal/keyboard_shortcuts_modal.coffee | 4 ++-- app/views/play/level/modal/multiplayer_modal.coffee | 4 ++-- app/views/play/level/modal/reload_modal.coffee | 4 ++-- app/views/play/level/modal/victory_modal.coffee | 4 ++-- 20 files changed, 40 insertions(+), 40 deletions(-) diff --git a/app/views/editor/level/component/new.coffee b/app/views/editor/level/component/new.coffee index a1f2985ce..314cf2c86 100644 --- a/app/views/editor/level/component/new.coffee +++ b/app/views/editor/level/component/new.coffee @@ -1,10 +1,10 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/editor/level/component/new' LevelComponent = require 'models/LevelComponent' forms = require 'lib/forms' {me} = require 'lib/auth' -module.exports = class LevelComponentNewView extends View +module.exports = class LevelComponentNewView extends ModalView id: 'editor-level-component-new-modal' template: template instant: false diff --git a/app/views/editor/level/fork_view.coffee b/app/views/editor/level/fork_view.coffee index 522a21b1c..2b3f7cfea 100644 --- a/app/views/editor/level/fork_view.coffee +++ b/app/views/editor/level/fork_view.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/editor/level/fork' forms = require 'lib/forms' Level = require 'models/Level' -module.exports = class LevelForkView extends View +module.exports = class LevelForkView extends ModalView id: 'editor-level-fork-modal' template: template instant: false diff --git a/app/views/editor/level/modal/world_select.coffee b/app/views/editor/level/modal/world_select.coffee index adbbd11d3..4274a76ec 100644 --- a/app/views/editor/level/modal/world_select.coffee +++ b/app/views/editor/level/modal/world_select.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/editor/level/modal/world_select' Surface = require 'lib/surface/Surface' ThangType = require 'models/ThangType' -module.exports = class WorldSelectModal extends View +module.exports = class WorldSelectModal extends ModalView id: 'select-point-modal' template: template modalWidthPercent: 80 diff --git a/app/views/editor/level/system/add.coffee b/app/views/editor/level/system/add.coffee index 28a362809..f0c3b7490 100644 --- a/app/views/editor/level/system/add.coffee +++ b/app/views/editor/level/system/add.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/editor/level/system/add' availableSystemTemplate = require 'templates/editor/level/system/available_system' LevelSystem = require 'models/LevelSystem' @@ -8,7 +8,7 @@ class LevelSystemSearchCollection extends CocoCollection url: '/db/level_system' model: LevelSystem -module.exports = class LevelSystemAddView extends View +module.exports = class LevelSystemAddView extends ModalView id: 'editor-level-system-add-modal' template: template instant: true diff --git a/app/views/editor/level/system/new.coffee b/app/views/editor/level/system/new.coffee index 1ddd8d158..86b959f01 100644 --- a/app/views/editor/level/system/new.coffee +++ b/app/views/editor/level/system/new.coffee @@ -1,10 +1,10 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/editor/level/system/new' LevelSystem = require 'models/LevelSystem' forms = require 'lib/forms' {me} = require 'lib/auth' -module.exports = class LevelSystemNewView extends View +module.exports = class LevelSystemNewView extends ModalView id: 'editor-level-system-new-modal' template: template instant: false diff --git a/app/views/modal/auth_modal.coffee b/app/views/modal/auth_modal.coffee index 9d32de0ae..ead7af8b9 100644 --- a/app/views/modal/auth_modal.coffee +++ b/app/views/modal/auth_modal.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/auth' {loginUser, createUser, me} = require 'lib/auth' forms = require 'lib/forms' User = require 'models/User' application = require 'application' -module.exports = class AuthModalView extends View +module.exports = class AuthModalView extends ModalView id: 'auth-modal' template: template mode: 'login' # or 'signup' diff --git a/app/views/modal/contact_modal.coffee b/app/views/modal/contact_modal.coffee index 0851c9ee9..c8a6db460 100644 --- a/app/views/modal/contact_modal.coffee +++ b/app/views/modal/contact_modal.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/contact' forms = require 'lib/forms' @@ -18,7 +18,7 @@ contactSchema = type: 'string' minLength: 1 -module.exports = class ContactView extends View +module.exports = class ContactView extends ModalView id: 'contact-modal' template: template closeButton: true diff --git a/app/views/modal/diplomat_suggestion_modal.coffee b/app/views/modal/diplomat_suggestion_modal.coffee index 48312ad36..c0abed5e7 100644 --- a/app/views/modal/diplomat_suggestion_modal.coffee +++ b/app/views/modal/diplomat_suggestion_modal.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/diplomat_suggestion' {me} = require 'lib/auth' forms = require 'lib/forms' -module.exports = class DiplomatSuggestionView extends View +module.exports = class DiplomatSuggestionView extends ModalView id: 'diplomat-suggestion-modal' template: template diff --git a/app/views/modal/employer_signup_modal.coffee b/app/views/modal/employer_signup_modal.coffee index 5355e26c9..db766d979 100644 --- a/app/views/modal/employer_signup_modal.coffee +++ b/app/views/modal/employer_signup_modal.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/employer_signup_modal' forms = require 'lib/forms' User = require 'models/User' auth = require 'lib/auth' me = auth.me -module.exports = class EmployerSignupView extends View +module.exports = class EmployerSignupView extends ModalView id: 'employer-signup' template: template closeButton: true diff --git a/app/views/modal/model_modal.coffee b/app/views/modal/model_modal.coffee index 50b0cdd8a..a5fbc5ce5 100644 --- a/app/views/modal/model_modal.coffee +++ b/app/views/modal/model_modal.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/model' -module.exports = class ModelModal extends View +module.exports = class ModelModal extends ModalView id: 'model-modal' template: template plain: true diff --git a/app/views/modal/recover_modal.coffee b/app/views/modal/recover_modal.coffee index c65fc1f8a..5f8e9a17d 100644 --- a/app/views/modal/recover_modal.coffee +++ b/app/views/modal/recover_modal.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/recover' forms = require 'lib/forms' {genericFailure} = require 'lib/errors' @@ -9,7 +9,7 @@ filterKeyboardEvents = (allowedEvents, func) -> return unless e.keyCode in allowedEvents or not e.keyCode return func(splat...) -module.exports = class RecoverModalView extends View +module.exports = class RecoverModalView extends ModalView id: 'recover-modal' template: template diff --git a/app/views/modal/wizard_settings_modal.coffee b/app/views/modal/wizard_settings_modal.coffee index 12732b28e..d8527ee74 100644 --- a/app/views/modal/wizard_settings_modal.coffee +++ b/app/views/modal/wizard_settings_modal.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/modal/wizard_settings' WizardSprite = require 'lib/surface/WizardSprite' ThangType = require 'models/ThangType' @@ -6,7 +6,7 @@ ThangType = require 'models/ThangType' forms = require 'lib/forms' User = require 'models/User' -module.exports = class WizardSettingsModal extends View +module.exports = class WizardSettingsModal extends ModalView id: 'wizard-settings-modal' template: template closesOnClickOutside: false diff --git a/app/views/play/ladder/play_modal.coffee b/app/views/play/ladder/play_modal.coffee index 41bf1e22b..0d7494950 100644 --- a/app/views/play/ladder/play_modal.coffee +++ b/app/views/play/ladder/play_modal.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/ladder/play_modal' ThangType = require 'models/ThangType' {me} = require 'lib/auth' LeaderboardCollection = require 'collections/LeaderboardCollection' {teamDataFromLevel} = require './utils' -module.exports = class LadderPlayModal extends View +module.exports = class LadderPlayModal extends ModalView id: 'ladder-play-modal' template: template closeButton: true diff --git a/app/views/play/level/modal/docs_modal.coffee b/app/views/play/level/modal/docs_modal.coffee index 9970b8916..a046df051 100644 --- a/app/views/play/level/modal/docs_modal.coffee +++ b/app/views/play/level/modal/docs_modal.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/docs' Article = require 'models/Article' utils = require 'lib/utils' # let's implement this once we have the docs database schema set up -module.exports = class DocsModal extends View +module.exports = class DocsModal extends ModalView template: template id: 'docs-modal' diff --git a/app/views/play/level/modal/editor_config_modal.coffee b/app/views/play/level/modal/editor_config_modal.coffee index 5f8fd878f..c7dc162d1 100644 --- a/app/views/play/level/modal/editor_config_modal.coffee +++ b/app/views/play/level/modal/editor_config_modal.coffee @@ -1,8 +1,8 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/editor_config' {me} = require 'lib/auth' -module.exports = class EditorConfigModal extends View +module.exports = class EditorConfigModal extends ModalView id: 'level-editor-config-modal' template: template aceConfig: {} diff --git a/app/views/play/level/modal/infinite_loop_modal.coffee b/app/views/play/level/modal/infinite_loop_modal.coffee index ff89e229f..6436c7667 100644 --- a/app/views/play/level/modal/infinite_loop_modal.coffee +++ b/app/views/play/level/modal/infinite_loop_modal.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/infinite_loop' -module.exports = class InfiniteLoopModal extends View +module.exports = class InfiniteLoopModal extends ModalView id: '#infinite-loop-modal' template: template diff --git a/app/views/play/level/modal/keyboard_shortcuts_modal.coffee b/app/views/play/level/modal/keyboard_shortcuts_modal.coffee index 816bd3f10..41c15df9d 100644 --- a/app/views/play/level/modal/keyboard_shortcuts_modal.coffee +++ b/app/views/play/level/modal/keyboard_shortcuts_modal.coffee @@ -1,7 +1,7 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/keyboard_shortcuts' -module.exports = class KeyboardShortcutsModal extends View +module.exports = class KeyboardShortcutsModal extends ModalView id: 'keyboard-shortcuts-modal' template: template diff --git a/app/views/play/level/modal/multiplayer_modal.coffee b/app/views/play/level/modal/multiplayer_modal.coffee index c7e02b157..6645ca2f3 100644 --- a/app/views/play/level/modal/multiplayer_modal.coffee +++ b/app/views/play/level/modal/multiplayer_modal.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/multiplayer' {me} = require 'lib/auth' LadderSubmissionView = require 'views/play/common/ladder_submission_view' -module.exports = class MultiplayerModal extends View +module.exports = class MultiplayerModal extends ModalView id: 'level-multiplayer-modal' template: template diff --git a/app/views/play/level/modal/reload_modal.coffee b/app/views/play/level/modal/reload_modal.coffee index f8b454f1c..f7089e05c 100644 --- a/app/views/play/level/modal/reload_modal.coffee +++ b/app/views/play/level/modal/reload_modal.coffee @@ -1,9 +1,9 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/reload' # let's implement this once we have the docs database schema set up -module.exports = class ReloadModal extends View +module.exports = class ReloadModal extends ModalView id: '#reload-code-modal' template: template diff --git a/app/views/play/level/modal/victory_modal.coffee b/app/views/play/level/modal/victory_modal.coffee index 6ee9cabef..03c8d72d8 100644 --- a/app/views/play/level/modal/victory_modal.coffee +++ b/app/views/play/level/modal/victory_modal.coffee @@ -1,11 +1,11 @@ -View = require 'views/kinds/ModalView' +ModalView = require 'views/kinds/ModalView' template = require 'templates/play/level/modal/victory' {me} = require 'lib/auth' LadderSubmissionView = require 'views/play/common/ladder_submission_view' LevelFeedback = require 'models/LevelFeedback' utils = require 'lib/utils' -module.exports = class VictoryModal extends View +module.exports = class VictoryModal extends ModalView id: 'level-victory-modal' template: template From 2d7b6eb1452f30f03b48298f52249baff61eb6ff Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 20:12:59 -0700 Subject: [PATCH 39/58] Updated code language logos. Added code language blurb i18n tags. --- .../images/common/code_languages/c_icon.png | Bin 0 -> 3108 bytes .../common/code_languages/clojure_icon.png | Bin 0 -> 3094 bytes .../code_languages/clojure_small.png} | Bin .../code_languages/coffeescript_icon.png | Bin 0 -> 3018 bytes .../code_languages/coffeescript_small.png} | Bin .../images/common/code_languages/cpp_icon.png | Bin 0 -> 3093 bytes .../common/code_languages/csharp_icon.png | Bin 0 -> 3077 bytes .../images/common/code_languages/go_icon.png | Bin 0 -> 2983 bytes .../images/common/code_languages/io_icon.png | Bin 0 -> 4113 bytes .../code_languages/io_small.png} | Bin .../common/code_languages/java_icon.png | Bin 0 -> 3105 bytes .../common/code_languages/javascript_icon.png | Bin 0 -> 3976 bytes .../code_languages/javascript_small.png} | Bin .../images/common/code_languages/lua_icon.png | Bin 0 -> 2917 bytes .../code_languages/lua_small.png} | Bin .../images/common/code_languages/php_icon.png | Bin 0 -> 3020 bytes .../common/code_languages/python_icon.png | Bin 0 -> 3008 bytes .../code_languages/python_small.png} | Bin .../common/code_languages/ruby_icon.png | Bin 0 -> 3073 bytes .../common/code_languages/swift_icon.png | Bin 0 -> 2961 bytes app/locale/en.coffee | 6 ++++ app/styles/home.sass | 17 ++++++++--- app/styles/play/ladder/ladder_tab.sass | 5 ++-- app/styles/play/ladder/my_matches_tab.sass | 5 ++-- app/styles/play/ladder/play_modal.sass | 10 +++---- app/styles/play/level/tome/spell_palette.sass | 28 +++++++++++------- app/templates/home.jade | 12 ++++---- app/templates/play/ladder/ladder_tab.jade | 4 +-- app/templates/play/ladder/my_matches_tab.jade | 2 +- app/templates/play/ladder/play_modal.jade | 8 ++--- app/views/home_view.coffee | 2 +- 31 files changed, 59 insertions(+), 40 deletions(-) create mode 100755 app/assets/images/common/code_languages/c_icon.png create mode 100755 app/assets/images/common/code_languages/clojure_icon.png rename app/assets/images/{pages/home/language_logo_clojure.png => common/code_languages/clojure_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/coffeescript_icon.png rename app/assets/images/{pages/home/language_logo_coffeescript.png => common/code_languages/coffeescript_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/cpp_icon.png create mode 100755 app/assets/images/common/code_languages/csharp_icon.png create mode 100755 app/assets/images/common/code_languages/go_icon.png create mode 100644 app/assets/images/common/code_languages/io_icon.png rename app/assets/images/{pages/home/language_logo_io.png => common/code_languages/io_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/java_icon.png create mode 100644 app/assets/images/common/code_languages/javascript_icon.png rename app/assets/images/{pages/home/language_logo_javascript.png => common/code_languages/javascript_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/lua_icon.png rename app/assets/images/{pages/home/language_logo_lua.png => common/code_languages/lua_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/php_icon.png create mode 100755 app/assets/images/common/code_languages/python_icon.png rename app/assets/images/{pages/home/language_logo_python.png => common/code_languages/python_small.png} (100%) create mode 100755 app/assets/images/common/code_languages/ruby_icon.png create mode 100755 app/assets/images/common/code_languages/swift_icon.png diff --git a/app/assets/images/common/code_languages/c_icon.png b/app/assets/images/common/code_languages/c_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..99cd55241df4b94612ea0f61f6984561304c52cf GIT binary patch literal 3108 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/clojure_icon.png b/app/assets/images/common/code_languages/clojure_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..7152f84c0ca9f772194cf8da1a4ae67426686d9a GIT binary patch literal 3094 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_clojure.png b/app/assets/images/common/code_languages/clojure_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_clojure.png rename to app/assets/images/common/code_languages/clojure_small.png diff --git a/app/assets/images/common/code_languages/coffeescript_icon.png b/app/assets/images/common/code_languages/coffeescript_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..502db9b06bc3af2ad3060afe03588aba55619110 GIT binary patch literal 3018 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 M07*qoM6N<$f)%@!EC2ui literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_coffeescript.png b/app/assets/images/common/code_languages/coffeescript_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_coffeescript.png rename to app/assets/images/common/code_languages/coffeescript_small.png diff --git a/app/assets/images/common/code_languages/cpp_icon.png b/app/assets/images/common/code_languages/cpp_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..c3067378cca155e9e81de53c6adf38e294f1c2cb GIT binary patch literal 3093 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/csharp_icon.png b/app/assets/images/common/code_languages/csharp_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..d3eff9260c6f09acaddc205ec7c31d94fc67128e GIT binary patch literal 3077 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 Tlxi+a00000NkvXXu0mjfW<0v? literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/go_icon.png b/app/assets/images/common/code_languages/go_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..ecbfb0d6ab769009983d760404a64aa92b6363d5 GIT binary patch literal 2983 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/io_icon.png b/app/assets/images/common/code_languages/io_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6c58fe4eafcd179cb0df77a7fe4123a42c8903 GIT binary patch literal 4113 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_io.png b/app/assets/images/common/code_languages/io_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_io.png rename to app/assets/images/common/code_languages/io_small.png diff --git a/app/assets/images/common/code_languages/java_icon.png b/app/assets/images/common/code_languages/java_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e39879caeb661b8ae5d8f969991c3f49ee21ccaa GIT binary patch literal 3105 zcmV++4BqpJP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00009a7bBm000XU z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_ zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0 zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc= zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0003@Nkl<Zc-oYbu}T9$7=*vbf`V0w6bnhE?d1{TBSa8Q6(Q+Pxh7!B6jv#N77?#Y zz*GSP`UuG*n52xA5aEhcDGm<SBHVhLV}mXnyZ`(<^Un>Nd%ZqZZy#$;%ZC8GPuEnP z?Ag}aW5?=^J*rR5U03V^39(V>8uj)PHUTmBxxC8nBwGc}+%J6|1S^>PjDq4H1r*fX zyaCzB0AdkF04&0Yqr(30)GbG&ph$1*0q|H00Qd}}tOG^XK_b{Z>GJZt0t%oucMXBW zO<4+VI-$nz{Q?kW24ym6r%0xYSi7jZdCJlfVnP}Ot4t0_-;qL3Hw0Qkmxo%wbQxzd z`1ecfPdxe)4@V066HjA~6tspet)Yt}g()EBzP8_}bakEH+nvzpZPJ__sN}o5D5-Rv v#%#UZ?RiPfzGDC!DVQ!}<98Cw*83R%eu1qDm&tC@00000NkvXXu0mjfsy4$O literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/javascript_icon.png b/app/assets/images/common/code_languages/javascript_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4580f350b4b9412f0dbd539340325962c5bbba0e GIT binary patch literal 3976 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 F{{(R7Ih+6h literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_javascript.png b/app/assets/images/common/code_languages/javascript_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_javascript.png rename to app/assets/images/common/code_languages/javascript_small.png diff --git a/app/assets/images/common/code_languages/lua_icon.png b/app/assets/images/common/code_languages/lua_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e97873a331f62e51f94b8fa374a596233ebf6510 GIT binary patch literal 2917 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 P00000NkvXXu0mjfDMxEp literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_lua.png b/app/assets/images/common/code_languages/lua_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_lua.png rename to app/assets/images/common/code_languages/lua_small.png diff --git a/app/assets/images/common/code_languages/php_icon.png b/app/assets/images/common/code_languages/php_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..35757de0b61b2f778df0e3ef459938f74ef5f350 GIT binary patch literal 3020 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 O0000<MNUMnLSTYoi=V{+ literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/python_icon.png b/app/assets/images/common/code_languages/python_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..b8575c4f842679491f5c631b62a76d18062200c6 GIT binary patch literal 3008 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 CK##fr literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_python.png b/app/assets/images/common/code_languages/python_small.png similarity index 100% rename from app/assets/images/pages/home/language_logo_python.png rename to app/assets/images/common/code_languages/python_small.png diff --git a/app/assets/images/common/code_languages/ruby_icon.png b/app/assets/images/common/code_languages/ruby_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..7e1192d7abf52cba6f1f82b272051b79c867ed81 GIT binary patch literal 3073 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 P00000NkvXXu0mjfD=f2y literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/swift_icon.png b/app/assets/images/common/code_languages/swift_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..e789c15168232d60bb83864e1699406a9b6fbe0c GIT binary patch literal 2961 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 Hu0mjfcJg_# literal 0 HcmV?d00001 diff --git a/app/locale/en.coffee b/app/locale/en.coffee index a3cf8152b..2b8549b5e 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -100,6 +100,12 @@ for_beginners: "For Beginners" multiplayer: "Multiplayer" for_developers: "For Developers" + javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." + python_blurb: "Simple yet powerful, Python is a great general purpose programming language." + coffeescript_blurb: "Nicer JavaScript syntax." + clojure_blurb: "A modern Lisp." + lua_blurb: "Game scripting language." + io_blurb: "Simple but obscure." play: choose_your_level: "Choose Your Level" diff --git a/app/styles/home.sass b/app/styles/home.sass index c58133fb8..f5abd9c0f 100644 --- a/app/styles/home.sass +++ b/app/styles/home.sass @@ -167,6 +167,10 @@ h2 margin: 15px 0 5px + p + overflow: hidden + height: 40px + .secondary-code-languages margin-left: -10px @@ -201,17 +205,22 @@ margin: 0 padding: 0 + p + white-space: nowrap + text-overflow: ellipsis + overflow: hidden + #coffeescript .code-language-logo - background: transparent url(/images/pages/home/language_logo_coffeescript.png) no-repeat center + background: transparent url(/images/common/code_languages/coffeescript_small.png) no-repeat center #clojure .code-language-logo - background: transparent url(/images/pages/home/language_logo_clojure.png) no-repeat center + background: transparent url(/images/common/code_languages/clojure_small.png) no-repeat center #lua .code-language-logo - background: transparent url(/images/pages/home/language_logo_lua.png) no-repeat center + background: transparent url(/images/common/code_languages/lua_small.png) no-repeat center #io .code-language-logo - background: transparent url(/images/pages/home/language_logo_io.png) no-repeat center + background: transparent url(/images/common/code_languages/io_small.png) no-repeat center #multiplayer-launch-modal diff --git a/app/styles/play/ladder/ladder_tab.sass b/app/styles/play/ladder/ladder_tab.sass index c92726c9c..2529f6280 100644 --- a/app/styles/play/ladder/ladder_tab.sass +++ b/app/styles/play/ladder/ladder_tab.sass @@ -53,6 +53,5 @@ .code-language-cell padding: 0 10px - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center - background-size: contain - height: 19px + background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center + height: 16px diff --git a/app/styles/play/ladder/my_matches_tab.sass b/app/styles/play/ladder/my_matches_tab.sass index 741a3a534..13aca340d 100644 --- a/app/styles/play/ladder/my_matches_tab.sass +++ b/app/styles/play/ladder/my_matches_tab.sass @@ -40,6 +40,5 @@ .code-language-cell padding: 0 10px - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center - background-size: contain - height: 19px + background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center + height: 16px diff --git a/app/styles/play/ladder/play_modal.sass b/app/styles/play/ladder/play_modal.sass index 3587c557f..6050df159 100644 --- a/app/styles/play/ladder/play_modal.sass +++ b/app/styles/play/ladder/play_modal.sass @@ -98,12 +98,12 @@ .code-language position: absolute - background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center + background: transparent url(/images/common/code_languages/javascript_small.png) no-repeat center center background-size: contain - width: 40px - height: 40px - right: -5px - top: -15px + width: 50px + height: 50px + right: -0px + top: -30px display: block .my-name diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass index 3e2f78794..6c5a12f32 100644 --- a/app/styles/play/level/tome/spell_palette.sass +++ b/app/styles/play/level/tome/spell_palette.sass @@ -70,10 +70,10 @@ .code-language-logo position: absolute - width: 20px - height: 20px - left: 12px - top: 34px + width: 16px + height: 16px + left: 16px + top: 36px z-index: 10 background-color: transparent background-repeat: no-repeat @@ -81,21 +81,27 @@ cursor: pointer &.javascript - background-image: url(/images/pages/home/language_logo_javascript.png) + background-image: url(/images/common/code_languages/javascript_icon.png) &.python - background-image: url(/images/pages/home/language_logo_python.png) + background-image: url(/images/common/code_languages/python_icon.png) &.coffeescript - background-image: url(/images/pages/home/language_logo_coffeescript.png) + background-image: url(/images/common/code_languages/coffeescript_icon.png) &.clojure - background-image: url(/images/pages/home/language_logo_clojure.png) + background-image: url(/images/common/code_languages/clojure_icon.png) &.lua - background-image: url(/images/pages/home/language_logo_lua.png) + background-image: url(/images/common/code_languages/lua_icon.png) &.io - background-image: url(/images/pages/home/language_logo_io.png) + background-image: url(/images/common/code_languages/io_icon.png) + + &:hover + outline: 1px outset #ccc + + &:active + outline: 1px inset #ccc html.no-borderimage #spell-palette-view span.code-palette-background display: none img.code-palette-background - display: block \ No newline at end of file + display: block diff --git a/app/templates/home.jade b/app/templates/home.jade index 02775696a..6d9d939df 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -10,14 +10,14 @@ block content .code-language#javascript(data-code-language='javascript') .code-wizard h2 JavaScript - p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. + p(data-i18n="home.javascript_blurb") The language of the web. Great for writing websites, web apps, HTML5 games, and servers. .col-md-6 .code-language.beta#python(data-code-language='python') .code-wizard .code-language-beta h2 Python - p Simple yet powerful, Python is a great general purpose programming language. + p(data-i18n="home.python_blurb") Simple yet powerful, Python is a great general purpose programming language. .secondary-code-languages.row .col-md-3 @@ -26,7 +26,7 @@ block content .code-wizard .code-language-beta h3 CoffeeScript - p Nicer JavaScript syntax + p(data-i18n="home.coffeescript_blurb") Nicer JavaScript syntax. .col-md-3 .code-language.beta#clojure(data-code-language='clojure') @@ -34,7 +34,7 @@ block content .code-wizard .code-language-beta h3 Clojure - p A modern Lisp + p(data-i18n="home.clojure_blurb") A modern Lisp. .col-md-3 .code-language.beta#lua(data-code-language='lua') @@ -42,7 +42,7 @@ block content .code-wizard .code-language-beta h3 Lua - p Game scripting language + p(data-i18n="home.lua_blurb") Game scripting language. .col-md-3 .code-language.beta#io(data-code-language='io', title="Careful: Io is still quite buggy") @@ -50,7 +50,7 @@ block content .code-wizard .code-language-beta h3 Io - p Simple but obscure + p(data-i18n="home.io_blurb") Simple but obscure. .alert.alert-danger.lt-ie10 strong(data-i18n="home.no_ie") CodeCombat does not run in Internet Explorer 9 or older. Sorry! diff --git a/app/templates/play/ladder/ladder_tab.jade b/app/templates/play/ladder/ladder_tab.jade index 4d682243a..515397e1f 100644 --- a/app/templates/play/ladder/ladder_tab.jade +++ b/app/templates/play/ladder/ladder_tab.jade @@ -21,7 +21,7 @@ div#columns.row for session, rank in topSessions - var myRow = session.get('creator') == me.id tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id) - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)") td.rank-cell= rank + 1 td.score-cell= Math.round(session.get('totalScore') * 100) td.name-col-cell= session.get('creatorName') || "Anonymous" @@ -35,7 +35,7 @@ div#columns.row for session in team.leaderboard.nearbySessions() - var myRow = session.get('creator') == me.id tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id) - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)") td.rank-cell= session.rank td.score-cell= Math.round(session.get('totalScore') * 100) td.name-col-cell= session.get('creatorName') || "Anonymous" diff --git a/app/templates/play/ladder/my_matches_tab.jade b/app/templates/play/ladder/my_matches_tab.jade index a08f6651b..bf4d9e856 100644 --- a/app/templates/play/ladder/my_matches_tab.jade +++ b/app/templates/play/ladder/my_matches_tab.jade @@ -39,7 +39,7 @@ div#columns.row span(data-i18n="general.loss").loss Loss if match.state === 'tie' span(data-i18n="general.tie").tie Tie - td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + match.codeLanguage + ".png)") + td.code-language-cell(style="background-image: url(/images/common/code_languages/" + match.codeLanguage + "_icon.png)") td.name-cell= match.opponentName || "Anonymous" td.time-cell= match.when td.battle-cell diff --git a/app/templates/play/ladder/play_modal.jade b/app/templates/play/ladder/play_modal.jade index 841203b2f..c25c3a1f5 100644 --- a/app/templates/play/ladder/play_modal.jade +++ b/app/templates/play/ladder/play_modal.jade @@ -33,7 +33,7 @@ block modal-body-content span= myName div.opponent-name.name-label span(data-i18n="ladder.simple_ai") Simple AI - //span.code-language(style="background-image: url(/images/pages/home/language_logo_javascript.png)") + //span.code-language(style="background-image: url(/images/common/code_languages/javascript_small.png)") div.difficulty span(data-i18n="ladder.warmup") Warmup div(data-i18n="ladder.vs").vs VS @@ -50,7 +50,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.easy.opponentName if challengers.easy.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.easy.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.easy.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.easy") Easy div(data-i18n="ladder.vs").vs VS @@ -67,7 +67,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.medium.opponentName if challengers.medium.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.medium.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.medium.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.medium") Medium div(data-i18n="ladder.vs").vs VS @@ -84,7 +84,7 @@ block modal-body-content div.opponent-name.name-label span= challengers.hard.opponentName if challengers.hard.codeLanguage - span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.hard.codeLanguage + ".png)") + span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.hard.codeLanguage + "_small.png)") div.difficulty span(data-i18n="general.hard") Hard div(data-i18n="ladder.vs").vs VS diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index 40eb72e88..ff3b287c2 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -52,7 +52,7 @@ module.exports = class HomeView extends View @updateLanguageLogos codeLanguage updateLanguageLogos: (codeLanguage) -> - @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/pages/home/language_logo_#{codeLanguage}.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) + @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) onCodeLanguageSelected: (e) -> target = $(e.target).closest('.code-language') From 207f0adf11e8b7b8d963b4ba816786b60c40f443 Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Thu, 17 Jul 2014 20:13:30 -0700 Subject: [PATCH 40/58] Propagated i18n tags for code language blurbs. --- app/locale/ar.coffee | 6 ++++++ app/locale/bg.coffee | 6 ++++++ app/locale/ca.coffee | 6 ++++++ app/locale/cs.coffee | 6 ++++++ app/locale/da.coffee | 6 ++++++ app/locale/de-AT.coffee | 6 ++++++ app/locale/de-CH.coffee | 6 ++++++ app/locale/de-DE.coffee | 6 ++++++ app/locale/de.coffee | 6 ++++++ app/locale/el.coffee | 6 ++++++ app/locale/en-AU.coffee | 6 ++++++ app/locale/en-GB.coffee | 6 ++++++ app/locale/en-US.coffee | 6 ++++++ app/locale/es-419.coffee | 6 ++++++ app/locale/es-ES.coffee | 6 ++++++ app/locale/es.coffee | 6 ++++++ app/locale/fa.coffee | 6 ++++++ app/locale/fi.coffee | 6 ++++++ app/locale/fr.coffee | 6 ++++++ app/locale/he.coffee | 6 ++++++ app/locale/hi.coffee | 6 ++++++ app/locale/hu.coffee | 6 ++++++ app/locale/id.coffee | 6 ++++++ app/locale/it.coffee | 6 ++++++ app/locale/ja.coffee | 6 ++++++ app/locale/ko.coffee | 6 ++++++ app/locale/lt.coffee | 6 ++++++ app/locale/ms.coffee | 6 ++++++ app/locale/nb.coffee | 6 ++++++ app/locale/nl-BE.coffee | 6 ++++++ app/locale/nl-NL.coffee | 6 ++++++ app/locale/nl.coffee | 6 ++++++ app/locale/nn.coffee | 6 ++++++ app/locale/no.coffee | 6 ++++++ app/locale/pl.coffee | 6 ++++++ app/locale/pt-BR.coffee | 6 ++++++ app/locale/pt-PT.coffee | 6 ++++++ app/locale/pt.coffee | 6 ++++++ app/locale/ro.coffee | 6 ++++++ app/locale/ru.coffee | 6 ++++++ app/locale/sk.coffee | 6 ++++++ app/locale/sl.coffee | 6 ++++++ app/locale/sr.coffee | 6 ++++++ app/locale/sv.coffee | 6 ++++++ app/locale/th.coffee | 6 ++++++ app/locale/tr.coffee | 6 ++++++ app/locale/uk.coffee | 6 ++++++ app/locale/ur.coffee | 6 ++++++ app/locale/vi.coffee | 6 ++++++ app/locale/zh-HANS.coffee | 6 ++++++ app/locale/zh-HANT.coffee | 6 ++++++ app/locale/zh-WUU-HANS.coffee | 6 ++++++ app/locale/zh-WUU-HANT.coffee | 6 ++++++ app/locale/zh.coffee | 6 ++++++ 54 files changed, 324 insertions(+) diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee index 0d95ef171..40f349b61 100644 --- a/app/locale/ar.coffee +++ b/app/locale/ar.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index 5620a6b60..0609ffaf8 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "български език", englishDescri # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Избери своето ниво" diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index 3a1a35800..0ab50115a 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr for_beginners: "Per a principiants" multiplayer: "Multijugador" for_developers: "Per a Desenvolupadors" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escull el teu nivell" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index 5836d1889..cd470a43b 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Zvolte si úroveň" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index 470764cd8..1ffef227c 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans for_beginners: "For Begyndere" multiplayer: "Multiplayer" for_developers: "For Udviklere" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Vælg Dit Level" diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee index 1242212fd..9c4c0c144 100644 --- a/app/locale/de-AT.coffee +++ b/app/locale/de-AT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription: # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee index b8b40dbac..d83d4959a 100644 --- a/app/locale/de-CH.coffee +++ b/app/locale/de-CH.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge for_beginners: "Für Afänger" multiplayer: "Multiplayer" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähl dis Level us" diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee index 69570107d..d94fbbbfd 100644 --- a/app/locale/de-DE.coffee +++ b/app/locale/de-DE.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription: for_beginners: "Für Anfänger" multiplayer: "Mehrspieler" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähle dein Level" diff --git a/app/locale/de.coffee b/app/locale/de.coffee index 4f83a118e..aa72ab375 100644 --- a/app/locale/de.coffee +++ b/app/locale/de.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra for_beginners: "Für Anfänger" multiplayer: "Mehrspieler" for_developers: "Für Entwickler" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wähle dein Level" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index 41d735d5d..0405a50f3 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre for_beginners: "Για αρχάριους" # multiplayer: "Multiplayer" for_developers: "Για προγραμματιστές" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Διάλεξε την πίστα σου" diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee index 29d87cbe7..772111136 100644 --- a/app/locale/en-AU.coffee +++ b/app/locale/en-AU.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee index 0ba3466cc..e6fadc26e 100644 --- a/app/locale/en-GB.coffee +++ b/app/locale/en-GB.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee index ebecb2bd2..61513d098 100644 --- a/app/locale/en-US.coffee +++ b/app/locale/en-US.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 84d5ddd86..6d4b7892c 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip for_beginners: "Para Principiantes" multiplayer: "Multijugador" for_developers: "Para Desarrolladores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index 565025b19..956682ba2 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis for_beginners: "Para principiantes" multiplayer: "Multijugador" for_developers: "Para programadores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/es.coffee b/app/locale/es.coffee index dcc2e7ff1..3382d263f 100644 --- a/app/locale/es.coffee +++ b/app/locale/es.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t for_beginners: "Para principiantes" multiplayer: "Multijugador" for_developers: "Para desarrolladores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Elige tu nivel" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index e043269ae..5643e4646 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "مرحله خود را انتخاب کنید" diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee index cd1da3699..d045279e8 100644 --- a/app/locale/fi.coffee +++ b/app/locale/fi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index 94a3dd46d..1d717c739 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "français", englishDescription: "French", t for_beginners: "Pour débutants" multiplayer: "Multijoueurs" for_developers: "Pour développeurs" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Choisissez votre niveau" diff --git a/app/locale/he.coffee b/app/locale/he.coffee index 7dda67ac8..4621f2dce 100644 --- a/app/locale/he.coffee +++ b/app/locale/he.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", for_beginners: "למתחילים" multiplayer: "רב-משתתפים" for_developers: "למומחים" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "בחר את השלב" diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee index 85ccf7dac..ca51ba569 100644 --- a/app/locale/hi.coffee +++ b/app/locale/hi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 2aef84d38..390e20a98 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t for_beginners: "Kezdőknek" # multiplayer: "Multiplayer" for_developers: "Fejlesztőknek" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Válaszd ki a pályát!" diff --git a/app/locale/id.coffee b/app/locale/id.coffee index ae972660d..fe9958166 100644 --- a/app/locale/id.coffee +++ b/app/locale/id.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index e1535c040..a1ed0fbaf 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t for_beginners: "Per Principianti" # multiplayer: "Multiplayer" for_developers: "Per Sviluppatori" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Scegli il tuo livello" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index fce997c9a..acdc9ffb6 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", for_beginners: "初心者向け" multiplayer: "マルチプレイヤー" for_developers: "開発者向け" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "レベル選択" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index 791630d0e..fdc645eb4 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t for_beginners: "초보자용" multiplayer: "멀티플레이어" for_developers: "개발자용" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "레벨을 선택하세요." diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee index dd8420fff..c34b07ae6 100644 --- a/app/locale/lt.coffee +++ b/app/locale/lt.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee index 7149e3b19..62d60bdb5 100644 --- a/app/locale/ms.coffee +++ b/app/locale/ms.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index 855b05b2b..cfcf2cd07 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Velg Ditt Nivå" diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee index 42221b38d..20eef3d90 100644 --- a/app/locale/nl-BE.coffee +++ b/app/locale/nl-BE.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription: for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee index f54d02efd..5db7557ee 100644 --- a/app/locale/nl-NL.coffee +++ b/app/locale/nl-NL.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee index 74b8c35b4..0fccad1af 100644 --- a/app/locale/nl.coffee +++ b/app/locale/nl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t for_beginners: "Voor Beginners" multiplayer: "Multiplayer" for_developers: "Voor ontwikkelaars" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Kies Je Level" diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee index c7e58789f..180420e6a 100644 --- a/app/locale/nn.coffee +++ b/app/locale/nn.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/no.coffee b/app/locale/no.coffee index 4085d5128..d319665ee 100644 --- a/app/locale/no.coffee +++ b/app/locale/no.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Velg Ditt Nivå" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index 6cbdc2007..a047b1f31 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish for_beginners: "Dla początkujących" # multiplayer: "Multiplayer" for_developers: "Dla developerów" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Wybierz poziom" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index f7758b9be..21ef4fcf3 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Desenvolvedores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha seu estágio" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index ec504f6db..9e51664d6 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha o Seu Nível" diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee index ea24890d3..e69e86463 100644 --- a/app/locale/pt.coffee +++ b/app/locale/pt.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Escolha seu estágio" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index baefa15fb..145382ca0 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman for_beginners: "Pentru Începători" multiplayer: "Multiplayer" for_developers: "Pentru dezvoltatori" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Alege nivelul" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index 9ac956a4d..cb96b0e6e 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi for_beginners: "Новичкам" multiplayer: "Мультиплеер" for_developers: "Разработчикам" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Выберите ваш уровень" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 20be15ee8..135b8acf0 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", for_beginners: "Pre začiatočníkov" # multiplayer: "Multiplayer" for_developers: "Pre vývojárov" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Vyber si úroveň" diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee index 73c8947f7..6517ac37d 100644 --- a/app/locale/sl.coffee +++ b/app/locale/sl.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index 4b748189c..ae0508b0f 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Изабери ниво" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index ac9d04d87..1e6356c4f 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr for_beginners: "För nybörjare" multiplayer: "Flera spelare" for_developers: "För utvecklare" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Välj din nivå" diff --git a/app/locale/th.coffee b/app/locale/th.coffee index debe63e0f..0ffadebae 100644 --- a/app/locale/th.coffee +++ b/app/locale/th.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index 83596230d..6c52344fa 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t for_beginners: "Yeni Başlayanlar için" multiplayer: "Çoklu-oyuncu Modu" for_developers: "Geliştiriciler için" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Seviye Seçimi" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index beb7659ec..65c15f9c3 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "українська мова", englishDesc for_beginners: "Для новачків" multiplayer: "Командна гра" for_developers: "Для розробників" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Оберіть свій рівень" diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee index a0ca20473..9672ccdbd 100644 --- a/app/locale/ur.coffee +++ b/app/locale/ur.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu", # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 55bf539c7..f58f20fb4 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "Chọn Trình của bạn" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index 665af4c82..7523c69af 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese for_beginners: "适合初学者" multiplayer: "多人游戏" for_developers: "适合开发者" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "选择关卡" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index 96a11fc42..b4a96e647 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "選取關卡" diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee index 5d5a8c757..ea129d982 100644 --- a/app/locale/zh-WUU-HANS.coffee +++ b/app/locale/zh-WUU-HANS.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." # play: # choose_your_level: "Choose Your Level" diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee index 6fdb7dd26..361a86c11 100644 --- a/app/locale/zh-WUU-HANT.coffee +++ b/app/locale/zh-WUU-HANT.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio for_beginners: "適合學起頭個人" multiplayer: "聚隊打遊戲" for_developers: "適合開發個人" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "揀關數" diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee index 7a2b8c97e..811f7a5ca 100644 --- a/app/locale/zh.coffee +++ b/app/locale/zh.coffee @@ -100,6 +100,12 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra # for_beginners: "For Beginners" # multiplayer: "Multiplayer" # for_developers: "For Developers" +# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." +# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." +# coffeescript_blurb: "Nicer JavaScript syntax." +# clojure_blurb: "A modern Lisp." +# lua_blurb: "Game scripting language." +# io_blurb: "Simple but obscure." play: choose_your_level: "选取难度" From 051fd9ecbc014143e919cfee40ed51a2710783ab Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Fri, 18 Jul 2014 13:40:05 +0100 Subject: [PATCH 41/58] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 9e51664d6..215d1aad0 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" -# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." -# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." -# coffeescript_blurb: "Nicer JavaScript syntax." -# clojure_blurb: "A modern Lisp." -# lua_blurb: "Game scripting language." -# io_blurb: "Simple but obscure." + javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." + python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." + coffeescript_blurb: "Sintaxe do Javascript mais agradável." + clojure_blurb: "Um Lisp moderno" + lua_blurb: "Linguagem para scripts de jogos" + io_blurb: "Simples mas obscuro" play: choose_your_level: "Escolha o Seu Nível" From 3ac1d6c77cae0b493cf1b23b9b89396e9e764ae3 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com> Date: Fri, 18 Jul 2014 15:48:36 +0100 Subject: [PATCH 42/58] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 215d1aad0..47879bfe7 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: for_beginners: "Para Iniciantes" multiplayer: "Multijogador" for_developers: "Para Programadores" - javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." - python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." - coffeescript_blurb: "Sintaxe do Javascript mais agradável." - clojure_blurb: "Um Lisp moderno" - lua_blurb: "Linguagem para scripts de jogos" - io_blurb: "Simples mas obscuro" +# javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores." +# python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais." +# coffeescript_blurb: "Sintaxe do Javascript mais agradável." +# clojure_blurb: "Um Lisp moderno" +# lua_blurb: "Linguagem para scripts de jogos" +# io_blurb: "Simples mas obscuro" play: choose_your_level: "Escolha o Seu Nível" From a6ab97703410aeadc73e864374e2a0151b44cdb5 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 11:05:37 -0700 Subject: [PATCH 43/58] Add candidate finish reminder email --- server/routes/mail.coffee | 104 +++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 26a5e8ed0..e7deb6707 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -1,5 +1,6 @@ mail = require '../commons/mail' MailSent = require '../mail/sent/MailSent' +UserRemark = require '../users/remarks/UserRemark' User = require '../users/User' async = require 'async' errors = require '../commons/errors' @@ -28,6 +29,9 @@ setupScheduledEmails = -> , taskFunction: employerNewCandidatesAvailableTask frequencyMs: 10 * 60 * 1000 #10 minutes + , + taskFunction: unapprovedCandidateFinishProfileTask + frequencyMs: 10 * 60 * 1000 ] for mailTask in mailTasks @@ -35,7 +39,7 @@ setupScheduledEmails = -> testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!" -### Candidate Update Reminder Task ### +### Approved Candidate Update Reminder Task ### candidateUpdateProfileTask = -> mailTaskName = "candidateUpdateProfileTask" @@ -132,7 +136,103 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) -> sendwithus.api.send context, (err, result) -> log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err sendEmailCallback null -### End Candidate Update Reminder Task ### +### End Approved Candidate Update Reminder Task ### + +### Unapproved Candidate Finish Reminder Task ### +unapprovedCandidateFinishProfileTask = -> + mailTaskName = "unapprovedCandidateFinishProfileTask" + lockDurationMs = 2 * 60 * 1000 + currentDate = new Date() + timeRanges = [] + for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']] + timeRanges.push + start: generateWeekOffset currentDate, weekPair[0] + end: generateWeekOffset currentDate, weekPair[1] + name: weekPair[2] + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" + async.each timeRanges, emailUnapprovedCandidateTimeRange.bind({mailTaskName: mailTaskName}), (err) -> + if err + log.error "There was an error sending the candidate profile update reminder emails: #{err}" + else + log.info "Completed mail task #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) -> + waterfallContext = + "timeRange": timeRange + "mailTaskName": @mailTaskName + async.waterfall [ + findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext) + (unfilteredCandidates, cb) -> + async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null) + (unfilteredPotentialCandidates, cb) -> + async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null) + (filteredCandidates, cb) -> + async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb + ], emailTimeRangeCallback + +findAllUnapprovedCandidatesWithinTimeRange = (cb) -> + findParameters = + "jobProfile": + $exists: true + "jobProfile.updated": + $gt: @timeRange.start + $lte: @timeRange.end + "jobProfileApproved": false + selection = "_id email jobProfile.name jobProfile.updated emails" + User.find(findParameters).select(selection).lean().exec cb + +ignoredCandidateFilter = (candidate, cb) -> + findParameters = + "user": candidate._id + "contactName": "Ignore" + UserRemark.count findParameters, (err, results) -> + if err? then return true + return cb Boolean(results.length) + +unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) -> + if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false + return sentEmailFilterCallback true + findParameters = + "user": candidate._id + "mailTask": @mailTaskName + "metadata.timeRangeName": @timeRange.name + "metadata.updated": candidate.jobProfile.updated + MailSent.find(findParameters).lean().exec (err, sentMail) -> + if err? + log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!" + sentEmailFilterCallback true + else + sentEmailFilterCallback Boolean(sentMail.length) + +sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) -> + if err? + log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}" + return sendEmailCallback err + context = + email_id: "tem_RXyjzmc7S2HJH287pfoSPN" + recipient: + address: candidate.email + name: candidate.jobProfile.name + email_data: + user_profile: "http://codecombat.com/account/profile/#{candidate._id}" + recipient_address: encodeURIComponent(candidate.email) + log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})" + newSentMail = + mailTask: @mailTaskName + user: candidate._id + metadata: + timeRangeName: @timeRange.name + updated: candidate.jobProfile.updated + MailSent.create newSentMail, (err) -> + if err? then return sendEmailCallback err + sendwithus.api.send context, (err, result) -> + log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err + sendEmailCallback null +### End Unapproved Candidate Finish Reminder Task ### + ### Internal Candidate Update Reminder Email ### internalCandidateUpdateTask = -> mailTaskName = "internalCandidateUpdateTask" From 321bce121c8772b38be3f837bff2f6ff21d1f88e Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 14:50:31 -0700 Subject: [PATCH 44/58] Edited task schema --- app/schemas/models/user_remark.coffee | 18 +++++++++++++++++- server/routes/mail.coffee | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/schemas/models/user_remark.coffee b/app/schemas/models/user_remark.coffee index 839ce1380..260164a3b 100644 --- a/app/schemas/models/user_remark.coffee +++ b/app/schemas/models/user_remark.coffee @@ -12,7 +12,23 @@ _.extend UserRemarkSchema.properties, history: c.array {title: 'History', description: 'Records of our interactions with the user.'}, c.object {title: 'Record'}, {date: c.date(title: 'Date'), content: {title: 'Content', type: 'string', format: 'markdown'}} tasks: c.array {title: 'Tasks', description: 'Task entries: when to email the contact about something.'}, - c.object {title: 'Task'}, {date: c.date(title: 'Date'), action: {title: 'Action', type: 'string'}} + c.object {title: 'Task'}, + date: c.date + title: 'Date' + action: + title: 'Action' + type: 'string' + status: + title: 'Status' + description: 'The current status of the task' + type: 'string' + enum: ['Not started', 'In progress', 'Completed'] + notes: + title: 'Notes' + description: 'Notes about the task in progress' + type: 'string' + format: 'markdown' + # denormalization userName: {title: 'Player Name', type: 'string'} diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index e0ef70220..0786a5f62 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -403,6 +403,10 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> cb null ### End Employer New Candidates Available Email ### + +### Task Emails ### +userRemarkTaskEmailTask = -> + ### New Recruit Leaderboard Email ### ### From 18631ec5b152468d0889713f9d4e9bd1c1a36aa8 Mon Sep 17 00:00:00 2001 From: George Saines <gsaines@gmail.com> Date: Fri, 18 Jul 2014 15:42:53 -0700 Subject: [PATCH 45/58] upgrading our level icons --- app/assets/images/pages/home/language_js.png | Bin 9586 -> 9268 bytes .../images/pages/home/language_python.png | Bin 7633 -> 8282 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/assets/images/pages/home/language_js.png b/app/assets/images/pages/home/language_js.png index 75db0f254b6ce29a7e5b869ec1d8ed2e98ee2c80..9da73cf33c8c7ee7d6e29f82ccb850e866574279 100644 GIT binary patch delta 8701 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 Q65TFsbpy59XLgbQ3wXY0g#Z8m delta 9001 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 OpQ$Lkl`oUE2>CzL&<<Sy diff --git a/app/assets/images/pages/home/language_python.png b/app/assets/images/pages/home/language_python.png index 80e09da9eddaaf746a569d80f1671a5e4b1e5f1d..71f23d4ad89a4618e74065bd1edbd01e3b13886d 100644 GIT binary patch delta 7530 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 delta 6876 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 Wl{nr3RxTa@0000<MNUMnLSTYWXr)X5 From 90a4a1b635db04f91564537ad8a3e4afeaa6ea47 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:22:06 -0700 Subject: [PATCH 46/58] Added setProjection so CocoModels can more easily get subsets of data. --- app/models/CocoModel.coffee | 15 +++++++++++---- test/app/models/CocoModel.spec.coffee | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index 045843306..5da19cab3 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -13,8 +13,10 @@ class CocoModel extends Backbone.Model getMe: -> @me or @me = require('lib/auth').me - initialize: -> - super() + initialize: (attributes, options) -> + super(arguments...) + options ?= {} + @setProjection options.project if not @constructor.className console.error("#{@} needs a className set.") @addSchemaDefaults() @@ -22,6 +24,8 @@ class CocoModel extends Backbone.Model @on 'error', @onError, @ @on 'add', @onLoaded, @ @saveBackup = _.debounce(@saveBackup, 500) + + setProjection: (@project) -> type: -> @constructor.className @@ -116,8 +120,11 @@ class CocoModel extends Backbone.Model console.debug 'Patching', @get('name') or @, keys @save(attrs, options) - fetch: -> - @jqxhr = super(arguments...) + fetch: (options) -> + options ?= {} + options.data ?= {} + options.data.project = @project.join(',') if @project + @jqxhr = super(options) @loading = true @jqxhr diff --git a/test/app/models/CocoModel.spec.coffee b/test/app/models/CocoModel.spec.coffee index 67e019c9a..7f2529466 100644 --- a/test/app/models/CocoModel.spec.coffee +++ b/test/app/models/CocoModel.spec.coffee @@ -14,6 +14,14 @@ class BlandClass extends CocoModel urlRoot: '/db/bland' describe 'CocoModel', -> + describe 'setProjection', -> + it 'takes an array of properties to project and adds them as a query parameter', -> + b = new BlandClass({}) + b.setProjection ['number', 'object'] + b.fetch() + request = jasmine.Ajax.requests.mostRecent() + expect(decodeURIComponent(request.url).indexOf('project=number,object')).toBeGreaterThan(-1) + describe 'save', -> it 'saves to db/<urlRoot>', -> From 52447f9e227d7da4e9a1a1d31313d8403a1e70f8 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:12 -0700 Subject: [PATCH 47/58] Fixed the avatar endpoint handling when the user object DNE. --- server/users/user_handler.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 020d30f20..275807ad7 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -219,6 +219,7 @@ UserHandler = class UserHandler extends Handler avatar: (req, res, id) -> @modelClass.findById(id).exec (err, document) => return @sendDatabaseError(res, err) if err + return @sendNotFoundError(res) unless document photoURL = document?.get('photoURL') if photoURL photoURL = "/file/#{photoURL}" From 4658c3000f34d0655adbca47a861d3ec68635cd5 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:28:52 -0700 Subject: [PATCH 48/58] Extended getLatestVersion for Handler to also be able to accept project parameters. --- server/commons/Handler.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index a796b705e..9dfca705b 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -232,7 +232,11 @@ module.exports = class Handler query['version.minor'] = minorVersion unless _.isNaN(minorVersion) sort = { 'version.major': -1, 'version.minor': -1 } args = [query] - args.push PROJECT if req.query.project + if req.query.project + projection = {} + fields = if req.query.project is 'true' then _.keys(PROJECT) else req.query.project.split(',') + projection[field] = 1 for field in fields + args.push projection @modelClass.findOne(args...).sort(sort).exec (err, doc) => return @sendNotFoundError(res) unless doc? return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc) From 74425103d18e8122865fb0c17aa0c124f9e5e1c2 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 16:29:26 -0700 Subject: [PATCH 49/58] Fixed some DemoView issues, mainly clicking links from one demo to another. --- app/views/DemoView.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/DemoView.coffee b/app/views/DemoView.coffee index a3b65c781..d18190162 100644 --- a/app/views/DemoView.coffee +++ b/app/views/DemoView.coffee @@ -35,6 +35,7 @@ module.exports = DemoView = class DemoView extends CocoView @loadDemoingLibs() unless DemoView.loaded loadDemoingLibs: -> + DemoView.loaded = true @queue = new createjs.LoadQueue() @queue.on('complete', @scriptsLoaded, @) window.jasmine = {} # so that mock-ajax properly loads. It expects jasmine to be loaded @@ -81,8 +82,14 @@ module.exports = DemoView = class DemoView extends CocoView view = demoFunc() return unless view @$el.find('#demo-area').empty().append(view.$el) + view.afterInsert() # TODO, maybe handle root views differently than modal views differently than everything else? getAllDemoFiles: -> allFiles = window.require.list() (f for f in allFiles when f.indexOf('.demo') > -1) + + destroy: -> + # hack to get jasmine tests to properly run again on clicking links, and make sure if you + # leave this page (say, back to the main site) that test stuff doesn't follow you. + document.location.reload() From 9ad166048d37daaef40a6d961c871c003a13d3e8 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Thu, 17 Jul 2014 09:12:21 -0700 Subject: [PATCH 50/58] Some work the job profile page. Added a demo view, mainly added a modal view for viewing raw player code. --- app/schemas/models/level.coffee | 2 + app/schemas/models/level_session.coffee | 2 +- app/styles/account/profile.sass | 3 +- app/styles/base.sass | 13 +- .../common/level_session_code_view.sass | 25 + .../account/job_profile_code_modal.jade | 12 + app/templates/account/profile.jade | 7 +- app/templates/base.jade | 2 +- app/templates/common/level_session_code.jade | 13 + app/views/account/JobProfileCodeModal.coffee | 25 + app/views/account/profile_view.coffee | 14 +- app/views/common/LevelSessionCodeView.coffee | 50 ++ .../editor/level/settings_tab_view.coffee | 2 +- app/views/kinds/RootView.coffee | 7 + server/levels/level_handler.coffee | 2 + server/users/user_handler.coffee | 2 +- .../common/LevelSessionCodeView.demo.coffee | 13 + .../views/user/JobProfileView.demo.coffee | 576 ++++++++++++++++++ 18 files changed, 754 insertions(+), 16 deletions(-) create mode 100644 app/styles/common/level_session_code_view.sass create mode 100644 app/templates/account/job_profile_code_modal.jade create mode 100644 app/templates/common/level_session_code.jade create mode 100644 app/views/account/JobProfileCodeModal.coffee create mode 100644 app/views/common/LevelSessionCodeView.coffee create mode 100644 test/demo/views/common/LevelSessionCodeView.demo.coffee create mode 100644 test/demo/views/user/JobProfileView.demo.coffee diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee index eba42f599..262c02d18 100644 --- a/app/schemas/models/level.coffee +++ b/app/schemas/models/level.coffee @@ -230,12 +230,14 @@ _.extend LevelSchema.properties, title: 'Next Level', description: 'Reference to the next level players will play after beating this one.' } + employerDescription: { type:'string', format: 'markdown', title: 'Employer Description' } scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema # TODO: uniqueness should be based on 'original', not whole thing victory: c.object {title: 'Victory Screen', default: {}, properties: {'body': {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'}, i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}}} i18n: {type: 'object', format: 'i18n', props: ['name', 'description'], description: 'Help translate this level'} icon: {type: 'string', format: 'image-file', title: 'Icon'} + banner: {type: 'string', format: 'image-file', title: 'Banner'} goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial']) showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always']) diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee index f4f629914..92ff0f5ba 100644 --- a/app/schemas/models/level_session.coffee +++ b/app/schemas/models/level_session.coffee @@ -13,7 +13,7 @@ LevelSessionPlayerSchema = c.object changes: type: 'Number' -LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion']}, +LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion'], links: [{rel: 'db', href: '/db/level/{(original)}/version/{(majorVersion)}'}]}, original: c.objectId({}) majorVersion: type: 'integer' diff --git a/app/styles/account/profile.sass b/app/styles/account/profile.sass index 05a06f6ee..a661ea611 100644 --- a/app/styles/account/profile.sass +++ b/app/styles/account/profile.sass @@ -127,13 +127,14 @@ text-align: center ul.links + text-align: center li.has-icon display: inline-block img margin: 0 0 10px 0 li.has-icon:not(:nth-child(5)) img - margin: 0 10px 10px 0 + margin: 0 5px 10px 5px #contact-candidate margin-top: 20px diff --git a/app/styles/base.sass b/app/styles/base.sass index eae0d473b..c873d3d0f 100644 --- a/app/styles/base.sass +++ b/app/styles/base.sass @@ -24,13 +24,16 @@ h1 h2 h3 h4 @include box-sizing(border-box) #outer-content-wrapper + background: #B4B4B4 + +#outer-content-wrapper.show-background background: #8cc63f url(/images/pages/base/repeat-tile.png) top center -#intermediate-content-wrapper - background: url(/images/pages/base/sky_repeater.png) repeat-x + #intermediate-content-wrapper + background: url(/images/pages/base/sky_repeater.png) repeat-x -#inner-content-wrapper - background: url(/images/pages/base/background_texture.png) top center no-repeat + #inner-content-wrapper + background: url(/images/pages/base/background_texture.png) top center no-repeat #front-summary-points-left width: 250px @@ -70,7 +73,7 @@ h1 h2 h3 h4 &:hover color: $white -a[data-toggle="modal"] +a cursor: pointer .share-buttons, .partner-badges diff --git a/app/styles/common/level_session_code_view.sass b/app/styles/common/level_session_code_view.sass new file mode 100644 index 000000000..270d9a0d3 --- /dev/null +++ b/app/styles/common/level_session_code_view.sass @@ -0,0 +1,25 @@ +.level-session-code-view + #level-icon + max-width: 60% + max-height: 150px + margin-right: 10px + display: inline-block + float: right + margin-bottom: 20px + + #level-meta-data + width: 35% + button + float: right + + #session-code + clear: both + margin-top: 20px + + h3 + font-family: Arial + margin: 0 + + .code + height: 600px + border: 2px solid black \ No newline at end of file diff --git a/app/templates/account/job_profile_code_modal.jade b/app/templates/account/job_profile_code_modal.jade new file mode 100644 index 000000000..6f5703ef6 --- /dev/null +++ b/app/templates/account/job_profile_code_modal.jade @@ -0,0 +1,12 @@ +extends /templates/modal/modal_base + +block modal-header-content + h3 Applicant Code for + span.spl= session.get('levelName') + +block modal-body-content + .level-session-code-view + +block modal-footer + .modal-footer + button(data-dismiss="modal", data-i18n="modal.close").btn Close diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade index 11c0d6956..2699a3ac1 100644 --- a/app/templates/account/profile.jade +++ b/app/templates/account/profile.jade @@ -181,13 +181,12 @@ block content ul.sessions each session in sessions li - - var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id); - a(href=sessionLink) + a.session-link(data-session-id=session._id) span= session.levelName if session.team - span #{session.team} + span.spl - #{session.team} if session.codeLanguage != 'javascript' - span - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} + span.spl - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]} .middle-column.full-height-column .sub-column diff --git a/app/templates/base.jade b/app/templates/base.jade index 01a67687c..6c18d420c 100644 --- a/app/templates/base.jade +++ b/app/templates/base.jade @@ -49,7 +49,7 @@ body a.header-font(href='/community', data-i18n="nav.community") Community block outer_content - #outer-content-wrapper + #outer-content-wrapper(class=showBackground ? 'show-background' : '') #intermediate-content-wrapper #inner-content-wrapper .main-content-area diff --git a/app/templates/common/level_session_code.jade b/app/templates/common/level_session_code.jade new file mode 100644 index 000000000..ad998e89d --- /dev/null +++ b/app/templates/common/level_session_code.jade @@ -0,0 +1,13 @@ +div#session-info + img(src='/file/'+levelIcon alt='levelIcon')#level-icon + div#level-meta-data + a.btn.btn-primary(href=sessionLink, target=_blank) Spectate + p!= levelDescription + +div#session-code + for spell in levelSpells + .panel.panel-success + .panel-heading + h3= spell.name + .panel-body + .code(data-height=spell.height)= spell.code \ No newline at end of file diff --git a/app/views/account/JobProfileCodeModal.coffee b/app/views/account/JobProfileCodeModal.coffee new file mode 100644 index 000000000..397de97cf --- /dev/null +++ b/app/views/account/JobProfileCodeModal.coffee @@ -0,0 +1,25 @@ +ModalView = require 'views/kinds/ModalView' +template = require 'templates/account/job_profile_code_modal' +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +console.log 'template', template + +module.exports = class JobProfileCodeModal extends ModalView + id: 'job_profile_code_modal' + template: template + modalWidthPercent: 90 + plain: true + + constructor: (options) -> + super(arguments...) + @session = options.session + + getRenderData: -> + c = super() + c.session = @session + c + + afterRender: -> + super() + codeView = new LevelSessionCodeView({session:@session}) + @insertSubView(codeView, @$el.find('.level-session-code-view')) + \ No newline at end of file diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee index 213b89a97..ca33ba8e8 100644 --- a/app/views/account/profile_view.coffee +++ b/app/views/account/profile_view.coffee @@ -1,4 +1,4 @@ -View = require 'views/kinds/RootView' +RootView = require 'views/kinds/RootView' template = require 'templates/account/profile' User = require 'models/User' LevelSession = require 'models/LevelSession' @@ -9,6 +9,7 @@ JobProfileView = require 'views/account/job_profile_view' UserRemark = require 'models/UserRemark' forms = require 'lib/forms' ModelModal = require 'views/modal/model_modal' +JobProfileCodeModal = require './JobProfileCodeModal' class LevelSessionsCollection extends CocoCollection url: -> "/db/user/#{@userID}/level.sessions/employer" @@ -25,9 +26,11 @@ adminContacts = [ {id: '52a57252a89409700d0000d9', name: 'Ignore'} ] -module.exports = class ProfileView extends View +module.exports = class ProfileView extends RootView id: 'profile-view' template: template + showBackground: false + subscriptions: 'linkedin-loaded': 'onLinkedInLoaded' @@ -49,6 +52,7 @@ module.exports = class ProfileView extends View 'keyup .editable-profile .editable-array input': 'onEditArray' 'click .editable-profile a': 'onClickLinkWhileEditing' 'change #admin-contact': 'onAdminContactChanged' + 'click .session-link': 'onSessionLinkPressed' constructor: (options, @userID) -> @userID ?= me.id @@ -584,3 +588,9 @@ module.exports = class ProfileView extends View {name: t('account_profile.next_photo'), weight: 2, container: '#profile-photo-container', fn: modified 'photoURL'} {name: t('account_profile.next_active'), weight: 1, fn: modified 'active'} ] + + onSessionLinkPressed: (e) -> + sessionID = $(e.target).closest('.session-link').data('session-id') + session = _.find @sessions.models, (session) -> session.id is sessionID + modal = new JobProfileCodeModal({session:session}) + @openModalView modal \ No newline at end of file diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee new file mode 100644 index 000000000..768793115 --- /dev/null +++ b/app/views/common/LevelSessionCodeView.coffee @@ -0,0 +1,50 @@ +CocoView = require 'views/kinds/CocoView' +template = require 'templates/common/level_session_code' + +Level = require 'models/Level' +LevelSession = require 'models/LevelSession' + +module.exports = class LevelSessionCodeView extends CocoView + className: 'level-session-code-view' + template: template + + constructor: (options) -> + super(options) + @session = options.session + @level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level) + @level.setProjection ['employerDescription', 'name', 'icon', 'banner', 'slug'] + @supermodel.loadModel @level, 'level' + + getRenderData: -> + c = super() + c.levelIcon = @level.get('banner') or @level.get('icon') + c.levelName = @level.get('name') + c.levelDescription = marked(@level.get('employerDescription') or '') + c.levelSpells = @organizeCode() + c.sessionLink = "/play/level/" + (@level.get('slug') or @level.id) + "?team=" + (@session.get('team') || 'humans') + "&session=" + @session.id + c + + afterRender: -> + super() + @$el.find('.code').each (index, codeEl) -> + height = parseInt($(codeEl).data('height')) + $(codeEl).height(height) + editor = ace.edit codeEl + editor.setReadOnly true + aceSession = editor.getSession() + aceSession.setMode 'ace/mode/javascript' + + organizeCode: -> + team = @session.get('team') or 'humans' + teamSpells = @session.get('teamSpells')[team] or [] + filteredSpells = [] + for spell in teamSpells + code = @session.getSourceFor(spell) + lines = code.split('\n').length + height = lines * 16 + 20 + filteredSpells.push { + code: code + name: spell + height: height + } + filteredSpells \ No newline at end of file diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee index b3f99150c..21504830a 100644 --- a/app/views/editor/level/settings_tab_view.coffee +++ b/app/views/editor/level/settings_tab_view.coffee @@ -13,7 +13,7 @@ module.exports = class SettingsTabView extends View # not thangs or scripts or the backend stuff editableSettings: [ 'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals', - 'type', 'showsGuide' + 'type', 'showsGuide', 'banner', 'employerDescription' ] subscriptions: diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee index aac5dc64f..858c9fb48 100644 --- a/app/views/kinds/RootView.coffee +++ b/app/views/kinds/RootView.coffee @@ -17,6 +17,8 @@ filterKeyboardEvents = (allowedEvents, func) -> return func(splat...) module.exports = class RootView extends CocoView + showBackground: true + events: 'click #logout-button': 'logoutAccount' 'change .language-dropdown': 'onLanguageChanged' @@ -112,6 +114,11 @@ module.exports = class RootView extends CocoView @renderScrollbar() #@$('.antiscroll-wrap').antiscroll() # not yet, buggy + getRenderData: -> + c = super() + c.showBackground = @showBackground + c + afterRender: -> super(arguments...) @chooseTab(location.hash.replace('#', '')) if location.hash diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee index bcda60e1c..76d0ed8ac 100644 --- a/server/levels/level_handler.coffee +++ b/server/levels/level_handler.coffee @@ -25,6 +25,8 @@ LevelHandler = class LevelHandler extends Handler 'goals' 'type' 'showsGuide' + 'banner' + 'employerDescription' ] postEditableProperties: ['name'] diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 275807ad7..fbd13ec19 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -233,7 +233,7 @@ UserHandler = class UserHandler extends Handler getLevelSessionsForEmployer: (req, res, userID) -> return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions')) query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']} - projection = 'levelName levelID team playtime codeLanguage submitted code totalScore' + projection = 'levelName levelID team playtime codeLanguage submitted code totalScore teamSpells level' LevelSession.find(query).select(projection).exec (err, documents) => return @sendDatabaseError(res, err) if err documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents) diff --git a/test/demo/views/common/LevelSessionCodeView.demo.coffee b/test/demo/views/common/LevelSessionCodeView.demo.coffee new file mode 100644 index 000000000..a7aa3810e --- /dev/null +++ b/test/demo/views/common/LevelSessionCodeView.demo.coffee @@ -0,0 +1,13 @@ +LevelSessionCodeView = require 'views/common/LevelSessionCodeView' +LevelSession = require 'models/LevelSession' + +levelSessionData = {"_id":"5317ad4909098828ed071f4d","level":{"original":"53173f76c269d400000543c2","majorVersion":0},"team":"humans","levelID":"dungeon-arena","levelName":"Dungeon Arena","submitted":true,"totalScore":38.4584087145667,"code":{"programmable-librarian":{"chooseAction":"// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nif (this.canCast('slow', enemy)) {\n // Slow the enemy, or chase if out of range (30m).\n this.castSlow(enemy);\n if (this.distance(enemy) <= 50)\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n this.attack(enemy);\n}\nvar base = this.getFriends()[0];\nvar d = base.distance(enemy);\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n"},"human-base":{"chooseAction":"// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin'; // A fierce knight with battlecry abilities.\nhero = 'hushbaum'; // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n this.builtHero = this.build(hero);\n return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"},"hushbaum":{"chooseAction":"var enemy = this.getNearestEnemy();\nif (enemy) {\n if (!enemy.hasEffect('slow')) {\n this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n this.castSlow(enemy);\n }\n else {\n this.attack(enemy);\n }\n}\nelse {\n this.move({x: 70, y: 30});\n}\n"},"tharin":{"chooseAction":"var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n this.warcry();\n}\nelse if (enemy) {\n this.attack(enemy);\n}\nelse {\n this.move({x: 10, y: 30});\n}\n"},"tharin-1":{"chooseAction":"var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n var tmp0, tmp1;\n tmp1 = function () {\n _aether.logCallStart(this._aetherUserInfo); var enemies, enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;\n tmp2 = 'use strict';\n tmp3 = __interceptThis(this, __global);\n tmp4 = 'getEnemies';\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}]); enemies = tmp3[tmp4](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}], \"var enemies = this.getEnemies();\", this._aetherUserInfo);\n tmp5 = __interceptThis(this, __global);\n tmp6 = 'getNearest';\n tmp7 = enemies;\n _aether.logStatementStart([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}]); enemy = tmp5[tmp6](tmp7); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}], \"var enemy = this.getNearest(enemies);\", this._aetherUserInfo);\n tmp10 = __interceptThis(this, __global);\n tmp11 = 'getCooldown';\n _aether.logStatementStart([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}]); tmp12 = 'warcry'; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}], \"'warcry'\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}]); tmp9 = tmp10[tmp11](tmp12); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}], \"this.getCooldown('warcry')\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}]); tmp8 = !tmp9; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}], \"!this.getCooldown('warcry')\", this._aetherUserInfo);\n if (tmp8) {\n tmp13 = __interceptThis(this, __global);\n tmp14 = 'warcry';\n _aether.logStatementStart([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}]); tmp15 = tmp13[tmp14](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}], \"this.warcry()\", this._aetherUserInfo);\n } else {\n tmp16 = enemy;\n if (tmp16) {\n tmp17 = __interceptThis(this, __global);\n tmp18 = 'attack';\n tmp19 = enemy;\n _aether.logStatementStart([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}]); tmp20 = tmp17[tmp18](tmp19); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}], \"this.attack(enemy)\", this._aetherUserInfo);\n } else {\n tmp21 = __interceptThis(this, __global);\n tmp22 = 'move';\n _aether.logStatementStart([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}]); tmp24 = 10; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}], \"10\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}]); tmp25 = 30; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}], \"30\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}]); tmp23 = {\n x: tmp24,\n y: tmp25\n }; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}], \"{x: 10, y: 30}\", this._aetherUserInfo);\n _aether.logStatementStart([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}]); tmp26 = tmp21[tmp22](tmp23); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}], \"this.move({x: 10, y: 30})\", this._aetherUserInfo);\n }\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));"},"programmable-tharin":{"chooseAction":"/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n If they fully base race us, we actually do want to produce archers since they DPS faster\n The effective DPS on soldiers is better if they attack us\n but worse if they straight race us\n\n //not sure if this is good but...\n if they're attacking our base with a small number of units\n we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return; // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n var friend = friends[i];\n furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n} \nif (!this.getCooldown('warcry') && friends.length > 5) {\n this.warcry();\n} \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n this.shield();\n}\nelse {\n this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/"}},"teamSpells":{"ogres":["programmable-brawler/chooseAction","programmable-shaman/chooseAction","ogre-base/chooseAction"],"humans":["programmable-librarian/chooseAction","programmable-tharin/chooseAction","human-base/chooseAction"]},"submittedCodeLanguage":"javascript","playtime":9753,"codeLanguage":"javascript"} +levelData = {"_id":"53c997066567c600002a43d0","name":"Dungeon Arena","icon":"db/level/53173f76c269d400000543c2/11_dungeon.png","banner":"db/level/53173f76c269d400000543c2/dungeon_arena.png","employerDescription":"Players:\n* Attempt to destroy the enemy base.\n* Choose and control heroes to attack with.\n* Choose which types of lesser units to build and have limited control over them.\n* Try to write strategies that counter other enemy strategies.\n* Play on a small map.","systems":[],"thangs":[],"scripts":[],"documentation":{"generalArticles":[],"specificArticles":[]},"description":"This level is indescribably flarmy!","version":{"minor":0,"major":0,"isLatestMajor":true,"isLatestMinor":true}}; + +module.exports = -> + session = new LevelSession(levelSessionData) + v = new LevelSessionCodeView({session:session}) + request = jasmine.Ajax.requests.mostRecent() + request.response({status: 200, responseText: JSON.stringify(levelData)}) + console.log 'okay should be fine' + v diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee new file mode 100644 index 000000000..17ac8767b --- /dev/null +++ b/test/demo/views/user/JobProfileView.demo.coffee @@ -0,0 +1,576 @@ +ProfileView = require 'views/account/profile_view' + +responses = + '/db/user/joe/nameToID':'512ef4805a67a8c507000001' + + '/db/user/512ef4805a67a8c507000001': { + "_id": "512ef4805a67a8c507000001", + "__v": 47, + "email": "livelily@gmail.com", + "emailSubscriptions": [ + "announcement", + "notification", + "developer", + "level_creator", + "tester", + "article_editor", + "translator", + "support" + ], + "facebookID": "4301215", + "firstName": "Nick", + "gender": "male", + "lastName": "Winter", + "name": "Nick!", + "photoURL": "db/user/512ef4805a67a8c507000001/nick_wizard.png", + "volume": 0, + "wizardColor1": 0.4, + "testGroupNumber": 217, + "mailChimp": { + "leid": "70264209", + "euid": "c4418e2abd", + "email": "livelily@gmail.com" + }, + "hourOfCode": true, + "hourOfCodeComplete": true, + "signedCLA": "Fri Jan 03 2014 14:40:18 GMT-0800 (PST)", + "wizard": { + "colorConfig": { + "boots": { + "lightness": 0.1647058823529412, + "saturation": 0.023809523809523805, + "hue": 0 + }, + "spell": { + "hue": 0.7490196078431373, + "saturation": 0.4106280193236715, + "lightness": 0.5941176470588235 + }, + "cloud": { + "lightness": 0.14, + "saturation": 1, + "hue": 0 + }, + "clothes": { + "lightness": 0.1411764705882353, + "saturation": 0, + "hue": 0 + }, + "trim": { + "hue": 0.5, + "saturation": 0.009900990099009936, + "lightness": 0.19803921568627453 + } + } + }, + "aceConfig": { + "liveCompletion": true, + "indentGuides": true, + "invisibles": true, + "keyBindings": "emacs", + "behaviors": true, + "language": "javascript" + }, + "lastLevel": "drink-me", + "gplusID": "110703832132860599877", + "jobProfile": { + "photoURL": "db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg", + "links": [ +# { +# "name": "Twitter", +# "link": "https://twitter.com/nwinter" +# }, +# { +# "name": "Facebook", +# "link": "https://www.facebook.com/nwinter" +# }, + { + "name": "LinkedIn", + "link": "https://www.linkedin.com/in/nwinter" + }, + { + "name": "Blog", + "link": "http://blog.nickwinter.net/" + }, + { + "name": "Personal Site", + "link": "http://www.nickwinter.net/" + }, + { + "name": "GitHub", + "link": "https://github.com/nwinter" + }, + { + "name": "G+", + "link": "https://plus.google.com/u/0/+NickWinter" + } + ], + "projects": [ + { + "name": "The Motivation Hacker", + "description": "I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.", + "picture": "db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg", + "link": "http://www.nickwinter.net/motivation-hacker" + }, + { + "name": "Quantified Mind", + "description": "Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.", + "picture": "db/user/512ef4805a67a8c507000001/screenshot.png", + "link": "http://www.quantified-mind.com/" + }, + { + "link": "https://github.com/nwinter/telepath-logger", + "name": "Telepath", + "description": "A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).", + "picture": "db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067" + } + ], + "education": [ + { + "school": "Oberlin College", + "degree": "BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS", + "duration": "Aug 2004 - May 2008", + "description": "Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it." + } + ], + "work": [ + { + "employer": "CodeCombat", + "role": "Cofounder", + "duration": "Jan 2013 - present", + "description": "Programming a programming game for learning programming to be a programming programmer of programmatic programs." + }, + { + "employer": "Skritter", + "role": "Cofounder", + "duration": "May 2008 - present", + "description": "I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email." + } + ], + "visa": "Authorized to work in the US", + "longDescription": "I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.", + "shortDescription": "Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.", + "experience": 6, + "skills": [ + "python", + "coffeescript", + "node", + "ios", + "objective-c", + "javascript", + "app-engine", + "mongodb", + "web dev", + "django", + "backbone", + "chinese", + "qs", + "writing" + ], + "country": "USA", + "city": "San Francisco", + "active": false, + "lookingFor": "Full-time", + "name": "Nick Winter", + "updated": "2014-07-12T01:48:42.980Z", + "jobTitle": "Mutant Code Gorilla" + }, + "jobProfileApproved": false, + "emails": { + "anyNotes": { + "enabled": true + }, + "generalNews": { + "enabled": true + }, + "archmageNews": { + "enabled": true + }, + "artisanNews": { + "enabled": true + }, + "adventurerNews": { + "enabled": true + }, + "scribeNews": { + "enabled": true + }, + "diplomatNews": { + "enabled": true + }, + "ambassadorNews": { + "enabled": true + } + }, + "activity": { + "viewed_by_employer": { + "last": "2014-06-19T20:21:43.747Z", + "count": 6, + "first": "2014-06-12T01:37:38.278Z" + }, + "view_candidate": { + "first": "2014-06-10T19:59:30.773Z", + "count": 661, + "last": "2014-07-11T02:14:40.131Z" + }, + "login": { + "first": "2014-06-10T21:55:08.968Z", + "count": 22, + "last": "2014-07-16T16:32:31.661Z" + }, + "contacted_by_employer": { + "first": "2014-06-19T20:24:51.870Z", + "count": 1, + "last": "2014-06-19T20:24:51.870Z" + } + }, + "slug": "nick", + "jobProfileNotes": "Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.", + "simulatedFor": 2363, + "simulatedBy": 103674, + "preferredLanguage": "en-US", + "anonymous": false, + "permissions": [ + "admin" + ], + "autocastDelay": 90019001, + "music": false, + "dateCreated": "2013-02-28T06:09:04.743Z" + }, + + '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [ + { + "_id": "53179b49b483edfcdb7ef13e", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "code": { + }, + "submitted": false, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submittedCodeLanguage": "javascript", + "playtime": 33, + "codeLanguage": "javascript" + }, + { + "_id": "53336ee91506ed33756f73e5", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "code": { + }, + "teamSpells": { + "humans": [ + "programmable-coin/chooseAction", + "tharin/chooseAction", + "wizard-purple/chooseAction" + ] + }, + "levelID": "gold-rush", + "levelName": "Resource gathering multiplayer", + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "52ae32cbef42c52f1300000d", + "level": { + "original": "52ae2460ef42c52f13000008", + "majorVersion": 0 + }, + "levelID": "gridmancer", + "levelName": "Gridmancer", + "code": { + }, + "teamSpells": { + "humans": [ + "thoktar" + ] + }, + "submitted": false, + "submittedCodeLanguage": "javascript", + "playtime": 302, + "codeLanguage": "javascript" + }, + { + "_id": "5334901f0a0f9b286f57382c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "team": "humans", + "code": { + }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "levelID": "gold-rush", + "levelName": "Gold Rush", + "totalScore": 39.23691444835561, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1158, + "codeLanguage": "javascript" + }, + { + "_id": "52dea9b77e486eeb97000001", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, + "levelID": "brawlwood", + "levelName": "Brawlwood", + "code": { + }, + "totalScore": 24.138610165979667, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, + "team": "humans", + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 0, + "codeLanguage": "javascript" + }, + { + "_id": "535701331bfa9bba14b5e03d", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "greed", + "levelName": "Greed", + "code": { + }, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 36.77589873873074, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 12893, + "codeLanguage": "javascript" + }, + { + "_id": "5356fc2e1bfa9bba14b5e039", + "level": { + "original": "53558b5a9914f5a90d7ccddb", + "majorVersion": 0 + }, + "team": "humans", + "levelID": "greed", + "levelName": "Greed", + "code": { + }, + "teamSpells": { + "humans": [ + "human-base/chooseAction" + ], + "ogres": [ + "ogre-base/chooseAction" + ], + "common": [ + "well/chooseAction" + ] + }, + "totalScore": 31.538998178536794, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 15648, + "codeLanguage": "javascript" + }, + { + "_id": "52fd5bf7e3c53130231726e1", + "level": { + "original": "52d97ecd32362bc86e004e87", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "brawlwood", + "levelName": "Brawlwood", + "submitted": true, + "totalScore": 53.73511062513137, + "teamSpells": { + "humans": [ + "programmable-artillery/chooseAction", + "programmable-artillery/hear", + "programmable-soldier/chooseAction", + "programmable-soldier/hear", + "s-arrow-tower/chooseAction", + "programmable-archer/chooseAction", + "programmable-archer/hear", + "human-base/chooseAction", + "human-base/hear" + ], + "ogres": [ + "programmable-shaman/chooseAction", + "programmable-shaman/hear", + "n-beam-tower/chooseAction", + "programmable-thrower/chooseAction", + "programmable-thrower/hear", + "programmable-munchkin/chooseAction", + "programmable-munchkin/hear", + "ogre-base/chooseAction", + "ogre-base/hear" + ] + }, + "code": { + }, + "submittedCodeLanguage": "javascript", + "playtime": 178, + "codeLanguage": "javascript" + }, + { + "_id": "5317ad4909098828ed071f4d", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "team": "humans", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 38.19039674380126, + "code": { + }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "submittedCodeLanguage": "javascript", + "playtime": 9753, + "codeLanguage": "javascript" + }, + { + "_id": "53361c80948ad7a777a10d9c", + "level": { + "original": "533353722a61b7ca6832840c", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "gold-rush", + "levelName": "Gold Rush", + "code": { + }, + "teamSpells": { + "common": [ + "coin-generator-9000/chooseAction" + ], + "humans": [ + "tharin/chooseAction" + ], + "ogres": [ + "mak-fod/chooseAction" + ] + }, + "totalScore": 40.73558595296533, + "submitted": true, + "submittedCodeLanguage": "javascript", + "playtime": 1014, + "codeLanguage": "javascript" + }, + { + "_id": "531920069f44be00001a7aef", + "level": { + "original": "53173f76c269d400000543c2", + "majorVersion": 0 + }, + "team": "ogres", + "levelID": "dungeon-arena", + "levelName": "Dungeon Arena", + "submitted": true, + "totalScore": 26.50666470188054, + "code": { + }, + "teamSpells": { + "ogres": [ + "programmable-brawler/chooseAction", + "programmable-shaman/chooseAction", + "ogre-base/chooseAction" + ], + "humans": [ + "programmable-librarian/chooseAction", + "programmable-tharin/chooseAction", + "human-base/chooseAction" + ] + }, + "submittedCodeLanguage": "javascript", + "playtime": 1786, + "codeLanguage": "javascript" + } + ] + +module.exports = -> + me.isAdmin = -> false + me.set('permissions', ['employer']) + v = new ProfileView({}, 'joe') + for url, responseBody of responses + requests = jasmine.Ajax.requests.filter(url) + if not requests.length + console.error "could not find response for <#{url}>", responses + continue + request = requests[0] + request.response({status: 200, responseText: JSON.stringify(responseBody)}) + # v.$el = v.$el.find('.main-content-area') + v From cd0d81438dc75dc829afdbdf9b9a028e358e7222 Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 16:26:53 -0700 Subject: [PATCH 51/58] Add recruitment task reminder emails --- server/routes/mail.coffee | 94 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index 0786a5f62..ed239f9be 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -32,6 +32,9 @@ setupScheduledEmails = -> , taskFunction: unapprovedCandidateFinishProfileTask frequencyMs: 10 * 60 * 1000 + , + taskFunction: emailUserRemarkTaskRemindersTask + frequencyMs: 10 * 60 * 1000 ] for mailTask in mailTasks @@ -405,8 +408,97 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) -> ### End Employer New Candidates Available Email ### ### Task Emails ### -userRemarkTaskEmailTask = -> +emailUserRemarkTaskRemindersTask = -> + mailTaskName = "emailUserRemarkTaskRemindersTask" + lockDurationMs = 2 * 60 * 1000 + lockManager.setLock mailTaskName, lockDurationMs, (err) -> + if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}" + emailUserRemarkTaskReminders.call {"mailTaskName":mailTaskName}, (err) -> + if err + log.error "There was an error completing the #{mailTaskName}: #{err}" + else + log.info "Completed the #{mailTaskName}" + lockManager.releaseLock mailTaskName, (err) -> + if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}" + +emailUserRemarkTaskReminders = (cb) -> + currentTime = new Date() + asyncContext = + "currentTime": currentTime + "mailTaskName": @mailTaskName + async.waterfall [ + findAllIncompleteUserRemarkTasksDue.bind(asyncContext) + processRemarksIntoTasks.bind(asyncContext) + (allTasks, cb) -> + async.reject allTasks, taskReminderAlreadySentThisWeekFilter.bind(asyncContext), cb.bind(null,null) + (tasksToRemind, cb) -> + async.each tasksToRemind, sendUserRemarkTaskEmail.bind(asyncContext), cb + ], cb + +findAllIncompleteUserRemarkTasksDue = (cb) -> + findParameters = + tasks: + $exists: true + $elemMatch: + date: + $lte: @currentTime.toISOString() + status: + $ne: 'Completed' + selection = "contact user tasks" + UserRemark.find(findParameters).select(selection).lean().exec cb + +processRemarksIntoTasks = (remarks, cb) -> + tasks = [] + for remark in remarks + for task in remark.tasks + taskObject = + date: task.date + action: task.action + contact: remark.contact + user: remark.user + remarkID: remark._id + tasks.push taskObject + cb null, tasks + +taskReminderAlreadySentThisWeekFilter = (task, cb) -> + findParameters = + "user": task.contact + "mailTask": @mailTaskName + "sent": + $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) + "metadata": + remarkID: task.remarkID + taskAction: task.action + date: task.date + MailSent.count findParameters, (err, count) -> + if err? then return cb true + return cb Boolean(count) + +sendUserRemarkTaskEmail = (task, cb) -> + mailTaskName = @mailTaskName + User.findOne("_id":task.contact).select("email").lean().exec (err, contact) -> + if err? then return cb err + context = + email_id: "tem_aryDjyw6JmEmbKtCMTSwAM" + recipient: + address: contact.email + email_data: + candidate_link: "http://codecombat.com/account/profile/#{task.user}" + due_date: task.date + log.info "Sending recruitment task reminder to #{contact.email}" + newSentMail = + mailTask: mailTaskName + user: task.contact + "metadata": + remarkID: task.remarkID + taskAction: task.action + date: task.date + MailSent.create newSentMail, (err) -> + if err? then return cb err + sendwithus.api.send context, (err, result) -> + log.error "Error sending #{mailTaskName} to #{contact.email}: #{err} with result #{result}" if err + cb null ### New Recruit Leaderboard Email ### ### From 00c11fd70e1915f070de72d52978258d997fc427 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Fri, 18 Jul 2014 16:45:35 -0700 Subject: [PATCH 52/58] Minor defensive bug handling for the LevelSessionCodeView for when teamSpells has invalid, old data. --- app/views/common/LevelSessionCodeView.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee index 768793115..277eb2e3e 100644 --- a/app/views/common/LevelSessionCodeView.coffee +++ b/app/views/common/LevelSessionCodeView.coffee @@ -39,7 +39,7 @@ module.exports = class LevelSessionCodeView extends CocoView teamSpells = @session.get('teamSpells')[team] or [] filteredSpells = [] for spell in teamSpells - code = @session.getSourceFor(spell) + code = @session.getSourceFor(spell) ? '' lines = code.split('\n').length height = lines * 16 + 20 filteredSpells.push { From 574e9e7804f4039c6ef07187fc4cda61b5e0bcc4 Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Fri, 18 Jul 2014 16:56:08 -0700 Subject: [PATCH 53/58] Removed the deprecated ErrorView. --- app/views/editor/level/edit.coffee | 1 - app/views/editor/thang/edit.coffee | 1 - app/views/error_view.coffee | 6 ------ 3 files changed, 8 deletions(-) delete mode 100644 app/views/error_view.coffee diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index d597f0bfd..6683d6a54 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -16,7 +16,6 @@ LevelForkView = require './fork_view' SaveVersionModal = require 'views/modal/save_version_modal' PatchesView = require 'views/editor/patches_view' VersionHistoryView = require './versions_view' -ErrorView = require '../../error_view' module.exports = class EditorLevelView extends RootView id: 'editor-level-view' diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee index b5ea43653..b7d04b751 100644 --- a/app/views/editor/thang/edit.coffee +++ b/app/views/editor/thang/edit.coffee @@ -11,7 +11,6 @@ VersionHistoryView = require './versions_view' ColorsTabView = require './colors_tab_view' PatchesView = require 'views/editor/patches_view' SaveVersionModal = require 'views/modal/save_version_modal' -ErrorView = require '../../error_view' template = require 'templates/editor/thang/edit' CENTER = {x: 200, y: 300} diff --git a/app/views/error_view.coffee b/app/views/error_view.coffee deleted file mode 100644 index f7b0ba04b..000000000 --- a/app/views/error_view.coffee +++ /dev/null @@ -1,6 +0,0 @@ -RootView = require 'views/kinds/RootView' -template = require 'templates/error' - -module.exports = class ErrorView extends RootView - id: 'error-view' - template: template From 97964f785347517d533d751f24e759a7da7af57c Mon Sep 17 00:00:00 2001 From: Scott Erickson <sderickson@gmail.com> Date: Fri, 18 Jul 2014 17:06:20 -0700 Subject: [PATCH 54/58] More work on renaming. Cleaned out sprite_parser_test_view, and fixed the TeachersView. --- app/lib/Router.coffee | 35 +++++++++++++------ app/templates/teachers.jade | 2 +- ...oyers_view.coffee => EmployersView.coffee} | 0 .../{home_view.coffee => HomeView.coffee} | 0 .../{legal_view.coffee => LegalView.coffee} | 0 ...yer_view.coffee => MultiplayerView.coffee} | 2 +- .../{not_found.coffee => NotFoundView.coffee} | 0 ...achers_view.coffee => TeachersView.coffee} | 0 .../MainEditorView.coffee} | 2 +- .../MainPlayView.coffee} | 2 +- app/views/sprite_parser_test_view.coffee | 22 ------------ 11 files changed, 28 insertions(+), 37 deletions(-) rename app/views/{employers_view.coffee => EmployersView.coffee} (100%) rename app/views/{home_view.coffee => HomeView.coffee} (100%) rename app/views/{legal_view.coffee => LegalView.coffee} (100%) rename app/views/{multiplayer_view.coffee => MultiplayerView.coffee} (93%) rename app/views/{not_found.coffee => NotFoundView.coffee} (100%) rename app/views/{teachers_view.coffee => TeachersView.coffee} (100%) rename app/views/{editor_view.coffee => editor/MainEditorView.coffee} (69%) rename app/views/{play_view.coffee => play/MainPlayView.coffee} (99%) delete mode 100644 app/views/sprite_parser_test_view.coffee diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee index 17dab5309..2c3a026a3 100644 --- a/app/lib/Router.coffee +++ b/app/lib/Router.coffee @@ -1,4 +1,7 @@ gplusClientID = '800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com' +# TODO: Move to GPlusHandler + +NotFoundView = require('views/NotFoundView') go = (path) -> -> @routeDirectly path, arguments @@ -8,11 +11,15 @@ module.exports = class CocoRouter extends Backbone.Router Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @ routes: + '': go('HomeView') + 'about': go('AboutView') 'admin': go('AdminView') + + 'beta': go('HomeView') + 'cla': go('CLAView') 'community': go('CommunityView') - 'contribute': go('contribute/MainContributeView') 'contribute/adventurer': go('contribute/AdventurerView') 'contribute/ambassador': go('contribute/AmbassadorView') @@ -20,21 +27,28 @@ module.exports = class CocoRouter extends Backbone.Router 'contribute/artisan': go('contribute/ArtisanView') 'contribute/diplomat': go('contribute/DiplomatView') 'contribute/scribe': go('contribute/ScribeView') - - # every abnormal view gets listed here - '': 'home' - 'preview': 'home' - 'beta': 'home' + + 'demo(/*subpath)': go('DemoView') + + 'editor': go('editor/MainEditorView') + 'employers': go('EmployersView') + + 'legal': go('LegalView') + + 'multiplayer': go('MultiplayerView') + + 'play': go('play/MainPlayView') + 'preview': go('HomeView') + + 'teachers': go('TeachersView') + 'test(/*subpath)': go('TestView') + # editor views tend to have the same general structure 'editor/:model(/:slug_or_id)(/:subview)': 'editorModelView' # Direct links - 'test': go('TestView') - 'test/*subpath': go('TestView') - 'demo': go('DemoView') - 'demo/*subpath': go('DemoView') 'play/ladder/:levelID': go('play/ladder/ladder_view') 'play/ladder': go('play/ladder_home') @@ -147,7 +161,6 @@ module.exports = class CocoRouter extends Backbone.Router throw error notFoundView: -> - NotFoundView = require('views/not_found') view = new NotFoundView() view.render() diff --git a/app/templates/teachers.jade b/app/templates/teachers.jade index 3653491d8..651de1205 100644 --- a/app/templates/teachers.jade +++ b/app/templates/teachers.jade @@ -2,7 +2,7 @@ extends /templates/base block content - .row + p.row .span5 diff --git a/app/views/employers_view.coffee b/app/views/EmployersView.coffee similarity index 100% rename from app/views/employers_view.coffee rename to app/views/EmployersView.coffee diff --git a/app/views/home_view.coffee b/app/views/HomeView.coffee similarity index 100% rename from app/views/home_view.coffee rename to app/views/HomeView.coffee diff --git a/app/views/legal_view.coffee b/app/views/LegalView.coffee similarity index 100% rename from app/views/legal_view.coffee rename to app/views/LegalView.coffee diff --git a/app/views/multiplayer_view.coffee b/app/views/MultiplayerView.coffee similarity index 93% rename from app/views/multiplayer_view.coffee rename to app/views/MultiplayerView.coffee index acfaefe15..9b5737d10 100644 --- a/app/views/multiplayer_view.coffee +++ b/app/views/MultiplayerView.coffee @@ -1,4 +1,4 @@ -HomeView = require './home_view' +HomeView = require './HomeView' ModalView = require 'views/kinds/ModalView' modalTemplate = require 'templates/multiplayer_launch_modal' diff --git a/app/views/not_found.coffee b/app/views/NotFoundView.coffee similarity index 100% rename from app/views/not_found.coffee rename to app/views/NotFoundView.coffee diff --git a/app/views/teachers_view.coffee b/app/views/TeachersView.coffee similarity index 100% rename from app/views/teachers_view.coffee rename to app/views/TeachersView.coffee diff --git a/app/views/editor_view.coffee b/app/views/editor/MainEditorView.coffee similarity index 69% rename from app/views/editor_view.coffee rename to app/views/editor/MainEditorView.coffee index 7536d5ebc..e5a841279 100644 --- a/app/views/editor_view.coffee +++ b/app/views/editor/MainEditorView.coffee @@ -1,6 +1,6 @@ RootView = require 'views/kinds/RootView' template = require 'templates/editor' -module.exports = class EditorView extends RootView +module.exports = class MainEditorView extends RootView id: 'editor-nav-view' template: template diff --git a/app/views/play_view.coffee b/app/views/play/MainPlayView.coffee similarity index 99% rename from app/views/play_view.coffee rename to app/views/play/MainPlayView.coffee index 202bd32a3..685887eab 100644 --- a/app/views/play_view.coffee +++ b/app/views/play/MainPlayView.coffee @@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection super() @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID" -module.exports = class PlayView extends RootView +module.exports = class MainPlayView extends RootView id: 'play-view' template: template diff --git a/app/views/sprite_parser_test_view.coffee b/app/views/sprite_parser_test_view.coffee deleted file mode 100644 index 80369fc45..000000000 --- a/app/views/sprite_parser_test_view.coffee +++ /dev/null @@ -1,22 +0,0 @@ -RootView = require 'views/kinds/RootView' -template = require 'templates/editor/thang/sprite_parser_test' -SpriteParser = require 'lib/sprites/SpriteParser' -mixed_samples = require 'lib/sprites/parser_samples' -samples = require 'lib/sprites/parser_samples_artillery' -ThangType = require 'models/ThangType' - -module.exports = class SpriteParserTestView extends RootView - id: 'sprite-parser-test-view' - template: template - - afterRender: -> - @parse samples - - parse: (samples) -> - thangType = new ThangType() - for sample in _.shuffle samples - parser = new SpriteParser(thangType) - parser.parse(sample) - console.log 'thang type is now', thangType - console.log JSON.stringify(thangType).length -# console.log JSON.stringify(thangType.attributes.raw.animations.tharin_defend.tweens) From 1d5078ad10cbda15276ab1ecb2a21f0f7bde97bc Mon Sep 17 00:00:00 2001 From: Michael Schmatz <michaelschmatz@gmail.com> Date: Fri, 18 Jul 2014 19:22:00 -0700 Subject: [PATCH 55/58] Changed https to http in curation email --- server/routes/mail.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee index ed239f9be..b75acfce7 100644 --- a/server/routes/mail.coffee +++ b/server/routes/mail.coffee @@ -292,7 +292,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) -> address: "team@codecombat.com" name: "The CodeCombat Team" email_data: - new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}" + new_candidate_profile: "http://codecombat.com/account/profile/#{candidate._id}" log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}" newSentMail = mailTask: @mailTaskName From d45c2d31de6f8feddf823b9809cc2a165b855226 Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Fri, 18 Jul 2014 20:14:41 -0700 Subject: [PATCH 56/58] New language icons. --- .../images/common/code_languages/c_small.png | Bin 0 -> 3538 bytes .../common/code_languages/clojure_small.png | Bin 6228 -> 5202 bytes .../code_languages/coffeescript_small.png | Bin 16254 -> 4544 bytes .../common/code_languages/cpp_small.png | Bin 0 -> 4040 bytes .../common/code_languages/csharp_small.png | Bin 0 -> 3686 bytes .../images/common/code_languages/go_small.png | Bin 0 -> 4015 bytes .../images/common/code_languages/io_small.png | Bin 15390 -> 2824 bytes .../common/code_languages/java_small.png | Bin 0 -> 3914 bytes .../code_languages/javascript_small.png | Bin 3828 -> 2349 bytes .../common/code_languages/lua_small.png | Bin 1510 -> 3614 bytes .../common/code_languages/php_small.png | Bin 0 -> 3353 bytes .../common/code_languages/python_small.png | Bin 17483 -> 4192 bytes .../common/code_languages/ruby_small.png | Bin 0 -> 2797 bytes .../common/code_languages/swift_small.png | Bin 0 -> 2631 bytes app/views/HomeView.coffee | 2 +- 15 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 app/assets/images/common/code_languages/c_small.png create mode 100644 app/assets/images/common/code_languages/cpp_small.png create mode 100644 app/assets/images/common/code_languages/csharp_small.png create mode 100644 app/assets/images/common/code_languages/go_small.png create mode 100644 app/assets/images/common/code_languages/java_small.png create mode 100644 app/assets/images/common/code_languages/php_small.png create mode 100644 app/assets/images/common/code_languages/ruby_small.png create mode 100644 app/assets/images/common/code_languages/swift_small.png diff --git a/app/assets/images/common/code_languages/c_small.png b/app/assets/images/common/code_languages/c_small.png new file mode 100644 index 0000000000000000000000000000000000000000..23ba119bb4e99407c8412fbbca964105eec966df GIT binary patch literal 3538 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 M07*qoM6N<$f|2E`X#fBK literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/clojure_small.png b/app/assets/images/common/code_languages/clojure_small.png index 38f4ae07ac830431c6b5c30c2a193fd13382541f..606af043342c1fc41c347a6835ea2ce36fba51ad 100644 GIT binary patch literal 5202 zcmV-Y6s_xtP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU_^hrcPRCwCNS_yQU)s_AvS*vA9-Xz=c zmUv0*I9_6B-<&`wfdUC7Z3-=fav0X3?X(@H)1HA$>4Bk#Qn~^yTcAVQz=VYC84?Ga z#7?{=c48~uSK0C+$=dh1?@4lO;w5CxoO$Q`N6Y`~z4yI)?{~lZo&@*`ZAn&QF}-M} zxn*u_A8x=+HtLu4Sv=i6>bK%X`Vic}09)yLh_3P*=#LG0nyyb~14jL3hWp(R?pHHM zzYXEOU!#7zz7h}`j1BZov>2K)odApD1@H%HL@D@dq_OucrXa*ZV8{+!9tpzc<+s>? znbUO5zn4V;3*!XPMFVahP?RWuM0owfG7(T`4C2CI5W`OX)o%#Q4{rzvf!N7FtVk9h zOD*6XwTuPlG>1}5mn8Jupk06$Uj8lo{=mfj{=RO!`G;4Lsth2CCT;TyG2)!t%!zVf zS&{%QKTvH5!tTYp1m@vcfrQ<uvq&q@4BCTym8rc;*M4T=nM_N+D-XNLbCK`nrKUr! zh{o9HFq{qt616(?ba#H)6<=eo)USD#*tv(fB3UtWeVPErJNaU5oE$%b8C+^#Qgo25 zYFGFNU30|J*2rMY-*rhT$jZq@cFsb6|6+YD1`PxF+8uZC&uy)Gw6|Wx(BJ?k3Kmmz zy*FE6he5qVR^O_WFpE#MO4KyJDOQSuaQXQA_hthTc0p!=%q*I;QW-;&uHp9zi<d#F zP(mV+BBrAQCX)#%>Dh2PohVeQ5g?aS#>AkgxKwkop>}6`t9~c-$AWqnjrqwm>}96= zuTlJMO^`Ep6;6r2>3~$&yn^Q#m@uo%M8oeyD6_D1HCC_Nh=PIw^mMl2kFULq*MIjb zD57KFuv;g7_tNt}L5w;UR*MM*g(Z0G=^r5w6d+oi0AE0W?)Dbe-#+S}S?1ws7O|Mc z)}TWeVX`@cy?zp}vku>#bnkg)g`$!&EL*V}v2pP@e&ka$HHP|?%A>J#!xp6F7GP0c z0b*1tq|<xWdagFXY#B#uOB3|9XV6l27Cw&$9=8*$zoL>-csyQQs6Iokr#FYK^P5SO zT|bGc=T8PIm}SNHh3S)Z_;5HdnH9E5q;llsEkRnwd<^z=p`o^#Pk!?~JFxk-Eu6i) z#4r{Q&}*C8w@MOXw^*WaGtu;^6Gw35!#B}Fz*eo>1Ub3g*vK#%>#N}R`65KKD?FcR z7k92a!jQj8*Ukw4Qw(I@`_23LhyVKff5K+7VsY6T{PQn=i^cQP&`n;{YN3_4g+R>J za@3(Kg>uQMGiUMlH-5zdF|uI9V6$4ewb?k6Snh|@C0oG_%7;!-RFvjB4?l^_1=%>b zZx5QAFXKo5`U~89-ws?c0cQrMPTohE(&Y_O9tpzZ3sNjlauW+65()Tgl<3;fQc8Mi zvQ&N?@cBn?;{8{Cj$3cP8|ycHjky>;c;}DII!rBWyD5nh2EyEFCv&F+T?!nuIy#*e z_dod(hCJ!$8ggMnks8UFYSfPjaM|eR6K6m?b_c&AO%ko(7k?i`K`s+QDHlOFX%>qK zjM&(O=N{b#iC78+F`;?X7$J>mv-*u_tsgM=dhn4akd?g<yWjp3U!k=5c`*ADAdky| zEG`=gT?s@ICAO@H#j;`zj-9-My%k;Xd%V~6DUyg0qfLN1H3{+a(>aKERTLD`Yx*Q! zM%mobgcl#*hUBCqJovpQ(B7uU?zjHLZf~28o&|FVyZVd;3pLBvl;d*41$4HxU_ov^ z&k1gqld}z@Qr2S9)*(KBJMP+)jW^!<5CKao0=7N`?0pk`3ZqjYki|n3Ur1LGr0RGi zFImU|DaksqF;NrNnG7Z?dl6DIvvI!iGmH)on!}7`zEL3i!kL-}AIri&{@Dv$cCco* z+b}dVgx=m>G+wNQaiC`c6mvse3Qdl32FoRr8+*n)X2jSS%_F`P;`BSAN=d_lb<0W4 zNT7=qPXQC%cb33xotQ(oUFTw=S#;A&|MG9Y#3PS=AOC&q5SCD;mMauES9uzjDQC1@ zZJ`N`ATBNz#l-({+7tw+JC^V=a~4BJ`NYuM0i&S@U9Fd48#iIpH~@h_fW)L!BqgWP zYV^RYKLDRdhtWPOloWfQxL~ovnv>X99G?btzykZI0dKyym&ihdrc3oJb#c+}8BGrJ ztU&0YR}*z9ixQI3vG>FG(B0VzBdtbLb2a?&!w}Cm!KXGt87oKM<slsT^kdw;Z99TN zKh&Bys8nj0&12~8)MNG94Y>Dv&p?x!4OLtshA8iJQDU^)EYOnG60}JezWfOSA{8t| z7K+3~h~+ZK!kXSeU^cES#V2q78u}JJ=A~yrf8`Q<Uay9L?4M0Eve@Wk?!g+1gBYCz zOTU|poXzn_l@}r=N{2k<W*qtW0RH;>5Apaj&*IGK6R4}HVgq37_6Lx&r~t>09z@mW zCve+CFXQL`^Z@)(Vx9!6s?K8npF=q#g(jvZfLEJp5S9BqD6`iichefACMh_xaTQH@ z#!|HhZ|r&oljb!gRz%ZSV<#oP+qZxFJIGsH0GUjVAHV(-%1BQwN?Hb)%8yL{E!h3} zv-sfOKgHJj9wH{Yg3pc}#4ld?HQJq(IDfPbC1op6x@;xtDeE_1z6`6p82Neg_<*Yy zreXD+I}ntsaqj5H5DJCFgbOj$d>lb#0fIsq6k07O03KHaz9csdr$5<^2OoZvq)$Fm z)D%I`lT{jK0`lV0WvepFR&BtZ_uoQVkrr!iFGQ>VBUt2mXh|j1v>nCqznn)p1#5mm zAwD2l-to+R`0fKwBVl;}b?0i)aj6@t)|Mk>UOK8P_M^j*f%1)|IM6FXAJsTHDqzj> zQXT`JAKZhugd|9bnyq64aDn0?BMs3?=|tj`%VZGRjJR0+1<G%|6T`+q7>5kzh<i;_ zT%vr`G>*65`~!bjndL#J>m&qWGi!aNXd9%7eqlxyQSpbn|BUnk9iDmec`DYQ#o~nZ z*znXsB7<hmX4$!m5EoDCcBqPCV*vf5UbKt`@Q$7|&p3&u`*(1i#t0!fZ2^SliwL?# zVQAFD>hMoYYLN13N%<Yr?-jg7bF<obqTM<{?bEOo3_Wd#)5Jg|6+oD3fZcC|fH+YB z3RY7ujLi-trKFPl@MCbG4|je0ZkVE);lMC13SY;nrJIqlT7wJcDntDimBK%I2^Sg% zxD**3_i@Q`xCgw{efp;_@K|K5rio94ci<Gv{RTMP0sb6oY#$)Aa5Wc_^OCg~9qMOa zYr-*ookcQParFATe<M@t5UmqI9xb`1TuBU%yN6)vaY2`yhTg7rNE9M$*|Hsa=cfpe zG;z7Dum)RDc1Iq!h|}r7vQ_K&Dp#Dn#Irq{oXr_pZKl!kNpLc&n5iU=XEbhZ<<B`y z77ixT*iROfuE7FIkgxpyFB5Z~7Kko+9!{VB99Q+tP^C?+yVS@)kEMZv(oXJ@NUGF= z*bEtTifoM7+Tk*J;2!s4iQ-!*S+JRE5jA%)Uc1W`+$!yDp`>Pag(k?9GOYzl2#9rj zj3>~D8t@YXx;@u`m|XO%QiZCsm1xno^6GOYAQ%}L!J++o(cjZCtC*BXr7+P7>hhvt z30^DYwBiC(R2|1F&%H=8#zi1P73q@VQXVIkzQGWE`mXKDFfa*}Q^NJf1Q@GvlqyF| zQOT@GYtuJj&j)Xjx5Ug0#9|sj!Qy-_*Kf2rJ=e<F+LqHe`q|%MYW1Rc*;*W?WO?k+ zJ`@x!<&!hDHBC{(kvuU)ZbXqM_?)Da<#0{1NJ>aJ<DPGP3ksQp&vn{h=X*$69q#_d z{qTCHD%U`GX{1rgiSMGx%wye5Jcj(;<?y1Tc^Dms9ni#SVRzV(nwpC4{;NFTnS1$+ z)fnyU4fRPz(aJ-4Vsc}a<YR>;f21XcKMoBI<3~T;#r4;WKqOKbDk@IFG&VNn`yka9 zjFoiJ*$^v)yc~^-*TU58LgVl;q)J!d>LmjV^-j1g0VJm{Kuco{HgDeqhrFK${)St= z24DY481?Nun3;Q}D?=r3eZ}Dkfyo$5sLq+FT_z?=8DPZF%O(AV3pKRZo*99d$3{nR z>i9uk$k?e!vW>gK774=a??RfY2yq#5j8U<ZmYD_nh!>S-j-j)o55op4`p>vH^H|1) zkz6E4(UO%|xHJn*7wfQWC9xN|jJx*>7_W99Kqg^@RPTrdm52UD)T`ynm`VLe5f)Lx zT6s8z35e4+juS`rgUvNu{$2;9!Ab7mc37#Hc?=E$Vl}(2v4*z;395NmygDaDy%g{) zpET|pMpJhchMPRx8YyIrp@DA7FZW<vs>i0yThQ20%hmG+Dqp=FA7P-r9$JqXM07Z@ z=S{esc4(8+IR%Tz8m#!@9wH7+F_&t4D{%qSXHPuyW0*$<Cl-HNAUw6-dOPA0Q~0FJ z11`9nAt&|`k@r&mUSGBqVpRa``YXuIFX41NP;bKs0b$l)HHS<iz=rj=qaJ@E-d_Mk zN|1wDTfUhFCAYfzKB`V%LfwV4_=E(cE+vB!td}RnDBViLFG%BK#>xe_WgY>Md12~k z3e_ozNw{sxU6GBuhU<WYm1F}em}+Xyhpa&CW9T+dxL2$95Q>tvVBNP1ak2IsCkGbT zO?yok@A2`>%vLq6RE2=dgn&1IF=-uEZC}FKD<M&flI80tr(DEf&2IeeCl7J(OrG?1 zT;<k~r4&I)7AevSu}R}b&DlZx!}G`RkB>ga=TTK%O$A-ggj>xd8W)XQOe<Y3H(A07 z*SH6&TmjOv<3mZx@1bCi!n*tiaQxI>40euSVZl-u`>ALWija|&hn|jRY}&B`(kugI zb}KB7L2{c^oc^$$q`3mcr7O_g-HpN4YN#~vybxoS80_zYbn#=DPgK1+MUIX}BMyId z1yu)s1w-{K<Pl?GdKTl#r8*{&UL(<1H4~5_kH`JEodRmdgO8%NvKoqHAvDP{s{UjM zQh=I;ZKP#ZBP%Zl2mZPbF1r&+w4$tfV-;e5cN>z{_@PP-B1#+@Vw3J!=*P~W>eD)` zT)Po6g%V;}G`9u=!9=4Zc@5OMe0U6cT&g^ZmWo#~RQEapj(+MljuzI=WB1gF!@TaH z_C%ygybcK67$h)TgMmQOx4!cT6-(zaK4gU~je<Bs1EEOB-DOnLh}H8RLHxofoZNR3 zZo3=vGIDrr!Ae}4*@=PvF&N2P1EYy7zhO=3oj7;A3Wk9Jq^8e@hbF@oj6LshyWqF= zQuTWh4#PPJ934=Sc1a>-z^u#`XU+PJC@d+%>CcWKd@A<FY@65!pIN+fzWN-`vS#vq z!$k)=l82F7m_#KliN0|Q&cyD**Ec<fn737U<=I!!So;MpkXY3>(mFsa#`a6uRfz-I zbDRZvP7*|6psyQFs|A_!v!K<bz;3rs$qSJd6QhEmuaoB%EfGRpZO!C4&c6A;sxDS3 z4i5Bdd_E7PR3#dlt&nH<p-@S<i-Ev+J#Gxis!=xYK9t{a3%bp9Xsc}}%C<lqn}Ar# z3(O^$Ch|K4JWq(lQjAkQZ=`&XkdS~g6;u@ld{D*2K%-GZ6B|d9kAZ;df3M3yG=CKx zRD<yPo#M7#f0-$2b}+Q-Mz@1lZE}iPB(HEeI`oaCNgODAP>p4`&JTfM9Z(NajRe_I zcOuEX7M1!vIC69^dTYmd)@KQGN(_?7j7^uJ{Ojc?E4&5ofBGNjI%|R9k`*4Cf6B89 z^9o=kt0gAtkd>W_g9r9;%TO!%^8W8!JB@4;`v;{f*Yk>uZ4e|DNRWF^3`*B$LaCBn zlQzmI(o!lcz!qLbwhz~$XZ#{v4RHIWZpo*sig8QkQ;<nx&}=<{VK>D{z=l5OB?4r_ zg6LIPTYNVv_Eh2ckpuYou9vZQ&u$z(@G-(i4bR`q@$@OuK*gz<Iq2(Zg_~9+nzUN( zwrCWtNhP+rcCsv_a+p!GNGhb-C6fxV3|>`EZcML@qZ<~4q(8gQ3N}?R1984Z5cuS% ztUrX`{p=4I={4c5ZQq0}T7&(2-)GifF17JyH?jHFDcg;gO6ABP&S#d9#s!gehXNTz z8swMGo1j_VsYn2kM2IMvh=ZG{G13T-O!u>k6!ZWk-kL*wxbnAguCmLPuS9EG8|k(Y zru`bi=b7f|`V!3rgz+>5{xPEC9mFa!w%d_PG}}v}&)DFB!{&j>G0rst+w$aqf*}>) zb5X!L{6yD5_^Bd{eCKxtxZLsDd~n-B%AxLbH_pF5h>jz6sMT8Be)o31liA!<&)Ccy z-n{O*>0^a2onoDmNadQWydtzWU*!9{1HJ9E9DXF1k$_}ZrV6o%(a<DBPY}YFo7Lii zjjrK=arCuVxJEP7xJfpMxRfthv4Iy&O`%h(hPgm|B_NYxhHY+_Gd5#6gXyd*4OI~~ zL2Qng*ZK;bh`%xmMF2S+9$tKn_xj)%@^iJ!a!cgwMM*hhptqCP<!n<td~E&jOzw2k zK)!S!`h6BR3=GT4?3jTG#?c`IuPNqgZ1M~|vu<{7K2$0diNgwXw(BF(eBvPVfBmPL z8z2F8#=etThix1%@yE1NV@+jfg;lZPYR$;?RMw*6iOmJEM2xy~Cvn@?xARTuzV42Q zRo@Mt6Pmxud~O=ZmjHb~d}ykPl&g%U88Ei;jP00wVQ$EP`bjOYKxW`3{n6$<24b#Q z_&)<O!~an>gpZPE`umbOT*S@!m#F_2AhTF3@^_1_n_cm_+W!bJ0CtH%!QM#8OaK4? M07*qoM6N<$f-f%aX8-^I literal 6228 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 diff --git a/app/assets/images/common/code_languages/coffeescript_small.png b/app/assets/images/common/code_languages/coffeescript_small.png index 8eb9742ea08e235aed90b0c7f9d0e422f6ff380e..86e49ea1cb25960e800848afb3eba36c38015a91 100644 GIT binary patch literal 4544 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 literal 16254 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 aGt`hUIw1A^s(y|y<inLy6-6QQm;E1aLau!P diff --git a/app/assets/images/common/code_languages/cpp_small.png b/app/assets/images/common/code_languages/cpp_small.png new file mode 100644 index 0000000000000000000000000000000000000000..df701f002614696f4149caab96d59b95b9559770 GIT binary patch literal 4040 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/csharp_small.png b/app/assets/images/common/code_languages/csharp_small.png new file mode 100644 index 0000000000000000000000000000000000000000..86c26aea365c9912adde5cefc5432820c64bdd9a GIT binary patch literal 3686 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 Ef{4rIpa1{> literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/go_small.png b/app/assets/images/common/code_languages/go_small.png new file mode 100644 index 0000000000000000000000000000000000000000..7ff974e0733c20cabd6f7228bad89f46515066b7 GIT binary patch literal 4015 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 VyAkKPI_v-d002ovPDHLkV1j1Kq+|d9 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/io_small.png b/app/assets/images/common/code_languages/io_small.png index c9d3360df53ae92b34639116094d6160c34e9c12..2bbd5c51e5faca7ebd7d1b91de23fb7dd92b1c45 100644 GIT binary patch delta 2816 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 S<;R`?0000<MNUMnLSTZH7HjVS literal 15390 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 DznCwh diff --git a/app/assets/images/common/code_languages/java_small.png b/app/assets/images/common/code_languages/java_small.png new file mode 100644 index 0000000000000000000000000000000000000000..76126650c3be1938cc579cf10b6c757a20ca0511 GIT binary patch literal 3914 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 Y05Xd%@(P(SDF6Tf07*qoM6N<$f`qJr3;+NC literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/javascript_small.png b/app/assets/images/common/code_languages/javascript_small.png index ec8b134ae20775085642757fb04bcee548e1e15a..4472bea9de52ca311e926d3117145950c193b9e5 100644 GIT binary patch delta 2336 zcmV+*3E%eg9jy`}iBL{Q4GJ0x0000DNk~Le0000o0000o2nGNE03JVxv5_Gse+bV> zL_t(|+T2=OP#f17{#HT~=z_$}7#s)6&2}gOYBx?3XAo%`CvH6@5AC!swfmL_XL_5y z^u_gCAL|)E)On~qP3v}gGihfs9cL0lZ5L-I7~<RvMn=I{2w4)kYqip9d(PR_A_)mg z2r+KY%#U`@IeYg1&j0=YfA$=JfB%!hRcqjZ?iL&Q86(n3WRQqWX_{1i$3J#Foc&(_ zGGjDohW75#W8dCdR_FHd@P<-YT}vU#v#R0k0#j2(YoNiRfz=2sdlLwR6G)}fti8#C z43HrrvyZJs2$0LIyW7Whx3#NvJRgTBrV)?F5DJALrc#JS!?fv3#466mf6^k<H(r0^ zXXxAC&y-$UTSG7yL@XAA%jJU8xyU+A-*^{_4?TWBh&8BU_}icVNbJqQ>siTZkH>kW z(;_U^#!S@^dB$0(Rk&?Zo<^r{D^bceID80$!v{g=#e|lb=?~!Z`H)Bm@caGn`#eYr z3AkO$nPDi9aUy580*b2;f51udbDAjIdGy$EJa@#7?%sVleR!T{LMi6;da=B`%xFf7 zD2fD>56(pgBEdDRx|Sd$;<V`^k)IGifvN&g=ySQQ&Nwvk^`m&{=(kXBwW;lbARrQn zAel_EdwLxR1Q;0F7K=q0#lqpxhOxs0kn`@R6cDw_Yo&%~uAE4ef0fi|*tD4~^`P>o zlJSdDOIAb+WQFHR0_vCB;p}e{x$yH}oKbmStR#~Hnfau8uh;8v`}S>2PfwR?d|SZp zv3m&RDAhLWs4aCw&suD@wb5i>^ZPpwKR*KZiVGf(hfyY5d_FJSZZ`|L8L>7r!)P*N zk@y0g?NW=;WPx+xe^W^5^ciA}KW&?jD88}S*wjLz&cl+Q>+X9BFMi_~etZ7cWdk7; zb1F-jz_vO&0YiCu`oxGCFC2Naf83dm<J@=vd{V-|UL8)IXoktAMKmBH8Y~X#?^i;& zK9``EqXfi6H4-8n^z`?BunSF1I%qUx-4stlk_vb388Bf_e^(uD+==1Gr&<{ZTGB}o z$q)~HgAtrYp3h_?f%r-Y=FUb~`c1h0x)Y^<*eVbfMMRRd4F*{Ot-z55p;YvN;b9Yw zeA9}Wx^)7?9t0sKQV{tRjC-syIC3wgB?2;?=~i+c(UglK!_@_6f`nALE}fRjo(*ad zTBNLJsdZ|1f0<EZ)M5Ho6y>apD_U!XA|hQ*sesf$EyFPPo`WPtAo$)veEF=R=_`ar zJ;a1PFdvX-U!$uBS1YduxWr#!(45=RMWa)aq)w42!WD=e8GqrlW@zhr<$EHW?iKRJ zA(@Va-YiA3uFF$MvsECopT(JiX+_vz8hS0|I6lKbe=AB=Oabj$NoIc*SC3juH&tT} zCX*HhJqLdvl~pfmruHocMqFUlkVLoI$K^`y2(<!I7KLPGsc_gxH`z-0Af(8zfW*IY z@dzoTq6rupO=T;zRcd|Y_#&awis~5*i}3i8%<*%mrL^Y*;mGWB)NiD9I`Q5xcz+bB zSdy%af5n}NT9Ig4rI56NcGAZC{EV4Zm$9JUTuY*$1~ob@=I-)k<&g@)uT(Uf=hvsR zW<B4jWdtOWab}W7BG8*=xAc{?RUosg-qePf&w^OMB6*!GZ;%+gn*mTulzbQ_a@gdo zy0cRt*$JI1Vv!7kHejylDH?h|oQY*t5zZZ;e^#z9NJW6?OubvmBRiJaGY)SuY6>fp z35zwBTpyviBDo+-Vg|4his=;V(ED{DfvN+cCMVw|a4aP-u&=fxA7NJV{;0s}F|xrL za|?V~p|_GeqEbj>XoF?X_X&miiu!|;ZIOH_K&x;#y`wvg0ivKyOoq|e{Zn~zQzW4U ze{Lbky9(!#jN&v})sm2F7+$AU1^!VfklDrig1x^loZ}D1=8=u;$tY+$B`dG*+0@xx zZlP>yRTQ<NF*&<a3+QUwH>Du^WBJbJn`}xymzymZgF6N!vy5N7aU2FqAIvSIFgM%T zbwOt@RASe_@nrIO60wAZE$dPVkV%g(e`U|)5<WCXWFB6}dFbleU~D)j18cG8E*euL z{6-b!35Y@^97&gz)ho8hLtiRyrsW$U=3)|f@XwqkZt1%+kVlj`2VXXjio$QP(%NJ| zU#AJWn!MqYZZ$HcgrvOj@TibnO(4pSW5+|kh{>C=4eh!b4q6SBB74JvfN&@Xe<8u= zQi`k;{xH6lxwU7`B1<V-*=f9NHe1GCe)Tx$fzFL<S1~*NZye}K;j2&A;?Q6n13|&? z!g^xsXs?5@R^FVW+oqvl07jDuf@r|i|Ag`WR0LP2!fbcHwe1PqcRC;lY^RYPW4~4n zADJ`}ApK8&1p|Wz@!Sh`R{7S2fAjdwrAv_BTEob*Mj|G3JfSNbs1h1nyQL$_`<e23 zy#aeWyD|E55BdUWBLj``0q`QAJ5`@C;g#UhGTF6eanlh2PF!|=gF=<4di{-^dM z5(#7Cy(_r<mrGdsVi7G(HOxw{j#_YNz>E)O;zao{{_$>5RsP9NS^1`>e<pSiw7h&D zb9X+&=d(BItIlk8CQ>mF1<Z`q);L7L5Ku4}4Cw0a!r;X6mLcYY2N?_a^q>l1je zyre!ymG9~6SC!Xlwd^?V-aQ99*`fzL^PhZ3>35NU_+iz2Bnt?2#H&V=dFaWGUZP+x zj7IruufD#XS*W|Go1GtifAaB1h!Q1v5~<qS+F`X?*~~i}4y>-O${{-uhimB`0)7t# zF+o6#mZMLlhoKbANg{N8-r3gPfv(<uG`H+l`%o(#{@P*KY&I+`EMRJCip@SfOQgl; zaWSE1hsyejp6XsKSC?)3&j;m*`UH_NdOFqB(@*%{%V^i!(u`-Gc6|nKzIk4qeV=Cq z-c?ujDel=y{x4<Q|Aj-zG0aK?gsp8)2Lok)=|x=n{qIx@D4Cn?ZeJ|t7<$Km<bgV= zSjkS$-yL`7X!V3L`{UdBuBrmb0z|jq$CTN3R^uK26<`4TXN2aPh(~Y$0000<MNUMn GLSTXly>V;+ literal 3828 zcmaJ^c{r5q+a4x_MiE(3#vqMt48}5+EQ64xu~QgkjHNNt%wSZC7a6?SmuzL5Uh70n zl93WAZBi&Z$sU<PQuxOEdwYN1A79^d9M5y#*L_^)d2Q$Y$CKpbU=0$I5dr`JAe-YT zG<Q|wzFNEaxnE@ugL&>EO||r(Iuiq_kr*-#V1_07<G?lq3?7HZVX#qWyKqJT08k;= z#e?c$e*zgmBxqoEd^BhT5*G~s7#*XLFae=BD%c-~4-PYid}cp@fP=Bd5O;*Vraj35 z7ZiN_92w_)&cP+%Txfs+7IMr4Y(ztH2?#hU223NI38Nrs#*n{xk=*^xF$@C!+l3lx z4Eaw|9`;UP3nCc@Mra_^12nbZU_Ap3I6}t&4p#$fX~MN(a7~z&fjS(H)X_u2b;18U z5N<RwHV}zMS^X1>YZ*g=s8kXX28)c0)QHs9Ad>MgxPgHIOj8S{rKQgGP^UzNQ86_2 zFp9!21{97GKn^BRgNb3_9Y%~lF`Q});b!`u5(uP!X~QW0w29j=7!5;$!8J5@O8Vt! zZ~y<h5(xi#Q>bX%fAjr6i775oBpeKlqY%T%0o=g_D(r+JAuY%_43$WBArjC0>Y`H+ zkxHZl5lLVR3-D2UOh9nhjt%`AU~iAK38PRkVF5TBlre-$p%EO6MH(2utx%SF+E$uy z3pm_T+sqPfZmF+}fLp@hx(3=7zpyA`KsW&xM*W4w{uitBTkMV&2qbP~6pkDmfx}vn zi3IT9H6w$6p9}oAeE(pvzt2VMw^$fA8Q9Kb|JS5{9dYHev;9}MT;pHm<HERdCv$cE zE%_1!01(F8pv+uogB707iHF@Kj^P7a6Au}tF6uYQ+YVLM2|?&6i4>s%P#N|yZ+Mc2 ze5q}{UqZ7v9dwDO){jT+8E=xSoH_ln5X97`utFRGRX<B#T<3hhy?Gx$z06L#N15T| zSNype<rBHIIYR0FUi@V0&cfJse_MZ!ds+Vn?oAStr;MYw-Di4DFwwf*UF@~%veCP@ znqIF>wAz1&)7Dnj_^Bzgwj`ToUD$nGi*{K`4j(h{XrD3Y>+u$hZ2<OjFJ-O42^aC5 zqOvyg%{NFuE%?Im$*qy8N`oIA8zo;w&gwhQLbG<UImwyhP_bvsOr1WU#2{&EQY;8s zG8F@Tx-l+qSvOT2q~$R*QI9jsdB%G<+L2*1?NRpHn}(=-|ILjoVLATh3*8eV%1Dh} zG=877QM^!yp#;aX-8^rFi@C_Ot6du&cpFhBo(XD?xu$PyS7&7!3=zSJTs0oK>C9s; zcjEky{a!;-PU1Wv`l@kDR|G^U0V#@eyAx{$mJO^LqSr4&m;uHHy2RVt^TkMO(bgc% z1fKI*YggJv^CYj-xs;iX-Dorx=m|3#jo!y|P9SZqXH&%!IC(++5WQCWl~1$H*-<ok zkJqgbmP<%2p&%s6yzN_-&HTA1<zf38BjKPVPRY!{xNJoBCa2?R@#Fl81y=u6qps!! zKU=o{4}J9$948dNXs_9b2;)yxZ=Z<4nLVAy^Fb?Jx^AS*gH|M7p-L&`c<K|{gMb?y ztB(-W=_}RCDB<-BZJPGXK!r*^%f^x1+~(|+oSL<C&TTKLX?lU3uTttXLf<^Gd<pdD zcfe<OY)}quP1S9`b6FL6)oNU~XI<ptU8qe5;t#6fu1<Q%%lV#j4uhW>%xv-~-cQzn z0Hm3)<5r9eWybWA42&?carjE4NsNg3e4Qly@DEYrFAba8nOnX*G@q~av7O&mdHE;c z0O5CJlc!a;U$9K3q#cg)upH-5#fI5`DqFpAxQE_ASy#s=#egN!?BagNzBJ{$*t3*p z{1?5~10fk*iv64&{vP*@P@4-%P1gP-Id^!)T{OX?ZBFl7uj@lEw=dvwYxyerRaK^Y z^)9DSPFh6M(i;;%N<StoQI{ofhdTE1sH<nKFv_+8V0dlnr%wm7vz@+gUTb5Y<o<Su zM29`Ajg8F`)A!-PcP|D%Tx(QrHI(dbS=m)xJMlare?ii>V)nhV$5Zwgf7`h1D{uT{ zllI-LX*htt&L-{AaMocN!O)Socmt`@vv$_}C&HlE<YW3;$vM#ZnwYcn&!);H9YS)3 z_x<X`vaJ#Gfxf`TMK<kL9RFWk_jWNsxRe_@j}O*2#oqgLwe7a-3#ryR4C74iE;nVj z4O%16=rn;^kZ3R)q!IDRKt(w{q}L~DF?m0yrFlX+w|WSsZdXKiL>D@-jTz_io!#FK zh;_B*41O#z%13&uvLh}%x@U(c@(xge!~9I(;?(=96#s@&SHZ5_ipdWuH>y%z?X|z* ze57>Z2y)9$LT}c$b|BU{e(Kpv0Xwh6;w-U&uGTaoC8Xcj>bcgsqOi<xmBUq%r}j8@ z*+@Oa@*?dUF%(q*|7nrj@Dha{tq(I#N`<%OWlkm7(l`eXZX#m7rr+|75OZmMbvqC3 z0700<GnP$#`6(UB56YoeWYRL?m3h7>F6CX3uMYT}mmT37=k2p{)WgaXpOM#0Y<PYo zxeB)5oooYLCiM&|DNv#IhF%b_sCz}1#M5XN!lstF8s5sIuRbY#QLH!1jZ9%?KJQ9! zcAoL8a7biSLUPNB;Cbr(XfWf4rha?7St?H9;1K>Z=nFEB+|<cno&1<#o~T8dhRP`= zE|bpmy{Ov?Tthy!ge<J<y}~c3H|Hs_8Q3-Id7(N|8)?|{nZ!O($9={XR!<x62=sTm z+On2dDtMl$IjkQfJyWGO7oD1}hF2AncwnI>pT+LTLhLe=YkRTHU%aK!(=bzqj0t&b z0ce!a4p0NWIBSSc`Z>$<@qM?7xMP7!>qPL!_TEP>A*4OG2IS{jgr03H_b-hBTA0^Q zlKrr8Q_A(1y~X2mYR#W3vI@$_Dhq7xiYx;N{6&^Qu{M>?iuv=QId}8PZZ3W^RT(E~ zvZiBCoZK}@eg`yyCWZlwVx7{!rl3Kbe+<=ip5gMSCb>lZTPP23`anUEE3jhnbO_9+ zZ0!q9X7RpdR(oOgo(wmJ@t)y&k2FWYi%+p&A?(+;3F1BiZd&nPM?tdpvd1ov0k45h zUb*qmNPD(Q%}rqK0nA7g&jl%+13_Ca>~z>0Vvpn4;&QFllba9Tt}n}6*~^?0oW*9v zL7DbduGPSZSRs;@CJ$0Jk#*hDYE$;e3eCh(eWKJM?LxC<WCQS&SI_xZ$$ipQBqN!C zdbs6F*O1yG##+^Lsr}FUFUggRB~-tdLuLOgv6Cx3d`e)!s3x{+_%=%0_q8b_TqHn; z;^3AQ7Y~(gQx_O*!Mzla%3%@TMoMXX<r{bLBxUm15<*`1mP~U}_AN7Qz8k0%D9$F0 zpPTE|6WzFY4LjYEDy<Tm-92MF0<J(6m>7qN1M*nJ=NZzuXm>9!g6#)g#lH6Pj8tZ} z$c;&iPY=iCQ4T;%ardGf{g4l{qr>EG%ICpST|vNK!P@x9X#tam<cx)fa3U*4>4Diu z+9liaC0CGcklM-jK0TkMs!|7RkA9yrPfwpdS#)*Ygzc~3J};-U0eAz_*?Yd5%_o>g zZOQ|Q$8^5oAQvyK1e}7Qb$*B=re9fru9bH-d`<r;4Is|XW0Sk+x>#uLbw%}QN`k+j zTPXG5+O~%5Q^Srp?}}R`;uC?@>sPh$N}J^_{)J~=y7CRkvY<g1g^C?nu~*i%{z$zj z0=?e3%fzlO0TyyPHSk!RpxQh-r%bCM3}L4;A~l&-I{41C<Q?658{oJt94&V>VnTLZ zn!lD}@C+z7F;dneAxaDggf8=cs9+Qwk29AD(#s9Mk?zo}v-C68iv8f7s%T?3nz9AC zbHFzyInFL8&gqy^QM;<g-J0|d;UpN~$sq;3usJD@sytf4qQ3npMLck5vCLN7J>+?Z zIO~y5uXpVls&gUuueO3OAKDUi=0+;ErfUYzC-evc_;Wx+OwM+^ZuCnv@ydtMeXH)n zyjn~ToQzN7uu@jHJp-Y%B_hKVw}@nRb$3V|I#NO{+MS7J4im~eo}mZ$u9H?LZMzsQ zSKU<1bj#rkfz7Wxl1Qh%_074$1UHptnU8rl)eat=OOaHB9yxm_DFk707gTGe!g#!@ zC?SV-w+vN!m@~^Dw(Q+ciJnj#qGO(g5*}}GShborKk3)-KGb&z);v+EcRc7p-Yn?Q zQ0Rk}Sn0kqA5P4BRGO4C51g#<aO&Tv)ZN_&8=^R^ew+aJ0s4rVwn4Imt|7YuXS#;x zX6dPKFnzP{X1~jh8|4!O8-}W<yh<M9-CV^VUPcNa@lrg!ewC)3y@@(c0Cm-d`Spb- zm)g;9+fT2o7Lw;BT`fGf_;gm>*8v$q(I8Xbj_<sqYB|~&7s?A$JXu1FhTit}tIdh~ z=YgO0`P~s;Js?Zd#)j~Js!7*cUs%7Nbko=37=0rOEpqz%eLYw|RzD}CfcLzh<FzN> z7n&|@R9;ZHt-$9*G!Urxrn1rs$3M2Z9}!9VVR-7Nw04v*tI>Ou1H-@DEBxM_S6^a7 z_EjF|huB5m&aZsX9-ol6EB+B`fDR(?^-xpPX;62>LQjYEiEUxhicRB*Wp*qxtmN(W z@r`V>G<6$f#E##(?xs+v?tLhIw6jl+vve0gJLK1>%GYA8582q>JC!sVqc~dMbHnSF qBq4VhiK05wZ@iN~%vrw)00Ja$HXiJbTF~A354Ev$Krzkz{`ens%(Hj^ diff --git a/app/assets/images/common/code_languages/lua_small.png b/app/assets/images/common/code_languages/lua_small.png index 724fa0cfc30ce8bbad793a608edab7f234e6d28e..c1f183c58c4ff7de164a9e69af07a8ad8adc6269 100644 GIT binary patch delta 3576 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 delta 1456 zcmV;h1yA~(9Oes<NPh*0Nkl<Zc-qujzi%5i6y~V{nk_O=pdAYM1Qe(@%TvAeJT;xH zOzCE6>S*aN&}sA}Wy~aL>!$M-Pd*O?vRT<$pg}L2w<tgd4+YxyQKU@WkrYp&ob~|} zsXHF;eSAOpq=4;+;y8}PFrzVANMp1)jb|IKD%Ygv<GFgL>VJ{(4t4v~UV?EjOs%Gw zT2p|YQoEsXVp$pU2h>`*>nVM7sh{~^z9n{=$$nGGQQs)8f$#ALYX2D82Pvgs3lP|) zOX^ck62;DUgz62&)oc2Q);tQy*MpKTYd|%8F>j+Nid$*QMvl|Fl`?8XUGp(OfCxkx zRXq)M;IBfV4u7FAew85@=11@;jMchz^wD$0U3Jh~h_@>|k&Sss>@3H4L1RQu41!Mv zZ#AKDV$gk8ny*tW7+>2Af_oJJ{Zs5-S<ls^Hl;P_`8elZSyE!1%Pmxk$BmvLR%~n< z*f?5SY+O7QU~NQm<9fxQQn5KMK;8HY2A)Ak)w`wjC4cj6VOKWS`y7MM3@-LSA8onK zxcK%GZZ>3LSYuhXG>IqFexf_?>3wfVNUvxd2(_�DhtNqm*8tGjM8i3y8+H%-3p9 z*kJGjYqeIF8jokJ-@j2oLCwZ4YX&(Gp~bLW^mQ#^_ph(dc(2u!`8_*1nXuXHPF^~4 z$*1x*(tooUcGHI{jYg+N5K>yx=?mTqnhI?wm;em90EDhJ7d~AZBYM8<0nJ5f&E~=K ztM2{cD6p>sk{HqtZ!Xpa#4_hN{WcfRv|hBo0z}wGXo=X5PKs(7)n2vdiV|UU^hrSQ zD3{GOyl8D@paR)9c&js?%q7Wh&U0^W-kVaI!hcj8&ZKH}4Qdto1Ok_urkRs85L0xf zV@PXefyi)cMTzhvZnO*CM;vK1zH*Htg}llXM;eBm*GdBs*~ZA)d|NPz2#&FO9a5;* zUz$J|dBUO3b{^T+T?7EQQH@tA1qPmev%@Be4TT58swKM&+5d-TRegfEeLjVjH*81} z(tl7@Cm-!`uZ(w-!Mv)}mAn-dkk$5j-?Jd-uUv<10UT^(@y>|P%hPc9hIPAFrD|ig zqwZ|i`T!7+(9zK=4jP6I*W2kFuQ?GGv!ANr1{2keof143R7t8DKwxakjvtP}tKh1Z z>PYG<>ou!H%Do^Y055oW_@$clnt0Nw)_=I76yNf<cUp*(f${eCXC9l*&%fi>)<pi9 z1_V!drHve#(xY7g!Op{5Aqej6UGN4cph*^0nwau031niZnoNA1Kk^1F?O-x_yNvLV zh~><Z8IHU>;jJpCEuHoy!ni_Rs-mVClHfMwuHsk=MxQ?YyZ}Vb!8(_hzb{hlvwy=S zKwQtc;J(2=x+~=%*hv&cS(>If?xK%s`V8Z|zyF&z9bH|$W3ONT!FTuBvv2qg9~^wa zE-rrM9_jAxFFprj%#kXFhCm4BF+M*2nm?mRqpgb{sW7TQH5$Y+^+2yY;<c8w0X^5% zhl$k@wRZl@o|)X6sQAr45s0w?#D7Y$q(tpE76s?WO$Mo*<bU{dscZ2cHAUG}WB9E7 zUjU(tdlkJX*||X~<3|Ex1JTr#r*smTn_Qg&=E#zxd9Vq)Iz9YY`ar>&^tfsM4V<6# zdyC?kp9&CL{BE8Yc&RBH&0JJ#B_-15VSGtikO!l>*u`xCv=>DMD~LfUV}H+Ql@^z* zq}AM)?+N=!9MleL4i_rQ0j%2yIG?WVH0$hsMW7s(I~vE4CSS@*yc33<y1cUtkWh%X zy^C|cE^1TvR%h5gUlJ<+{_(!H+PhL^!}mcVkt`s40?-jss3|FvGX<WQfOH)Gvb6F{ zLnNY^>oYd0dIFLPqm0x{S}6uN@yD})C}^Zg=_x6@^CtRNfB^v4m4`140g|);0000< KMNUMnLSTXqoyPG1 diff --git a/app/assets/images/common/code_languages/php_small.png b/app/assets/images/common/code_languages/php_small.png new file mode 100644 index 0000000000000000000000000000000000000000..62a5010f39a54a3ee9f6b7e1aef1c1a8fddcae14 GIT binary patch literal 3353 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/python_small.png b/app/assets/images/common/code_languages/python_small.png index f16d48c07a02e5f23d0a79e76c64ef0e53037dfd..aa303a518a05e192b3d4d022dbb0ba65d384c4d9 100644 GIT binary patch literal 4192 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 literal 17483 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 diff --git a/app/assets/images/common/code_languages/ruby_small.png b/app/assets/images/common/code_languages/ruby_small.png new file mode 100644 index 0000000000000000000000000000000000000000..9839340f75d91f6ff98a1649a2e93644243f8b0b GIT binary patch literal 2797 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/common/code_languages/swift_small.png b/app/assets/images/common/code_languages/swift_small.png new file mode 100644 index 0000000000000000000000000000000000000000..95d9c049ae0942535af58b704349c802b24f0771 GIT binary patch literal 2631 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 literal 0 HcmV?d00001 diff --git a/app/views/HomeView.coffee b/app/views/HomeView.coffee index c055214bf..05e9f78f0 100644 --- a/app/views/HomeView.coffee +++ b/app/views/HomeView.coffee @@ -52,7 +52,7 @@ module.exports = class HomeView extends RootView @updateLanguageLogos codeLanguage updateLanguageLogos: (codeLanguage) -> - @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) + @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)") onCodeLanguageSelected: (e) -> target = $(e.target).closest('.code-language') From 1537754a1688af6050652c68a06a96558a44f6ce Mon Sep 17 00:00:00 2001 From: Nick Winter <livelily@gmail.com> Date: Sat, 19 Jul 2014 20:26:13 -0700 Subject: [PATCH 57/58] A few bugfixes, plus gigantic child window convenience for me editing levels. --- app/lib/Angel.coffee | 2 ++ app/views/editor/level/edit.coffee | 5 ++++- app/views/play/level/tome/spell.coffee | 1 + app/views/play/level/tome/spell_view.coffee | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee index 4beeffa97..3b5f59a75 100644 --- a/app/lib/Angel.coffee +++ b/app/lib/Angel.coffee @@ -213,6 +213,8 @@ module.exports = class Angel extends CocoClass work.t1 = now() Math.random = work.testWorld.rand.randf # so user code is predictable Aether.replaceBuiltin('Math', Math) + replacedLoDash = _.runInContext(window) + _[key] = replacedLoDash[key] for key, val of replacedLoDash i = 0 while i < work.testWorld.totalFrames frame = work.testWorld.getFrame i++ diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee index 6683d6a54..62666f44a 100644 --- a/app/views/editor/level/edit.coffee +++ b/app/views/editor/level/edit.coffee @@ -94,7 +94,10 @@ module.exports = class EditorLevelView extends RootView # Create a new Window with a blank LevelView scratchLevelID = @level.get('slug') + '?dev=true' scratchLevelID += "&team=#{team}" if team - @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=1024,height=560,left=10,top=10,location=0,menubar=0,scrollbars=0,status=0,titlebar=0,toolbar=0', true) + if me.get('name') is 'Nick!' + @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=2560,height=1080,left=0,top=-1600,location=1,menubar=1,scrollbars=1,status=0,titlebar=1,toolbar=1', true) + else + @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=1024,height=560,left=10,top=10,location=0,menubar=0,scrollbars=0,status=0,titlebar=0,toolbar=0', true) @childWindow.onPlayLevelViewLoaded = (e) => sendLevel() # still a hack @childWindow.focus() diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee index 0572542b3..72a897ee2 100644 --- a/app/views/play/level/tome/spell.coffee +++ b/app/views/play/level/tome/spell.coffee @@ -90,6 +90,7 @@ module.exports = class Spell problems = spellThang.aether.problems #console.log 'aether transpiled', source.length, 'to', spellThang.aether.pure.length, 'for', thangID, @spellKey else + spellThang.aether.raw = source spellThang.aether.pure = pure spellThang.aether.problems = problems #console.log 'aether reused transpilation for', thangID, @spellKey diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index 3f6ec643d..46fb62e4e 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -396,7 +396,7 @@ module.exports = class SpellView extends CocoView displayAether: (aether, isCast=false) -> @displayedAether = aether - isCast = isCast or not _.isEmpty(aether.metrics) or _.some aether.problems.errors, {type: 'runtime'} + isCast = isCast or not _.isEmpty(aether.metrics) or _.some aether.getAllProblems(), {type: 'runtime'} problem.destroy() for problem in @problems # Just in case another problem was added since clearAetherDisplay() ran. @problems = [] annotations = [] From 9724c4f2180511a43d56f81fb58d5b31fca3846c Mon Sep 17 00:00:00 2001 From: Melondonut <psamy1@nate.com> Date: Sun, 20 Jul 2014 23:19:41 +0900 Subject: [PATCH 58/58] Update ko.coffee MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi there. I'm not sure that if it is okay to to this .. but anyway I thought there were a lot of thing that I could help so I did translate a bit. I checked out the code combat website but they just says "go to github, and translate." thank you, Melondonut. 안녕하세요. 제가 이래도 되는 건지는 모르겠지만, 제가 도움이 될 수 있을 것 같아 시험삼아 조금 번역해보았습니다. 코드 컴뱃 사이트를 확인했는데, 깃헙에 가서 번역한 다음 리퀘스트하라는 말만 있더라구요; 확인해주시면 감사하겠습니다. --- app/locale/ko.coffee | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index fdc645eb4..25b6159ac 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -90,11 +90,11 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t # required: "You need to log in before you can go that way." home: - slogan: "쉽고 간단한 게임배우기" + slogan: "쉽고 간단한 게임 배우기" no_ie: "죄송하지만 코드컴뱃은 인터넷 익스플로러 9에서는 동작하지 않습니다." no_mobile: "코드 컴뱃은 모바일 기기용으로 제작되지 않았습니다. 아마 동작하지 않을 가능성이 높습니다." play: "시작" - old_browser: "브라우저가 너무 오래된 버전이라 코드컴뱃을 실행할 수 없습니다." + old_browser: "브라우저가 너무 오래된 버전이라 코드 컴뱃을 실행할 수 없습니다." old_browser_suffix: "시도해볼 수는 있겠지만..안될수도 있습니다." campaign: "캠페인" for_beginners: "초보자용" @@ -109,7 +109,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t play: choose_your_level: "레벨을 선택하세요." - adventurer_prefix: "아래에 있는 어떤 레벨도 바로 시작하실 수 있습니다.또는 포럼에서 레벨에 관해 토론하세요 :" + adventurer_prefix: "아래에 있는 아무 레벨이나 바로 시작하실 수 있습니다. 또는 포럼에서 레벨에 관해 토론하세요 :" adventurer_forum: "모험가들의 포럼" adventurer_suffix: "." campaign_beginner: "초보자 캠페인" @@ -125,7 +125,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t spectate: "관중모드" contact: - contact_us: "코드컴뱃에 전할말" + contact_us: "코드컴뱃에 전할 말" welcome: "의견은 언제든지 환영합니다. 이 양식을 이메일에 사용해 주세요!" contribute_prefix: "혹시 같이 코드컴뱃에 공헌하고 싶으시다면 홈페이지에 들러주세요 " contribute_page: "참여하기 페이지" @@ -139,15 +139,15 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t diplomat_suggestion: title: "코드 컴뱃 번역을 도와주세요!" - sub_heading: "우리는 당신의 언어 능력이필요합니다." - pitch_body: "우리는 영어로 코드컴뱃을 개발하기 시작했지만, 이미 전세계의 유저들이 코드컴뱃을 이용하고 있습니다. 그중 많은 사람들이 한국어로 플레이하기를 바랍니다. 혹시 당신이 영어/한국어에 모두 능숙하다면, Diplomat 으로 코드컴뱃에 참여해서 모든 레벨 뿐 아니라 웹사이트를 한국어로 번역할 수 있습니다." + sub_heading: "우리는 당신의 언어 능력이 필요합니다." + pitch_body: "우리는 영어로 코드컴뱃을 개발하기 시작했지만, 이미 전세계의 유저들이 코드컴뱃을 이용하고 있습니다. 그 중 많은 사람들이 한국어로 플레이하기를 바랍니다. 혹시 당신이 영어/한국어에 모두 능숙하다면, Diplomat 으로 코드컴뱃에 참여해서 모든 레벨 뿐 아니라 웹사이트를 한국어로 번역할 수 있습니다." missing_translations: "우리가 모든 내용을 한국어로 번역할때까지 기본은 영어로 제공됩니다." - learn_more: "외교관에 대해서 좀더 자세히알기" - subscribe_as_diplomat: "훌륭한 외교관으로써, 정기 구독하기" + learn_more: "외교관에 대해서 좀 더 자세히 알아보기" + subscribe_as_diplomat: "외교관을 위한 정기 구독" wizard_settings: title: "마법사 설장" - customize_avatar: "당신의 분신을 직접 꾸미세요" + customize_avatar: "당신의 아바타를 직접 꾸미세요" # active: "Active" # color: "Color" # group: "Group" @@ -163,7 +163,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t account_settings: title: "계정 설정" - not_logged_in: "로그인 하시거나 계정을 생성하여 주세요." + not_logged_in: "로그인하시거나 계정을 생성하세요." autosave: "변경 사항은 자동 저장 됩니다" me_tab: "나" picture_tab: "사진" @@ -192,17 +192,17 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t error_saving: "오류 저장" saved: "변경사항 저장 완료" password_mismatch: "비밀번호가 일치하지 않습니다." -# password_repeat: "Please repeat your password." + password_repeat: "비밀번호를 한번 더 입력해 주세요." # job_profile: "Job Profile" # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # 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" + view_profile: "나의 프로필 보기" account_profile: -# settings: "Settings" -# edit_profile: "Edit Profile" -# done_editing: "Done Editing" + settings: "설정" + edit_profile: "프로필 수정하기" + done_editing: "수정 완료" profile_for_prefix: "프로필 " profile_for_suffix: "" # featured: "Featured" @@ -357,10 +357,10 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t multiplayer: "멀티 플레이어" restart: "재시작" goals: "목표" -# success: "Success!" -# incomplete: "Incomplete" -# timed_out: "Ran out of time" -# failing: "Failing" + success: "성공!" + incomplete: "목표 미완료" + timed_out: "제한 시간 초과" + failing: "다시 한번 더 도전해보세요." action_timeline: "액션 타임라인" click_to_select: "유닛을 선택하기 위해서 유닛을 마우스로 클릭하세요." reload_title: "모든 코드가 다시 로딩 되었나요?" @@ -400,8 +400,8 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t editor_config: "에디터 설정" editor_config_title: "에디터 설정" # editor_config_level_language_label: "Language for This Level" -# editor_config_level_language_description: "Define the programming language for this particular level." -# editor_config_default_language_label: "Default Programming Language" + editor_config_level_language_description: "이 레벨에서 사용할 언어를 선택하세요." + editor_config_default_language_label: "기본 프로그래밍 언어" # editor_config_default_language_description: "Define the programming language you want to code in when starting new levels." editor_config_keybindings_label: "단축키 설정" editor_config_keybindings_default: "기본(Ace)" @@ -414,7 +414,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t editor_config_indentguides_description: "들여쓰기 확인위해 세로줄 표시하기." editor_config_behaviors_label: "자동 기능" editor_config_behaviors_description: "괄호, 인용부호, 따옴표 자동 완성." -# keyboard_shortcuts: "Key Shortcuts" + keyboard_shortcuts: "단축키" # loading_ready: "Ready!" # tip_insert_positions: "Shift+Click a point on the map to insert it into the spell editor." # tip_toggle_play: "Toggle play/paused with Ctrl+P."