<commit_before>"use strict";

//-----------------------------------------------------------------------------

let [processPath, , exchangeId, methodName, ... params] = process.argv.filter (x => !x.startsWith ('--'))
    , verbose = process.argv.includes ('--verbose')
    , debug = process.argv.includes ('--verbose')
    , cloudscrape = process.argv.includes ('--cloudscrape')
    , cfscrape = process.argv.includes ('--cfscrape')
    , poll = process.argv.includes ('--poll')
    , no_send = process.argv.includes ('--no-send')
    , no_load_markets = process.argv.includes ('--no-load-markets')
    , details = process.argv.includes ('--details')
    , no_table = process.argv.includes ('--no-table')
    , iso8601 = process.argv.includes ('--iso8601')

//-----------------------------------------------------------------------------

const ccxt         = require ('../../ccxt.js')
    , fs           = require ('fs')
    , path         = require ('path')
    , ansi         = require ('ansicolor').nice
    , asTable      = require ('as-table').configure ({

        delimiter: ' | '.lightGray.dim,
        right: true,
        title: x => String (x).lightGray,
        dash: '-'.lightGray.dim,
        print: x => {
            if ((typeof x === 'string') && x.startsWith ('2018-')) {
                return new Date (x).toLocaleString ()
            } else if (typeof x === 'object') {
                const j = JSON.stringify (x).trim ()
                if (j.length < 100) return j
            }
            return String (x)
        }
    })
    , util         = require ('util')
    , { execSync } = require ('child_process')
    , log          = require ('ololog').configure ({ locate: false }).unlimited
    , { ExchangeError, NetworkError } = ccxt

//-----------------------------------------------------------------------------

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

//-----------------------------------------------------------------------------
// cloudscraper helper

const scrapeCloudflareHttpHeaderCookie = (url) =>

	(new Promise ((resolve, reject) => {

        const cloudscraper = require ('cloudscraper')
		return cloudscraper.get (url, function (error, response, body) {

			if (error) {

                log.red ('Cloudscraper error')
				reject (error)

			} else {

				resolve (response.request.headers)
			}
        })
    }))

const cfscrapeCookies = (url) => {

    const command = [
        `python -c "`,
        `import cfscrape; `,
        `import json; `,
        `tokens, user_agent = cfscrape.get_tokens('${url}'); `,
        `print(json.dumps({`,
            `'Cookie': '; '.join([key + '=' + tokens[key] for key in tokens]), `,
            `'User-Agent': user_agent`,
        `}));" 2> /dev/null`
    ].join ('')

    const output = execSync (command)
    return JSON.parse (output.toString ('utf8'))
}

//-----------------------------------------------------------------------------

const timeout = 30000
let exchange = undefined
const enableRateLimit = true

try {

    exchange = new (ccxt)[exchangeId] ({ timeout, enableRateLimit })

} catch (e) {

    log.red (e)
    printUsage ()
    process.exit ()
}

//-----------------------------------------------------------------------------

// set up keys and settings, if any
const keysGlobal = path.resolve ('keys.json')
const keysLocal = path.resolve ('keys.local.json')

let globalKeysFile = fs.existsSync (keysGlobal) ? keysGlobal : false
let localKeysFile = fs.existsSync (keysLocal) ? keysLocal : globalKeysFile
let settings = localKeysFile ? (require (localKeysFile)[exchangeId] || {}) : {}

Object.assign (exchange, settings)

//-----------------------------------------------------------------------------

function printSupportedExchanges () {
    log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
}

//-----------------------------------------------------------------------------

 function printUsage () {
    log ('This is an example of a basic command-line interface to all exchanges')
    log ('Usage: node', process.argv[1], 'id'.green, 'method'.yellow, '"param1" param2 "param3" param4 ...'.blue)
    log ('Examples:')
    log ('node', process.argv[1], 'okcoinusd fetchOHLCV BTC/USD 15m')
    log ('node', process.argv[1], 'bitfinex fetchBalance')
    log ('node', process.argv[1], 'kraken fetchOrderBook ETH/BTC')
    printSupportedExchanges ()
    log ('Supported options:')
    log ('--verbose         Print verbose output')
    log ('--debug           Print debugging output')
    log ('--cloudscrape     Use https://github.com/codemanki/cloudscraper to bypass Cloudflare')
    log ('--cfscrape        Use https://github.com/Anorov/cloudflare-scrape to bypass Cloudflare (requires python and cfscrape)')
    log ('--poll            Repeat continuously in rate-limited mode')
    log ("--no-send         Print the request but don't actually send it to the exchange (sets verbose and load-markets)")
    log ('--no-load-markets Do not pre-load markets (for debugging)')
    log ('--details         Print detailed fetch responses')
    log ('--no-table        Do not print tabulated fetch responses')
    log ('--iso8601         Print timestamps as ISO8601 datetimes')
}

//-----------------------------------------------------------------------------

const printHumanReadable = (exchange, result) => {

    if (Array.isArray (result)) {

        let arrayOfObjects = (typeof result[0] === 'object')

        if (details)
            result.forEach (object => {
                if (arrayOfObjects)
                    log ('-------------------------------------------')
                log (object)
            })

        if (!no_table)
            if (arrayOfObjects) {
                log (result.length > 0 ? asTable (result.map (element => {
                    let keys = Object.keys (element)
                    delete element['info']
                    keys.forEach (key => {
                        if (typeof element[key] === 'number') {
                            if (!iso8601)
                                return element[key]
                            try {
                                const iso8601 = exchange.iso8601 (element[key])
                                if (iso8601.match (/^20[0-9]{2}[-]?/))
                                    element[key] = iso8601
                                else
                                    throw new Error ('wrong date')
                            } catch (e) {
                                return element[key]
                            }
                        }
                    })
                    return element
                })) : result)
                log (result.length, 'objects');
            } else {
                log (result)
                log (result.length, 'objects');
            }

    } else {

        log (result)
    }
}

//-----------------------------------------------------------------------------

async function main () {

    const requirements = exchangeId && methodName
    if (!requirements) {

        printUsage ()

    } else {

        let args = params.map (param => {
            if (param === 'undefined')
                return undefined
            if (param[0] === '{' || param[0] === '[')
                return JSON.parse (param)
            if (param.match (/[0-9]{4}[-]?[0-9]{2}[-]?[0-9]{2}[T\s]?[0-9]{2}[:]?[0-9]{2}[:]?[0-9]{2}/g))
                return exchange.parse8601 (param)
            if (param.match (/[a-zA-Z-]/g))
                return param
            if (param.match (/^[+0-9\.-]+$/))
                return parseFloat (param)
            return param
        })

        const www = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www

        if (cloudscrape)
            exchange.headers = await scrapeCloudflareHttpHeaderCookie (www)

        if (cfscrape)
            exchange.headers = cfscrapeCookies (www)

        no_load_markets = no_send ? true : no_load_markets

        if (debug) {
            exchange.verbose = verbose
        }

        if (!no_load_markets) {
            await exchange.loadMarkets ()
        }

        exchange.verbose = verbose

        if (no_send) {

            exchange.verbose = no_send
            exchange.fetch = function fetch (url, method = 'GET', headers = undefined, body = undefined) {
                log.dim.noLocate ('-------------------------------------------')
                log.dim.noLocate (exchange.iso8601 (exchange.milliseconds ()))
                log.green.unlimited ({
                    url,
                    method,
                    headers,
                    body,
                })
                process.exit ()
            }
        }

        if (typeof exchange[methodName] === 'function') {

            log (exchange.id + '.' + methodName, '(' + args.join (', ') + ')')

            while (true) {

                try {

                    const result = await exchange[methodName] (... args)
                    printHumanReadable (exchange, result)

                } catch (e) {

                    if (e instanceof ExchangeError) {

                        log.red (e.constructor.name, e.message)

                    } else if (e instanceof NetworkError) {

                        log.yellow (e.constructor.name, e.message)

                    }

                    log.dim ('---------------------------------------------------')

                    // rethrow for call-stack // other errors
                    throw e

                }

                if (!poll)
                    break;
            }

        } else if (typeof exchange[methodName] === 'undefined') {

            log.red (exchange.id + '.' + methodName + ': no such property')

        } else {

            printHumanReadable (exchange, exchange[methodName])
        }
    }
}

//-----------------------------------------------------------------------------

main ()
<commit_msg>cli.js args eval<commit_after>"use strict";

//-----------------------------------------------------------------------------

let [processPath, , exchangeId, methodName, ... params] = process.argv.filter (x => !x.startsWith ('--'))
    , verbose = process.argv.includes ('--verbose')
    , debug = process.argv.includes ('--verbose')
    , cloudscrape = process.argv.includes ('--cloudscrape')
    , cfscrape = process.argv.includes ('--cfscrape')
    , poll = process.argv.includes ('--poll')
    , no_send = process.argv.includes ('--no-send')
    , no_load_markets = process.argv.includes ('--no-load-markets')
    , details = process.argv.includes ('--details')
    , no_table = process.argv.includes ('--no-table')
    , iso8601 = process.argv.includes ('--iso8601')

//-----------------------------------------------------------------------------

const ccxt         = require ('../../ccxt.js')
    , fs           = require ('fs')
    , path         = require ('path')
    , ansi         = require ('ansicolor').nice
    , asTable      = require ('as-table').configure ({

        delimiter: ' | '.lightGray.dim,
        right: true,
        title: x => String (x).lightGray,
        dash: '-'.lightGray.dim,
        print: x => {
            if ((typeof x === 'string') && x.startsWith ('2018-')) {
                return new Date (x).toLocaleString ()
            } else if (typeof x === 'object') {
                const j = JSON.stringify (x).trim ()
                if (j.length < 100) return j
            }
            return String (x)
        }
    })
    , util         = require ('util')
    , { execSync } = require ('child_process')
    , log          = require ('ololog').configure ({ locate: false }).unlimited
    , { ExchangeError, NetworkError } = ccxt

//-----------------------------------------------------------------------------

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

//-----------------------------------------------------------------------------
// cloudscraper helper

const scrapeCloudflareHttpHeaderCookie = (url) =>

	(new Promise ((resolve, reject) => {

        const cloudscraper = require ('cloudscraper')
		return cloudscraper.get (url, function (error, response, body) {

			if (error) {

                log.red ('Cloudscraper error')
				reject (error)

			} else {

				resolve (response.request.headers)
			}
        })
    }))

const cfscrapeCookies = (url) => {

    const command = [
        `python -c "`,
        `import cfscrape; `,
        `import json; `,
        `tokens, user_agent = cfscrape.get_tokens('${url}'); `,
        `print(json.dumps({`,
            `'Cookie': '; '.join([key + '=' + tokens[key] for key in tokens]), `,
            `'User-Agent': user_agent`,
        `}));" 2> /dev/null`
    ].join ('')

    const output = execSync (command)
    return JSON.parse (output.toString ('utf8'))
}

//-----------------------------------------------------------------------------

const timeout = 30000
let exchange = undefined
const enableRateLimit = true

try {

    exchange = new (ccxt)[exchangeId] ({ timeout, enableRateLimit })

} catch (e) {

    log.red (e)
    printUsage ()
    process.exit ()
}

//-----------------------------------------------------------------------------

// set up keys and settings, if any
const keysGlobal = path.resolve ('keys.json')
const keysLocal = path.resolve ('keys.local.json')

let globalKeysFile = fs.existsSync (keysGlobal) ? keysGlobal : false
let localKeysFile = fs.existsSync (keysLocal) ? keysLocal : globalKeysFile
let settings = localKeysFile ? (require (localKeysFile)[exchangeId] || {}) : {}

Object.assign (exchange, settings)

//-----------------------------------------------------------------------------

function printSupportedExchanges () {
    log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
}

//-----------------------------------------------------------------------------

 function printUsage () {
    log ('This is an example of a basic command-line interface to all exchanges')
    log ('Usage: node', process.argv[1], 'id'.green, 'method'.yellow, '"param1" param2 "param3" param4 ...'.blue)
    log ('Examples:')
    log ('node', process.argv[1], 'okcoinusd fetchOHLCV BTC/USD 15m')
    log ('node', process.argv[1], 'bitfinex fetchBalance')
    log ('node', process.argv[1], 'kraken fetchOrderBook ETH/BTC')
    printSupportedExchanges ()
    log ('Supported options:')
    log ('--verbose         Print verbose output')
    log ('--debug           Print debugging output')
    log ('--cloudscrape     Use https://github.com/codemanki/cloudscraper to bypass Cloudflare')
    log ('--cfscrape        Use https://github.com/Anorov/cloudflare-scrape to bypass Cloudflare (requires python and cfscrape)')
    log ('--poll            Repeat continuously in rate-limited mode')
    log ("--no-send         Print the request but don't actually send it to the exchange (sets verbose and load-markets)")
    log ('--no-load-markets Do not pre-load markets (for debugging)')
    log ('--details         Print detailed fetch responses')
    log ('--no-table        Do not print tabulated fetch responses')
    log ('--iso8601         Print timestamps as ISO8601 datetimes')
}

//-----------------------------------------------------------------------------

const printHumanReadable = (exchange, result) => {

    if (Array.isArray (result)) {

        let arrayOfObjects = (typeof result[0] === 'object')

        if (details)
            result.forEach (object => {
                if (arrayOfObjects)
                    log ('-------------------------------------------')
                log (object)
            })

        if (!no_table)
            if (arrayOfObjects) {
                log (result.length > 0 ? asTable (result.map (element => {
                    let keys = Object.keys (element)
                    delete element['info']
                    keys.forEach (key => {
                        if (typeof element[key] === 'number') {
                            if (!iso8601)
                                return element[key]
                            try {
                                const iso8601 = exchange.iso8601 (element[key])
                                if (iso8601.match (/^20[0-9]{2}[-]?/))
                                    element[key] = iso8601
                                else
                                    throw new Error ('wrong date')
                            } catch (e) {
                                return element[key]
                            }
                        }
                    })
                    return element
                })) : result)
                log (result.length, 'objects');
            } else {
                log (result)
                log (result.length, 'objects');
            }

    } else {

        log (result)
    }
}

//-----------------------------------------------------------------------------

async function main () {

    const requirements = exchangeId && methodName
    if (!requirements) {

        printUsage ()

    } else {

        let args = params
            .map (s => s.match (/[0-9]{4}[-]?[0-9]{2}[-]?[0-9]{2}[T\s]?[0-9]{2}[:]?[0-9]{2}[:]?[0-9]{2}/g) ? exchange.parse8601 (s) : s)
            .map (s => (() => { try { return eval ('(() => (' + s + ')) ()') } catch (e) { return s } }) ())

        const www = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www

        if (cloudscrape)
            exchange.headers = await scrapeCloudflareHttpHeaderCookie (www)

        if (cfscrape)
            exchange.headers = cfscrapeCookies (www)

        no_load_markets = no_send ? true : no_load_markets

        if (debug) {
            exchange.verbose = verbose
        }

        if (!no_load_markets) {
            await exchange.loadMarkets ()
        }

        exchange.verbose = verbose

        if (no_send) {

            exchange.verbose = no_send
            exchange.fetch = function fetch (url, method = 'GET', headers = undefined, body = undefined) {
                log.dim.noLocate ('-------------------------------------------')
                log.dim.noLocate (exchange.iso8601 (exchange.milliseconds ()))
                log.green.unlimited ({
                    url,
                    method,
                    headers,
                    body,
                })
                process.exit ()
            }
        }

        if (typeof exchange[methodName] === 'function') {

            log (exchange.id + '.' + methodName, '(' + args.join (', ') + ')')

            while (true) {

                try {

                    const result = await exchange[methodName] (... args)
                    printHumanReadable (exchange, result)

                } catch (e) {

                    if (e instanceof ExchangeError) {

                        log.red (e.constructor.name, e.message)

                    } else if (e instanceof NetworkError) {

                        log.yellow (e.constructor.name, e.message)

                    }

                    log.dim ('---------------------------------------------------')

                    // rethrow for call-stack // other errors
                    throw e

                }

                if (!poll)
                    break;
            }

        } else if (typeof exchange[methodName] === 'undefined') {

            log.red (exchange.id + '.' + methodName + ': no such property')

        } else {

            printHumanReadable (exchange, exchange[methodName])
        }
    }
}

//-----------------------------------------------------------------------------

main ()
<|endoftext|>


<commit_before><commit_msg>pull request #402 from j0kaso/master structure path availability<commit_after><|endoftext|>


<commit_before>/*jshint esversion: 6 */

var harvestAction = require('action.harvest');
var transferAction = require('action.transfer');
var idleAction = require('action.idle');

var roleHarvester = {
    run: function(creep) {
        var source = _findSource(creep);
        var target = _findTarget(creep.room);

        transferAction.run(creep, target, "harvest");
        harvestAction.run(creep, source, "transfer");
        idleAction.run(creep, { x:30, y:14 }, _stopIdleCondition, 'harvest');
    }
};

function _findSource(creep) {
    var source = creep.room.find(FIND_SOURCES)[0]; // TODO: choose nearest source
    return source;
}

function _findTarget(room) {
    var targets = room.find(FIND_STRUCTURES, {
            filter: (structure) => {
                return ([STRUCTURE_SPAWN, STRUCTURE_EXTENSION, STRUCTURE_TOWER].indexOf(structure.structureType) > -1 &&
                        structure.energy < structure.energyCapacity) ||
                    ([STRUCTURE_CONTAINER].indexOf(structure.structureType) > -1 &&
                        structure.store.energy < structure.energyCapacity);
            }
    });
    return targets[0]; // TODO: find closest target
}

function _stopIdleCondition(creep) {
    var target = _findTarget(creep);
    return target !== null && typeof target !== 'undefined';
}

module.exports = roleHarvester;
<commit_msg>Fix Harvester role<commit_after>/*jshint esversion: 6 */

var harvestAction = require('action.harvest');
var transferAction = require('action.transfer');
var idleAction = require('action.idle');

var roleHarvester = {
    run: function(creep) {
        var source = _findSource(creep);
        var target = _findTarget(creep);

        transferAction.run(creep, target, "harvest");
        harvestAction.run(creep, source, "transfer");
        idleAction.run(creep, { x:30, y:14 }, _stopIdleCondition, 'harvest');
    }
};

function _findSource(creep) {
    var source = creep.room.find(FIND_SOURCES)[0]; // TODO: choose nearest source
    return source;
}

function _findTarget(creep) {
    var targets = creep.room.find(FIND_STRUCTURES, {
            filter: (structure) => {
                return ([STRUCTURE_SPAWN, STRUCTURE_EXTENSION, STRUCTURE_TOWER].indexOf(structure.structureType) > -1 &&
                        structure.energy < structure.energyCapacity) ||
                    ([STRUCTURE_CONTAINER].indexOf(structure.structureType) > -1 &&
                        structure.store.energy < structure.energyCapacity);
            }
    });
    return targets[0]; // TODO: find closest target
}

function _stopIdleCondition(creep) {
    var target = _findTarget(creep);
    return target !== null && typeof target !== 'undefined';
}

module.exports = roleHarvester;
<|endoftext|>


<commit_before>'use strict'

const MetaRole = require('roles_meta')

class Factotum extends MetaRole {
  constructor () {
    super()
    this.defaultEnergy = 800
  }

  getPriority (creep) {
    return PRIORITIES_CREEP_FACTOTUM
  }

  getBuild (room, options) {
    this.setBuildDefaults(room, options)
    let build = [MOVE, CARRY, CARRY, CARRY, CARRY]
    return Creep.buildFromTemplate(build, options.energy)
  }

  manageCreep (creep) {
    if (creep.ticksToLive < 50) {
      return creep.recycle()
    }

    if (creep.memory.labs) {
      if (creep.memory.labs === 'fill') {
        this.fillFeeders(creep)
      } else {
        this.emptyLabs(creep)
      }
      return
    }

    if (_.sum(creep.carry) > 0) {
      if (creep.carry[RESOURCE_ENERGY]) {
        this.emptyEnergy(creep)
      } else {
        this.emptyResources(creep)
      }
      return
    }

    const storage = creep.room.storage
    const terminal = creep.room.terminal

    // empty link
    const storageLink = storage.getLink()
    if (storageLink && storageLink.energy) {
      if (creep.pos.isNearTo(storageLink)) {
        creep.withdraw(storageLink, RESOURCE_ENERGY)
      } else {
        this.goHome(creep)
      }
      return
    }

    if (terminal && terminal.store[RESOURCE_ENERGY] > TERMINAL_ENERGY) {
      const overflow = terminal.store[RESOURCE_ENERGY] - TERMINAL_ENERGY
      const transferAmount = overflow < creep.carryCapacity ? overflow : creep.carryCapacity
      creep.withdraw(terminal, RESOURCE_ENERGY, transferAmount)
      return
    }

    // pick up dropped resources and creep renewal energy and empty tombstones
    const suicideBooth = creep.room.getSuicideBooth()
    if (suicideBooth) {
      const resources = suicideBooth.lookFor(LOOK_RESOURCES)
      if (resources.length > 0) {
        console.log("Found resources on suicide booth")
        if (creep.pos.isNearTo(suicideBooth)) {
          creep.pickup(resources[0])
        } else {
          this.goHome(creep)
        }
        return
      } else {
        const tombstones = suicideBooth.lookFor(LOOK_TOMBSTONES)
        if (tombstones.length > 0) {
          console.log("Found tombstone on suicide booth")
          if (creep.pos.isNearTo(suicideBooth)) {
            console.log("Withdrawing from tombstone")
            creep.withdraw(tombstones[0], Object.keys(tombstones[0].store)[0])
          } else {
            this.goHome(creep)
          }
          return
        }
      }
    }

    if (terminal && storage) {
      // Does terminal have something storage needs?
      const terminalResources = _.shuffle(Object.keys(terminal.store))
      for (const resource of terminalResources) {
        if (resource === RESOURCE_ENERGY) {
          continue
        }
        const need = storage.getResourceNeed(resource)
        if (need > 0) {
          const amount = Math.min(need, creep.carryCapacity - creep.carry, terminal.store[resource])
          creep.withdraw(terminal, resource, amount)
          return
        }
      }

      // Does storage have terminal overflow?
      const storageResources = _.shuffle(Object.keys(storage.store))
      for (const resource of storageResources) {
        if (resource === RESOURCE_ENERGY) {
          continue
        }
        const need = storage.getResourceNeed(resource)
        if (need < 0) {
          const amount = Math.min((-need), creep.carryCapacity - creep.carry, terminal.store[resource])
          creep.withdraw(storage, resource, amount)
          return
        }
      }
    }

    creep.memory.labs = 'fill'
  }

  fillFeeders (creep) {
    const reaction = creep.room.getActiveReaction()
    const feeders = creep.room.getFeederLabs()
    if (!reaction || !feeders || feeders.length < 2) {
      delete creep.memory.labs
      delete creep.memory.filling
      return
    }

    if (feeders[0].mineralAmount > 0 && feeders[0].mineralType !== reaction[0]) {
      creep.memory.labs = 'empty'
      return
    }
    if (feeders[1].mineralAmount > 0 && feeders[1].mineralType !== reaction[1]) {
      creep.memory.labs = 'empty'
      return
    }

    if (_.sum(creep.carry) <= 0) {
      if (feeders[0].mineralAmount / feeders[0].mineralCapacity >= 0.5) {
        if (feeders[1].mineralAmount / feeders[1].mineralCapacity >= 0.5) {
          creep.memory.labs = 'empty'
        }
      }
    }

    const carrying = Object.keys(creep.carry)
    if (carrying.length > 3) {
      creep.memory.labs = 'empty'
      return
    }

    const individualMax = creep.carryCapacity / 2
    let reactionPrimaryAvailable = creep.room.storage.store[reaction[0]]
    if (creep.carry[reaction[0]]) {
      reactionPrimaryAvailable += creep.carry[reaction[0]]
    }
    let reactionSecondaryAvailable = creep.room.storage.store[reaction[1]]
    if (creep.carry[reaction[1]]) {
      reactionSecondaryAvailable += creep.carry[reaction[1]]
    }

    let primaryTargetAmount = Math.min(individualMax, reactionPrimaryAvailable, reactionSecondaryAvailable)
    if (feeders[0].mineralAmount / feeders[0].mineralCapacity >= 0.5) {
      primaryTargetAmount = 0
    }

    let secondaryTargetAmount = Math.min(individualMax, reactionPrimaryAvailable, reactionSecondaryAvailable)
    if (feeders[1].mineralAmount / feeders[1].mineralCapacity >= 0.5) {
      secondaryTargetAmount = 0
    }

    if (primaryTargetAmount <= 0 && secondaryTargetAmount <= 0) {
      creep.memory.labs = 'empty'
      return
    }

    if (creep.carry[carrying[0]] > primaryTargetAmount || creep.carry[carrying[1]] > secondaryTargetAmount) {
      creep.memory.labs = 'empty'
      return
    }

    if (creep.memory.filling) {
      if (creep.carry[reaction[0]] && feeders[0].canFill()) {
        if (creep.pos.isNearTo(feeders[0])) {
          creep.transfer(feeders[0], reaction[0])
        } else {
          creep.travelTo(feeders[0], {'ignoreCore': true})
        }
      } else if (creep.carry[reaction[1]] && feeders[1].canFill()) {
        if (creep.pos.isNearTo(feeders[1])) {
          creep.transfer(feeders[1], reaction[1])
        } else {
          creep.travelTo(feeders[1], {'ignoreCore': true})
        }
      } else {
        delete creep.memory.filling
        creep.memory.labs = 'empty'
      }
    } else {
      if (!creep.pos.isNearTo(creep.room.storage)) {
        this.goHome(creep)
        return
      }

      if (creep.carryCapacity === _.sum(creep.carry)) {
        creep.memory.filling = true
        return
      }

      if (!creep.carry[reaction[0]] || creep.carry[reaction[0]] < primaryTargetAmount) {
        const amount = creep.carry[reaction[0]] ? primaryTargetAmount - creep.carry[reaction[0]] : primaryTargetAmount
        creep.withdraw(creep.room.storage, reaction[0], Math.min(amount, creep.carryCapacity - _.sum(creep.carry)))
      } else if (!creep.carry[reaction[1]] || creep.carry[reaction[1]] < secondaryTargetAmount) {
        const amount = creep.carry[reaction[1]] ? secondaryTargetAmount - creep.carry[reaction[1]] : secondaryTargetAmount
        creep.withdraw(creep.room.storage, reaction[1], Math.min(amount, creep.carryCapacity - _.sum(creep.carry)))
      } else {
        creep.memory.filling = true
      }
    }
  }

  emptyLabs (creep) {
    if (creep.carryCapacity - _.sum(creep.carry) <= 0) {
      delete creep.memory.labs
      return
    }
    const lab = this.getLabToEmpty(creep)
    if (!lab) {
      delete creep.memory.labs
      return
    }
    if (creep.pos.isNearTo(lab)) {
      creep.withdraw(lab, lab.mineralType)
    } else {
      creep.travelTo(lab, {'ignoreCore': true})
    }
  }

  getLabToEmpty (creep) {
    const feeders = creep.room.getFeederLabs()
    const reaction = creep.room.getActiveReaction()

    // If one feeder doesn't have the right mineral and the other is empty then empty the first.
    if (feeders[0].mineralAmount) {
      if (feeders[1].mineralAmount < LAB_REACTION_AMOUNT && feeders[0].mineralType !== reaction[0]) {
        return feeders[0]
      }
    }
    if (feeders[1].mineralAmount) {
      if (feeders[0].mineralAmount < LAB_REACTION_AMOUNT && feeders[1].mineralType !== reaction[1]) {
        return feeders[1]
      }
    }

    // If feeders can not produce a reaction start emptying them.
    // Once one is empty the above code will finish the other.
    if (feeders[0].mineralAmount > 0 && feeders[1].mineralAmount > 0) {
      if (!REACTIONS[feeders[0].mineralType][feeders[1].mineralType]) {
        return feeders[0]
      }
    }

    // Empty vats that don't have a boost that will work with the feeders, or that are filling up.
    const vats = creep.room.getVatLabs()
    let currentProduct = false
    if (feeders[0].mineralAmount > 0 && feeders[1].mineralAmount > 0) {
      currentProduct = REACTIONS[feeders[0].mineralType][feeders[1].mineralType]
    }
    const desiredProduct = REACTIONS[reaction[0]][reaction[1]]
    let target = false
    let amount = 150
    for (const vat of vats) {
      if (!vat.mineralType) {
        continue
      }
      if ((!currentProduct || vat.mineralType !== currentProduct) && vat.mineralType !== desiredProduct) {
        return vat
      }
      if (vat.mineralAmount > amount) {
        amount = vat.mineralAmount
        target = vat
      }
    }
    return target
  }

  emptyEnergy (creep) {
    // fill terminal with energy
    if (creep.room.terminal && creep.room.terminal.store[RESOURCE_ENERGY] < TERMINAL_ENERGY) {
      if (creep.pos.isNearTo(creep.room.terminal)) {
        const need = TERMINAL_ENERGY - creep.room.terminal.store[RESOURCE_ENERGY]
        const amount = need > creep.carry[RESOURCE_ENERGY] ? creep.carry[RESOURCE_ENERGY] : need
        creep.transfer(creep.room.terminal, RESOURCE_ENERGY, amount)
      } else {
        this.goHome(creep)
      }
      return
    }

    if (creep.room.structures[STRUCTURE_NUKER] && creep.room.isEconomyCapable('FILL_NUKER')) {
      const nuker = creep.room.structures[STRUCTURE_NUKER][0]
      if (nuker.energy < nuker.energyCapacity) {
        this.dumpEnergyToStructure(creep, nuker)
        return
      }
    }

    if (creep.room.structures[STRUCTURE_POWER_SPAWN] && creep.room.isEconomyCapable('FILL_POWER_SPAWN')) {
      const powerspawn = creep.room.structures[STRUCTURE_POWER_SPAWN][0]
      if (powerspawn.energy < powerspawn.energyCapacity) {
        this.dumpEnergyToStructure(creep, powerspawn)
        return
      }
    }

    // fill storage with energy
    this.dumpEnergyToStructure(creep, creep.room.storage)
  }

  dumpEnergyToStructure (creep, structure) {
    if (creep.pos.isNearTo(structure)) {
      creep.transfer(structure, RESOURCE_ENERGY)
    } else {
      creep.travelTo(structure, {'ignoreCore': true})
    }
  }

  emptyResources (creep) {
    // Must be near storage to empty creep.
    if (!creep.pos.isNearTo(creep.room.storage)) {
      this.goHome(creep)
      return
    }

    const resources = _.filter(Object.keys(creep.carry), a => a !== RESOURCE_ENERGY)
    if (resources.length < 1) {
      return false
    }
    const resource = resources[0]

    // If there's no other option just put it all in storage.
    if (!creep.room.terminal) {
      creep.transfer(creep.room.storage, resource)
      return true
    }

    // Intermediate boosts should stay in room.
    const resourceType = Mineral.getResourceType(resource)
    if (resourceType === 'tier1' || resourceType === 'tier2') {
      creep.transfer(creep.room.storage, resource)
      return true
    }

    // Put needed resources into storage and excess into terminal.
    const currentNeed = creep.room.storage.getResourceNeed(resource)
    if (currentNeed > 0) {
      const amount = creep.carry[resource] < currentNeed ? creep.carry[resource] : currentNeed
      creep.transfer(creep.room.storage, resource, amount)
    } else {
      if (creep.pos.isNearTo(creep.room.terminal)) {
        creep.transfer(creep.room.terminal, resource)
      } else {
        this.goHome(creep)
      }
    }
    return true
  }

  goHome (creep) {
    return creep.travelTo(creep.room.getFactotumHome(), {'ignoreCore': true})
  }
}

module.exports = Factotum
<commit_msg>Removed console.logs<commit_after>'use strict'

const MetaRole = require('roles_meta')

class Factotum extends MetaRole {
  constructor () {
    super()
    this.defaultEnergy = 800
  }

  getPriority (creep) {
    return PRIORITIES_CREEP_FACTOTUM
  }

  getBuild (room, options) {
    this.setBuildDefaults(room, options)
    let build = [MOVE, CARRY, CARRY, CARRY, CARRY]
    return Creep.buildFromTemplate(build, options.energy)
  }

  manageCreep (creep) {
    if (creep.ticksToLive < 50) {
      return creep.recycle()
    }

    if (creep.memory.labs) {
      if (creep.memory.labs === 'fill') {
        this.fillFeeders(creep)
      } else {
        this.emptyLabs(creep)
      }
      return
    }

    if (_.sum(creep.carry) > 0) {
      if (creep.carry[RESOURCE_ENERGY]) {
        this.emptyEnergy(creep)
      } else {
        this.emptyResources(creep)
      }
      return
    }

    const storage = creep.room.storage
    const terminal = creep.room.terminal

    // empty link
    const storageLink = storage.getLink()
    if (storageLink && storageLink.energy) {
      if (creep.pos.isNearTo(storageLink)) {
        creep.withdraw(storageLink, RESOURCE_ENERGY)
      } else {
        this.goHome(creep)
      }
      return
    }

    if (terminal && terminal.store[RESOURCE_ENERGY] > TERMINAL_ENERGY) {
      const overflow = terminal.store[RESOURCE_ENERGY] - TERMINAL_ENERGY
      const transferAmount = overflow < creep.carryCapacity ? overflow : creep.carryCapacity
      creep.withdraw(terminal, RESOURCE_ENERGY, transferAmount)
      return
    }

    // pick up dropped resources and creep renewal energy and empty tombstones
    const suicideBooth = creep.room.getSuicideBooth()
    if (suicideBooth) {
      const resources = suicideBooth.lookFor(LOOK_RESOURCES)
      if (resources.length > 0) {
        if (creep.pos.isNearTo(suicideBooth)) {
          creep.pickup(resources[0])
        } else {
          this.goHome(creep)
        }
        return
      } else {
        const tombstones = suicideBooth.lookFor(LOOK_TOMBSTONES)
        if (tombstones.length > 0) {
          if (creep.pos.isNearTo(suicideBooth)) {
            creep.withdraw(tombstones[0], Object.keys(tombstones[0].store)[0])
          } else {
            this.goHome(creep)
          }
          return
        }
      }
    }

    if (terminal && storage) {
      // Does terminal have something storage needs?
      const terminalResources = _.shuffle(Object.keys(terminal.store))
      for (const resource of terminalResources) {
        if (resource === RESOURCE_ENERGY) {
          continue
        }
        const need = storage.getResourceNeed(resource)
        if (need > 0) {
          const amount = Math.min(need, creep.carryCapacity - creep.carry, terminal.store[resource])
          creep.withdraw(terminal, resource, amount)
          return
        }
      }

      // Does storage have terminal overflow?
      const storageResources = _.shuffle(Object.keys(storage.store))
      for (const resource of storageResources) {
        if (resource === RESOURCE_ENERGY) {
          continue
        }
        const need = storage.getResourceNeed(resource)
        if (need < 0) {
          const amount = Math.min((-need), creep.carryCapacity - creep.carry, terminal.store[resource])
          creep.withdraw(storage, resource, amount)
          return
        }
      }
    }

    creep.memory.labs = 'fill'
  }

  fillFeeders (creep) {
    const reaction = creep.room.getActiveReaction()
    const feeders = creep.room.getFeederLabs()
    if (!reaction || !feeders || feeders.length < 2) {
      delete creep.memory.labs
      delete creep.memory.filling
      return
    }

    if (feeders[0].mineralAmount > 0 && feeders[0].mineralType !== reaction[0]) {
      creep.memory.labs = 'empty'
      return
    }
    if (feeders[1].mineralAmount > 0 && feeders[1].mineralType !== reaction[1]) {
      creep.memory.labs = 'empty'
      return
    }

    if (_.sum(creep.carry) <= 0) {
      if (feeders[0].mineralAmount / feeders[0].mineralCapacity >= 0.5) {
        if (feeders[1].mineralAmount / feeders[1].mineralCapacity >= 0.5) {
          creep.memory.labs = 'empty'
        }
      }
    }

    const carrying = Object.keys(creep.carry)
    if (carrying.length > 3) {
      creep.memory.labs = 'empty'
      return
    }

    const individualMax = creep.carryCapacity / 2
    let reactionPrimaryAvailable = creep.room.storage.store[reaction[0]]
    if (creep.carry[reaction[0]]) {
      reactionPrimaryAvailable += creep.carry[reaction[0]]
    }
    let reactionSecondaryAvailable = creep.room.storage.store[reaction[1]]
    if (creep.carry[reaction[1]]) {
      reactionSecondaryAvailable += creep.carry[reaction[1]]
    }

    let primaryTargetAmount = Math.min(individualMax, reactionPrimaryAvailable, reactionSecondaryAvailable)
    if (feeders[0].mineralAmount / feeders[0].mineralCapacity >= 0.5) {
      primaryTargetAmount = 0
    }

    let secondaryTargetAmount = Math.min(individualMax, reactionPrimaryAvailable, reactionSecondaryAvailable)
    if (feeders[1].mineralAmount / feeders[1].mineralCapacity >= 0.5) {
      secondaryTargetAmount = 0
    }

    if (primaryTargetAmount <= 0 && secondaryTargetAmount <= 0) {
      creep.memory.labs = 'empty'
      return
    }

    if (creep.carry[carrying[0]] > primaryTargetAmount || creep.carry[carrying[1]] > secondaryTargetAmount) {
      creep.memory.labs = 'empty'
      return
    }

    if (creep.memory.filling) {
      if (creep.carry[reaction[0]] && feeders[0].canFill()) {
        if (creep.pos.isNearTo(feeders[0])) {
          creep.transfer(feeders[0], reaction[0])
        } else {
          creep.travelTo(feeders[0], {'ignoreCore': true})
        }
      } else if (creep.carry[reaction[1]] && feeders[1].canFill()) {
        if (creep.pos.isNearTo(feeders[1])) {
          creep.transfer(feeders[1], reaction[1])
        } else {
          creep.travelTo(feeders[1], {'ignoreCore': true})
        }
      } else {
        delete creep.memory.filling
        creep.memory.labs = 'empty'
      }
    } else {
      if (!creep.pos.isNearTo(creep.room.storage)) {
        this.goHome(creep)
        return
      }

      if (creep.carryCapacity === _.sum(creep.carry)) {
        creep.memory.filling = true
        return
      }

      if (!creep.carry[reaction[0]] || creep.carry[reaction[0]] < primaryTargetAmount) {
        const amount = creep.carry[reaction[0]] ? primaryTargetAmount - creep.carry[reaction[0]] : primaryTargetAmount
        creep.withdraw(creep.room.storage, reaction[0], Math.min(amount, creep.carryCapacity - _.sum(creep.carry)))
      } else if (!creep.carry[reaction[1]] || creep.carry[reaction[1]] < secondaryTargetAmount) {
        const amount = creep.carry[reaction[1]] ? secondaryTargetAmount - creep.carry[reaction[1]] : secondaryTargetAmount
        creep.withdraw(creep.room.storage, reaction[1], Math.min(amount, creep.carryCapacity - _.sum(creep.carry)))
      } else {
        creep.memory.filling = true
      }
    }
  }

  emptyLabs (creep) {
    if (creep.carryCapacity - _.sum(creep.carry) <= 0) {
      delete creep.memory.labs
      return
    }
    const lab = this.getLabToEmpty(creep)
    if (!lab) {
      delete creep.memory.labs
      return
    }
    if (creep.pos.isNearTo(lab)) {
      creep.withdraw(lab, lab.mineralType)
    } else {
      creep.travelTo(lab, {'ignoreCore': true})
    }
  }

  getLabToEmpty (creep) {
    const feeders = creep.room.getFeederLabs()
    const reaction = creep.room.getActiveReaction()

    // If one feeder doesn't have the right mineral and the other is empty then empty the first.
    if (feeders[0].mineralAmount) {
      if (feeders[1].mineralAmount < LAB_REACTION_AMOUNT && feeders[0].mineralType !== reaction[0]) {
        return feeders[0]
      }
    }
    if (feeders[1].mineralAmount) {
      if (feeders[0].mineralAmount < LAB_REACTION_AMOUNT && feeders[1].mineralType !== reaction[1]) {
        return feeders[1]
      }
    }

    // If feeders can not produce a reaction start emptying them.
    // Once one is empty the above code will finish the other.
    if (feeders[0].mineralAmount > 0 && feeders[1].mineralAmount > 0) {
      if (!REACTIONS[feeders[0].mineralType][feeders[1].mineralType]) {
        return feeders[0]
      }
    }

    // Empty vats that don't have a boost that will work with the feeders, or that are filling up.
    const vats = creep.room.getVatLabs()
    let currentProduct = false
    if (feeders[0].mineralAmount > 0 && feeders[1].mineralAmount > 0) {
      currentProduct = REACTIONS[feeders[0].mineralType][feeders[1].mineralType]
    }
    const desiredProduct = REACTIONS[reaction[0]][reaction[1]]
    let target = false
    let amount = 150
    for (const vat of vats) {
      if (!vat.mineralType) {
        continue
      }
      if ((!currentProduct || vat.mineralType !== currentProduct) && vat.mineralType !== desiredProduct) {
        return vat
      }
      if (vat.mineralAmount > amount) {
        amount = vat.mineralAmount
        target = vat
      }
    }
    return target
  }

  emptyEnergy (creep) {
    // fill terminal with energy
    if (creep.room.terminal && creep.room.terminal.store[RESOURCE_ENERGY] < TERMINAL_ENERGY) {
      if (creep.pos.isNearTo(creep.room.terminal)) {
        const need = TERMINAL_ENERGY - creep.room.terminal.store[RESOURCE_ENERGY]
        const amount = need > creep.carry[RESOURCE_ENERGY] ? creep.carry[RESOURCE_ENERGY] : need
        creep.transfer(creep.room.terminal, RESOURCE_ENERGY, amount)
      } else {
        this.goHome(creep)
      }
      return
    }

    if (creep.room.structures[STRUCTURE_NUKER] && creep.room.isEconomyCapable('FILL_NUKER')) {
      const nuker = creep.room.structures[STRUCTURE_NUKER][0]
      if (nuker.energy < nuker.energyCapacity) {
        this.dumpEnergyToStructure(creep, nuker)
        return
      }
    }

    if (creep.room.structures[STRUCTURE_POWER_SPAWN] && creep.room.isEconomyCapable('FILL_POWER_SPAWN')) {
      const powerspawn = creep.room.structures[STRUCTURE_POWER_SPAWN][0]
      if (powerspawn.energy < powerspawn.energyCapacity) {
        this.dumpEnergyToStructure(creep, powerspawn)
        return
      }
    }

    // fill storage with energy
    this.dumpEnergyToStructure(creep, creep.room.storage)
  }

  dumpEnergyToStructure (creep, structure) {
    if (creep.pos.isNearTo(structure)) {
      creep.transfer(structure, RESOURCE_ENERGY)
    } else {
      creep.travelTo(structure, {'ignoreCore': true})
    }
  }

  emptyResources (creep) {
    // Must be near storage to empty creep.
    if (!creep.pos.isNearTo(creep.room.storage)) {
      this.goHome(creep)
      return
    }

    const resources = _.filter(Object.keys(creep.carry), a => a !== RESOURCE_ENERGY)
    if (resources.length < 1) {
      return false
    }
    const resource = resources[0]

    // If there's no other option just put it all in storage.
    if (!creep.room.terminal) {
      creep.transfer(creep.room.storage, resource)
      return true
    }

    // Intermediate boosts should stay in room.
    const resourceType = Mineral.getResourceType(resource)
    if (resourceType === 'tier1' || resourceType === 'tier2') {
      creep.transfer(creep.room.storage, resource)
      return true
    }

    // Put needed resources into storage and excess into terminal.
    const currentNeed = creep.room.storage.getResourceNeed(resource)
    if (currentNeed > 0) {
      const amount = creep.carry[resource] < currentNeed ? creep.carry[resource] : currentNeed
      creep.transfer(creep.room.storage, resource, amount)
    } else {
      if (creep.pos.isNearTo(creep.room.terminal)) {
        creep.transfer(creep.room.terminal, resource)
      } else {
        this.goHome(creep)
      }
    }
    return true
  }

  goHome (creep) {
    return creep.travelTo(creep.room.getFactotumHome(), {'ignoreCore': true})
  }
}

module.exports = Factotum
<|endoftext|>


<commit_before>'use strict';

const lov = require( '../lib' );

const schema = {

    first: lov.string().trim().min( 1 ).max( 60 ),

    last: lov.string().trim().min( 1 ).max( 60 ).required(),

    dob: lov.date().format( 'YYYY-MM-DD' ).required(),

    favNumber: lov.number().min( 0 ).max( 150 ).required(),

    numbers: lov.array().items( lov.number() ),

    address: lov.object().keys( {

        street1: lov.string().trim().required(),

        street2: lov.string()
    })
};

let data = {

    first: '  Joe  ',

    last: 'Smith',

    dob: '1984-09-04',

    favNumber: '44',

    numbers: [ '3', 2, 24 ],

    address: {

        street1: '  1 Yonge Street'
    }
}

try {

    console.log( data );

    lov.validate( data, schema );

    console.log( data );
}
catch( err ) {

    console.log( err );
    console.log( err.cause );
}
<commit_msg>updated<commit_after>'use strict';

const lov = require( '../lib' );

const schema = {

    first: lov.string().trim().min( 1 ).max( 60 ),

    last: lov.string().trim().min( 1 ).max( 60 ).required(),

    dob: lov.date().format( 'YYYY-MM-DD' ).required(),

    favNumber: lov.number().min( 0 ).max( 150 ).required(),

    numbers: lov.array().items( lov.number() ),

    address: lov.object().keys( {

        street1: lov.string().trim().required(),

        street2: lov.string()
    })
};

let data = {

    first: '  Joe  ',

    last: 'Smith',

    dob: '1984-09-04',

    favNumber: '44',

    numbers: [ '3', 2, 24 ],

    address: {

        street1: '  1 Yonge Street'
    }
}

try {

    console.log( 'original data:' );
    console.log( data );

    let result = lov.validate( data, schema );

    console.log( 'validated:' );
    console.log( result.value );
}
catch( err ) {

    console.log( err );
    console.log( err.cause );
}
<|endoftext|>


<commit_before>/**
 * @module Lyria
 * @submodule Scene
 */
define('lyria/scene/director', ['root', 'mixer', 'jquery', 'eventmap', 'lyria/scene', 'lyria/viewport'], function(root, mixer, $, EventMap, Scene, Viewport) {'use strict';

  /**
   * The scene director is the manager for all scenes
   *
   */
  return (function() {

    /**
     * The scene director constructor
     * Attaches a scene director to a container, the parent is optional
     *
     * @class Director
     * @constructor
     *
     * @param {Object} container
     * @param {Object} parent
     */
    function SceneDirector(container, parent) {
      mixer(SceneDirector.prototype, new EventMap());

      if ( container instanceof Viewport) {
        this.viewport = container;
      } else {
        this.viewport = new Viewport(container, {parent: parent});
      }

      /**
       * All scenes
       *
       * @property sceneList
       * @type {Object}
       */
      this.sceneList = {};

      /**
       * The current scene
       *
       * @property currentScene
       * @type {Scene}
       */
      this.currentScene = null;

      /**
       * Define events for scene director
       *
       */
      this.on('render', function() {
        if (this.currentScene) {
          this.currentScene.trigger('render');
        }
      });

      this.on('update', function(dt) {
        if (this.currentScene) {
          this.currentScene.trigger('update', dt);
        }
      });
    }

    // Properties
    SceneDirector.prototype.sceneClassName = 'scene';

    // Methods

    /**
     * Adds a scene to the scene director
     *
     * @method add
     * @param {Object} scene
     * @param {Object} options
     */
    SceneDirector.prototype.add = function(scene, options) {

      // Shorthand to add all scenes to the scene director
      if (scene === '*' && this.scenes) {
        scene = Object.keys(this.scenes);
      }

      // Allow array as scenes
      if (Array.isArray(scene)) {
        for (var i = 0, j = scene.length; i < j; i++) {
          this.add(scene[i], options);
        }
      }

      if (!( scene instanceof Scene)) {
        if (this.scenes && !$.isEmptyObject(this.scenes)) {
          scene = this.scenes[scene];
        } else {
          // TODO: Don't throw a string. Throw an error
          throw 'No valid scene found.';
        }
      }

      scene.parent = this;

      // Update reference to the game itself
      if (this.parent != null) {
        scene.game = this.parent;
      }

      this.sceneList[scene.name] = scene;

      if (this.viewport.$element) {
        if ($('#' + scene.name).length === 0) {
          this.viewport.$element.prepend($(root.document.createElement('div')).attr('id', scene.name).attr('class', SceneDirector.prototype.sceneClassName));

          if (!scene.isAsync) {
            scene.trigger('added');
          }

        }
      }

      return this;
    };

    /**
     * Shows a specified scene
     *
     * @method show
     * @param {String} scene name of scene
     * @param {Object} options
     * @param {Function} callback
     */
    SceneDirector.prototype.show = function(sceneName, options, callback) {
      // More than one scene visible at the same time
      if ($('.' + SceneDirector.prototype.sceneClassName + ':visible')) {
        $('.' + SceneDirector.prototype.sceneClassName).hide();
      }

      if (this.currentScene) {
        if (this.currentScene.transition && this.currentScene.length) {
          $('#' + this.currentScene).hide(this.currentScene.transition.length, function() {
            $('.' + SceneDirector.prototype.sceneClassName).hide();
          });
        } else {
          $('.' + SceneDirector.prototype.sceneClassName).hide();
        }

        this.currentScene.trigger('deactivate', options);
      }

      var self = this;

      self.currentScene = this.sceneList[sceneName];

      if (self.currentScene.transition && self.currentScene.transition.length) {
        $('#' + sceneName).show(self.currentScene.transition.length);
      } else {
        $('#' + sceneName).show();
      }
      this.trigger('scene:change', sceneName);
      self.currentScene.trigger('active', options);

      if (callback) {
        callback(sceneName);
      }
    };

    /**
     * Refreshes a scene
     *
     * @method refresh
     * @param {String} scene
     */
    SceneDirector.prototype.refresh = function(scene) {
      var sceneObj = (scene) ? this.sceneList[scene] : this.currentScene;

      // Re-compile scene template
      sceneObj.refresh();
    };

    return SceneDirector;

  })();
});
<commit_msg>Added default scene property to scene director<commit_after>/**
 * @module Lyria
 * @submodule Scene
 */
define('lyria/scene/director', ['root', 'mixer', 'jquery', 'eventmap', 'lyria/scene', 'lyria/viewport'], function(root, mixer, $, EventMap, Scene, Viewport) {'use strict';

  /**
   * The scene director is the manager for all scenes
   *
   */
  return (function() {

    /**
     * The scene director constructor
     * Attaches a scene director to a container, the parent is optional
     *
     * @class Director
     * @constructor
     *
     * @param {Object} container
     * @param {Object} parent
     */
    function SceneDirector(container, parent) {
      mixer(SceneDirector.prototype, new EventMap());

      if ( container instanceof Viewport) {
        this.viewport = container;
      } else {
        this.viewport = new Viewport(container, {parent: parent});
      }

      /**
       * All scenes
       *
       * @property sceneList
       * @type {Object}
       */
      this.sceneList = {};

      /**
       * The current scene
       *
       * @property currentScene
       * @type {Scene}
       */
      this.currentScene = null;

      /**
       * The default scene
       *
       * @property defaultScene
       * @type {String}
       */
      this.defaultScene = null;

      /**
       * Define events for scene director
       *
       */
      this.on('render', function() {
        if (this.currentScene) {
          this.currentScene.trigger('render');
        }
      });

      this.on('update', function(dt) {
        if (this.currentScene) {
          this.currentScene.trigger('update', dt);
        }
      });
    }

    // Properties
    SceneDirector.prototype.sceneClassName = 'scene';

    // Methods

    /**
     * Adds a scene to the scene director
     *
     * @method add
     * @param {Object} scene
     * @param {Object} options
     */
    SceneDirector.prototype.add = function(scene, options) {

      // Shorthand to add all scenes to the scene director
      if (scene === '*' && this.scenes) {
        scene = Object.keys(this.scenes);
      }

      // Allow array as scenes
      if (Array.isArray(scene)) {
        for (var i = 0, j = scene.length; i < j; i++) {
          this.add(scene[i], options);
        }
      }

      if (!( scene instanceof Scene)) {
        if (this.scenes && !$.isEmptyObject(this.scenes)) {
          scene = this.scenes[scene];
        } else {
          // TODO: Don't throw a string. Throw an error
          throw 'No valid scene found.';
        }
      }

      scene.parent = this;

      // Update reference to the game itself
      if (this.parent != null) {
        scene.game = this.parent;
      }

      this.sceneList[scene.name] = scene;

      if (this.viewport.$element) {
        if ($('#' + scene.name).length === 0) {
          this.viewport.$element.prepend($(root.document.createElement('div')).attr('id', scene.name).attr('class', SceneDirector.prototype.sceneClassName));

          if (!scene.isAsync) {
            scene.trigger('added');
          }

        }
      }

      return this;
    };

    /**
     * Shows a specified scene
     *
     * @method show
     * @param {String} scene name of scene
     * @param {Object} options
     * @param {Function} callback
     */
    SceneDirector.prototype.show = function(sceneName, options, callback) {
      // More than one scene visible at the same time
      if ($('.' + SceneDirector.prototype.sceneClassName + ':visible')) {
        $('.' + SceneDirector.prototype.sceneClassName).hide();
      }

      if (this.currentScene) {
        if (this.currentScene.transition && this.currentScene.length) {
          $('#' + this.currentScene).hide(this.currentScene.transition.length, function() {
            $('.' + SceneDirector.prototype.sceneClassName).hide();
          });
        } else {
          $('.' + SceneDirector.prototype.sceneClassName).hide();
        }

        this.currentScene.trigger('deactivate', options);
      }

      var self = this;

      self.currentScene = this.sceneList[sceneName];

      if (self.currentScene.transition && self.currentScene.transition.length) {
        $('#' + sceneName).show(self.currentScene.transition.length);
      } else {
        $('#' + sceneName).show();
      }
      this.trigger('scene:change', sceneName);
      self.currentScene.trigger('active', options);

      if (callback) {
        callback(sceneName);
      }
    };

    /**
     * Refreshes a scene
     *
     * @method refresh
     * @param {String} scene
     */
    SceneDirector.prototype.refresh = function(scene) {
      var sceneObj = (scene) ? this.sceneList[scene] : this.currentScene;

      // Re-compile scene template
      sceneObj.refresh();
    };

    return SceneDirector;

  })();
});
<|endoftext|>


<commit_before>(function () {
  'use strict';

  require.config({
    // # Paths
    paths: {
      // ## Requirejs plugins
      text: '../../bower_components/requirejs-text/text',
      hbs: '../../bower_components/require-handlebars-plugin/hbs',
      cs: '../../bower_components/require-cs/cs',

      // ## Core Libraries
      jquery: '../../bower_components/jquery/dist/jquery',
      underscore: '../../bower_components/lodash/dist/lodash',
      backbone: '../../bower_components/backbone/backbone',
      'hbs/handlebars': '../../bower_components/require-handlebars-plugin/hbs/handlebars',

      // ## Backbone plugins
      'backbone-associations': '../../bower_components/backbone-associations/backbone-associations',

      // ## MathJax
      mathjax: 'http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=MML_HTMLorMML',

      // Use Minified Aloha ( `r.js -o build/aloha/build-profile-with-oer.js` )
      // because loading files in a different requirejs context is a royal pain
      aloha: '../../bower_components/aloha-editor/target/build-profile-with-oer/rjs-output/lib/aloha',
      // Override location of jquery-ui and use our own. Because
      // jquery-ui and bootstrap conflict in a few cases (buttons,
      // tooltip) our copy has those removed.
      jqueryui: '../../bower_components/aloha-editor/oerpub/js/jquery-ui-1.9.0.custom-aloha',

      // ## UI Libraries and Helpers
      tooltip: 'helpers/backbone/views/attached/tooltip/tooltip',
      popover: 'helpers/backbone/views/attached/popover/popover',
      // Boostrap Plugins
      bootstrapAffix: '../../bower_components/bootstrap/js/affix',
      bootstrapAlert: '../../bower_components/bootstrap/js/alert',
      bootstrapButton: '../../bower_components/bootstrap/js/button',
      bootstrapCarousel: '../../bower_components/bootstrap/js/carousel',
      bootstrapCollapse: '../../bower_components/bootstrap/js/collapse',
      bootstrapDropdown: '../../bower_components/bootstrap/js/dropdown',
      bootstrapModal: '../../bower_components/bootstrap/js/modal',
      bootstrapPopover: '../../bower_components/bootstrap/js/popover',
      bootstrapScrollspy: '../../bower_components/bootstrap/js/scrollspy',
      bootstrapTab: '../../bower_components/bootstrap/js/tab',
      bootstrapTooltip: '../../bower_components/bootstrap/js/tooltip',
      bootstrapTransition: '../../bower_components/bootstrap/js/transition',

      // # Select2 multiselect widget
      select2: '../../bower_components/select2/select2',

      // ## CoffeeScript Compiler
      'coffee-script': '../../bower_components/coffee-script/index'
    },

    // # Packages
    packages: [{
      name: 'css',
      location: '../../bower_components/require-css',
      main: 'css'
    }, {
      name: 'less',
      location: '../../bower_components/require-less',
      main: 'less'
    }],

    // # Shims
    shim: {
      // ## Aloha
      aloha: {
        // To disable MathJax comment out the `mathjax` entry in `deps` below.
        deps: ['jquery', 'jqueryui', 'mathjax', 'cs!configs/aloha', 'bootstrapModal', 'bootstrapPopover',
          'css!../../bower_components/aloha-editor/target/build-profile-with-oer/rjs-output/lib/aloha'
        ],
        exports: 'Aloha',
        init: function () {
          return window.Aloha;
        }
      },

      // ## MathJax
      mathjax: {
        exports: 'MathJax',
        init: function () {
          // This config is copied from
          // `../../bower_components/aloha-editor/cnx/mathjax-config.coffee`
          //
          // It configures the TeX and AsciiMath inputs and the MML output
          // mostly for the Math editor.
          //
          // MathMenu and Zoom may not be needed but the `noErrors` is useful
          // for previewing as you type.
          window.MathJax.Hub.Config({
            jax: [
              'input/MathML',
              'input/TeX',
              'input/AsciiMath',
              'output/NativeMML',
              'output/HTML-CSS'
            ],
            extensions: [
              'asciimath2jax.js',
              'tex2jax.js',
              'mml2jax.js',
              'MathMenu.js',
              'MathZoom.js'
            ],
            tex2jax: {
              inlineMath: [
                ['[TEX_START]', '[TEX_END]'],
                ['\\(', '\\)']
              ]
            },
            TeX: {
              extensions: [
                'AMSmath.js',
                'AMSsymbols.js',
                'noErrors.js',
                'noUndefined.js'
              ],
              noErrors: {
                disabled: true
              }
            },
            AsciiMath: {
              noErrors: {
                disabled: true
              }
            }
          });

          return window.MathJax;
        }
      },

      // ## UI Libraries
      // # Bootstrap Plugins
      bootstrapAffix: ['jquery'],
      bootstrapAlert: ['jquery'],
      bootstrapButton: ['jquery'],
      bootstrapCarousel: ['jquery'],
      bootstrapCollapse: ['jquery', 'bootstrapTransition'],
      bootstrapDropdown: ['jquery'],
      bootstrapModal: ['jquery'],
      bootstrapPopover: ['jquery', 'bootstrapTooltip'],
      bootstrapScrollspy: ['jquery'],
      bootstrapTab: ['jquery'],
      bootstrapTooltip: ['jquery'],
      bootstrapTransition: ['jquery'],

      // Select2
      select2: {
        deps: ['jquery', 'css!../../bower_components/select2/select2'],
        exports: 'Select2'
      }
    },

    // Handlebars Requirejs Plugin Configuration
    // Used when loading templates `'hbs!...'`.
    hbs: {
      templateExtension: 'html',
      helperPathCallback: function (name) {
        return 'cs!helpers/handlebars/' + name;
      }
    }
  });

})();
<commit_msg>Add complete compile command for aloha<commit_after>(function () {
  'use strict';

  require.config({
    // # Paths
    paths: {
      // ## Requirejs plugins
      text: '../../bower_components/requirejs-text/text',
      hbs: '../../bower_components/require-handlebars-plugin/hbs',
      cs: '../../bower_components/require-cs/cs',

      // ## Core Libraries
      jquery: '../../bower_components/jquery/dist/jquery',
      underscore: '../../bower_components/lodash/dist/lodash',
      backbone: '../../bower_components/backbone/backbone',
      'hbs/handlebars': '../../bower_components/require-handlebars-plugin/hbs/handlebars',

      // ## Backbone plugins
      'backbone-associations': '../../bower_components/backbone-associations/backbone-associations',

      // ## MathJax
      mathjax: 'http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=MML_HTMLorMML',

      // Use Minified Aloha ( `r.js -o bower_components/aloha-editor/build/aloha/build-profile-with-oer.js` )
      // because loading files in a different requirejs context is a royal pain
      aloha: '../../bower_components/aloha-editor/target/build-profile-with-oer/rjs-output/lib/aloha',
      // Override location of jquery-ui and use our own. Because
      // jquery-ui and bootstrap conflict in a few cases (buttons,
      // tooltip) our copy has those removed.
      jqueryui: '../../bower_components/aloha-editor/oerpub/js/jquery-ui-1.9.0.custom-aloha',

      // ## UI Libraries and Helpers
      tooltip: 'helpers/backbone/views/attached/tooltip/tooltip',
      popover: 'helpers/backbone/views/attached/popover/popover',
      // Boostrap Plugins
      bootstrapAffix: '../../bower_components/bootstrap/js/affix',
      bootstrapAlert: '../../bower_components/bootstrap/js/alert',
      bootstrapButton: '../../bower_components/bootstrap/js/button',
      bootstrapCarousel: '../../bower_components/bootstrap/js/carousel',
      bootstrapCollapse: '../../bower_components/bootstrap/js/collapse',
      bootstrapDropdown: '../../bower_components/bootstrap/js/dropdown',
      bootstrapModal: '../../bower_components/bootstrap/js/modal',
      bootstrapPopover: '../../bower_components/bootstrap/js/popover',
      bootstrapScrollspy: '../../bower_components/bootstrap/js/scrollspy',
      bootstrapTab: '../../bower_components/bootstrap/js/tab',
      bootstrapTooltip: '../../bower_components/bootstrap/js/tooltip',
      bootstrapTransition: '../../bower_components/bootstrap/js/transition',

      // # Select2 multiselect widget
      select2: '../../bower_components/select2/select2',

      // ## CoffeeScript Compiler
      'coffee-script': '../../bower_components/coffee-script/index'
    },

    // # Packages
    packages: [{
      name: 'css',
      location: '../../bower_components/require-css',
      main: 'css'
    }, {
      name: 'less',
      location: '../../bower_components/require-less',
      main: 'less'
    }],

    // # Shims
    shim: {
      // ## Aloha
      aloha: {
        // To disable MathJax comment out the `mathjax` entry in `deps` below.
        deps: ['jquery', 'jqueryui', 'mathjax', 'cs!configs/aloha', 'bootstrapModal', 'bootstrapPopover',
          'css!../../bower_components/aloha-editor/target/build-profile-with-oer/rjs-output/lib/aloha'
        ],
        exports: 'Aloha',
        init: function () {
          return window.Aloha;
        }
      },

      // ## MathJax
      mathjax: {
        exports: 'MathJax',
        init: function () {
          // This config is copied from
          // `../../bower_components/aloha-editor/cnx/mathjax-config.coffee`
          //
          // It configures the TeX and AsciiMath inputs and the MML output
          // mostly for the Math editor.
          //
          // MathMenu and Zoom may not be needed but the `noErrors` is useful
          // for previewing as you type.
          window.MathJax.Hub.Config({
            jax: [
              'input/MathML',
              'input/TeX',
              'input/AsciiMath',
              'output/NativeMML',
              'output/HTML-CSS'
            ],
            extensions: [
              'asciimath2jax.js',
              'tex2jax.js',
              'mml2jax.js',
              'MathMenu.js',
              'MathZoom.js'
            ],
            tex2jax: {
              inlineMath: [
                ['[TEX_START]', '[TEX_END]'],
                ['\\(', '\\)']
              ]
            },
            TeX: {
              extensions: [
                'AMSmath.js',
                'AMSsymbols.js',
                'noErrors.js',
                'noUndefined.js'
              ],
              noErrors: {
                disabled: true
              }
            },
            AsciiMath: {
              noErrors: {
                disabled: true
              }
            }
          });

          return window.MathJax;
        }
      },

      // ## UI Libraries
      // # Bootstrap Plugins
      bootstrapAffix: ['jquery'],
      bootstrapAlert: ['jquery'],
      bootstrapButton: ['jquery'],
      bootstrapCarousel: ['jquery'],
      bootstrapCollapse: ['jquery', 'bootstrapTransition'],
      bootstrapDropdown: ['jquery'],
      bootstrapModal: ['jquery'],
      bootstrapPopover: ['jquery', 'bootstrapTooltip'],
      bootstrapScrollspy: ['jquery'],
      bootstrapTab: ['jquery'],
      bootstrapTooltip: ['jquery'],
      bootstrapTransition: ['jquery'],

      // Select2
      select2: {
        deps: ['jquery', 'css!../../bower_components/select2/select2'],
        exports: 'Select2'
      }
    },

    // Handlebars Requirejs Plugin Configuration
    // Used when loading templates `'hbs!...'`.
    hbs: {
      templateExtension: 'html',
      helperPathCallback: function (name) {
        return 'cs!helpers/handlebars/' + name;
      }
    }
  });

})();
<|endoftext|>


<commit_before>$(document).ready(function () {
    loadRecentMovies();
    loadRecentTVshows();
    loadRecentAlbums();
    loadDownloadHistory();
    loadWantedMovies();
    loadNextAired();
});

function loadRecentMovies () {
    if (!$('#movie-carousel').length) return
    $.ajax({
        url: WEBDIR + 'xbmc/GetRecentMovies',
        type: 'get',
        dataType: 'json',
        success: function (data) {
            if (data == null) return;
            $('#movie-carousel').show();
            $.each(data.movies, function (i, movie) {
                var itemDiv = $('
').addClass('item carousel-item');

                if (i == 0) itemDiv.addClass('active');

                itemDiv.attr('style', 'background-image: url("' + WEBDIR + 'xbmc/GetThumb?h=240&w=430&thumb='+encodeURIComponent(movie.fanart)+ '");');

                itemDiv.append($('
').addClass('carousel-caption').click(function() {
                    location.href = 'xbmc/#movies';
                }).hover(function() {
                    var text = $(this).children('p').slideToggle()
                }).append(
                    $('
').html(movie.title + ' (' + movie.year + ')'),
                    $('
').html(
                        'Runtime: ' + parseSec(movie.runtime) + '
' + 'Genre: ' + movie.genre.join(', ') + '
' + movie.plot
                    ).hide()
                ));
                $('#movie-carousel .carousel-inner').append(itemDiv);
            });
        }
    });
}

function loadRecentTVshows () {
    if (!$('#tvshow-carousel').length) return
    $.ajax({
        url: WEBDIR + 'xbmc/GetRecentShows',
        type: 'get',
        dataType: 'json',
        success: function (data) {
            if (data == null) return;
            $('#tvshow-carousel').show();
            $.each(data.episodes, function (i, episode) {
                var itemDiv = $('
').addClass('item carousel-item');

                if (i == 0) itemDiv.addClass('active');

                itemDiv.attr('style', "background-image: url(" + WEBDIR + "xbmc/GetThumb?h=240&w=430&thumb="+encodeURIComponent(episode.fanart)+ ");");

                itemDiv.append($('
').addClass('carousel-caption').click(function() {
                    location.href = 'xbmc/#shows';
                }).hover(function() {
                    var text = $(this).children('p').slideToggle();
                }).append(
                    $('
').html(episode.showtitle + ': ' + episode.label),
                    $('
').html(
                        'Runtime: ' + parseSec(episode.runtime) + '
' + episode.plot
                    ).hide()
                ));

                $('#tvshow-carousel .carousel-inner').append(itemDiv);
            });
        }
    });
}

function loadRecentAlbums () {
    if (!$('#albums-content').length) return
    $.ajax({
        url: WEBDIR + 'xbmc/GetRecentAlbums/4',
        type: 'get',
        dataType: 'json',
        success: function (data) {
            if (data == null) return;
            $('#albums-content').parent().show();
            $.each(data.albums, function (i, album) {
                var imageSrc = WEBDIR + 'js/libs/holder.js/45x45/text:No cover';
                if (album.thumbnail != '') {
                    imageSrc = WEBDIR + 'xbmc/GetThumb?h=45&w=45&thumb='+encodeURIComponent(album.thumbnail);
                }

                // Frodo fix artist is now a list. Use the first.
                if($.isArray(album.artist)) album.artist = album.artist[0]

                var year = '';
                if (album.year != '0') year = ' (' + album.year + ')';

                $('#albums-content').append($('
').addClass('media').append(
                    $('').addClass('media-object pull-left img-rounded').attr('src', imageSrc),
                    $('
').addClass('media-body').append(
                        $('
').addClass('media-heading').html(album.label + year),
                        $('
').text(album.artist)
                    )
                ).click(function(e) {
                    location.href = 'xbmc/#albums';
                }));
            });

            Holder.run();
        }
    });
}

function loadDownloadHistory() {
    if (!$('#downloads_table_body').length) return
    $.ajax({
        url: WEBDIR + 'sabnzbd/GetHistory?limit=5',
        type: 'get',
        dataType: 'json',
        success: function (data) {
            $('#downloads_table_body').html('');
            $.each(data.history.slots, function (i, slot) {
                if (slot.status == 'Failed') {
                    var status = $('').addClass('icon-remove');
                    status.attr('title', slot.fail_message);
                } else {
                    var status = $('').addClass('icon-ok');
                }
                var row = $('
')
                row.append($('').html(slot.name).attr('title', slot.name));
                row.append($('').html(status));
                $('#downloads_table_body').append(row);
            });
        }
    });
}

function loadWantedMovies() {
    if (!$('#wantedmovies_table_body').length) return
    $.ajax({
        url: WEBDIR + 'couchpotato/GetMovieList?limit=5',
        type: 'get',
        dataType: 'json',
        success: function (result) {
            if (result == null) {
                var row = $('
')
                row.append($('').html('No wanted movies found').attr('colspan', '2'));
                $('#wantedmovies_table_body').append(row);
                return false;
            }
            $.each(result.movies, function(i, item) {
                var row = $('
');
                row.append($('').html(item.library.info.original_title));
                row.append($('').addClass('alignright').html(item.library.year));

                $('#wantedmovies_table_body').append(row);
            });
        }
    });
}

function loadNextAired(options) {
    if (!$('#nextaired_table_body').length) return
    $.ajax({
        url: WEBDIR + 'sickbeard/GetNextAired',
        type: 'get',
        dataType: 'json',
        success: function (result) {
            if (result == null || result.data.soon.legth == 0) {
                var row = $('
').append($('').html('No future episodes found'));
                $('#nextaired_table_body').append(row);
                return false;
            }

            var soonaired = result.data.soon;
            var todayaired = result.data.today;
            var nextaired = todayaired.concat(soonaired);

            $.each(nextaired, function (i, tvshow) {
                if (i > 5) return false;
                var name = $('').attr('href', WEBDIR + 'sickbeard/view/' + tvshow.tvdbid).html(tvshow.show_name);
                var row = $('
').append(
                    $('').append(name),
                    $('').html(tvshow.ep_name),
                    $('').html(tvshow.airdate)
                );
                $('#nextaired_table_body').append(row);
            });
        }
    });
}
<commit_msg>Dashboard cleanup<commit_after>$(document).ready(function () {
    loadRecentMovies()
    loadRecentTVshows()
    loadRecentAlbums()
    loadDownloadHistory()
    loadWantedMovies()
    loadNextAired()
})

function loadRecentMovies () {
    if (!$('#movie-carousel').length) return
    $.getJSON(WEBDIR + 'xbmc/GetRecentMovies',function (data) {
        if (data == null) return
        $.each(data.movies, function (i, movie) {
            var itemDiv = $('
').addClass('item carousel-item')

            if (i == 0) itemDiv.addClass('active')

            var src = WEBDIR + 'xbmc/GetThumb?h=240&w=430&thumb='+encodeURIComponent(movie.fanart)
            itemDiv.attr('style', 'background-image: url("' + src + '")')

            itemDiv.append($('
').addClass('carousel-caption').click(function() {
                location.href = 'xbmc/#movies'
            }).hover(function() {
                var text = $(this).children('p').slideToggle()
            }).append(
                $('
').html(movie.title + ' (' + movie.year + ')'),
                $('
').html(
                    'Runtime: ' + parseSec(movie.runtime) + '
' +
                    'Genre: ' + movie.genre.join(', ') + '
' +
                    movie.plot
                ).hide()
            ))
            $('#movie-carousel .carousel-inner').append(itemDiv)
        })
        $('#movie-carousel').show()
    })
}
function loadRecentTVshows () {
    if (!$('#tvshow-carousel').length) return
    $.getJSON(WEBDIR + 'xbmc/GetRecentShows', function (data) {
        if (data == null) return
        $.each(data.episodes, function (i, episode) {
            var itemDiv = $('
').addClass('item carousel-item')

            if (i == 0) itemDiv.addClass('active')

            var src = WEBDIR + "xbmc/GetThumb?h=240&w=430&thumb="+encodeURIComponent(episode.fanart)
            itemDiv.attr('style', "background-image: url(" + src + ")")

            itemDiv.append($('
').addClass('carousel-caption').click(function() {
                location.href = 'xbmc/#shows'
            }).hover(function() {
                var text = $(this).children('p').slideToggle()
            }).append(
                $('
').html(episode.showtitle + ': ' + episode.label),
                $('
').html(
                    'Runtime: ' + parseSec(episode.runtime) + '
' + episode.plot
                ).hide()
            ))
            $('#tvshow-carousel .carousel-inner').append(itemDiv)
        })
        $('#tvshow-carousel').show()
    })
}
function loadRecentAlbums () {
    if (!$('#albums-content').length) return
    $.getJSON(WEBDIR + 'xbmc/GetRecentAlbums/4', function (data) {
        if (data == null) return
        $.each(data.albums, function (i, album) {
            var imageSrc = WEBDIR + 'js/libs/holder.js/45x45/text:No cover'
            if (album.thumbnail != '') {
                imageSrc = WEBDIR + 'xbmc/GetThumb?h=45&w=45&thumb='+encodeURIComponent(album.thumbnail)
            }

            var label = album.label
            if (album.year != '0') label += ' (' + album.year + ')'

            $('#albums-content').append(
                $('
').addClass('media').append(
                    $('').addClass('media-object pull-left img-rounded').attr('src', imageSrc),
                    $('
').addClass('media-body').append(
                        $('
').addClass('media-heading').html(label),
                        $('
').text(album.artist[0])
                    )
                ).click(function(e) {
                    location.href = 'xbmc/#albums'
                })
            )
        })
        Holder.run()
        $('#albums-content').parent().show()
    })
}
function loadDownloadHistory() {
    if (!$('#downloads_table_body').length) return
    $.getJSON(WEBDIR + 'sabnzbd/GetHistory?limit=5', function (data) {
        $.each(data.history.slots, function (i, slot) {
            var status = $('').addClass('icon-ok')
            if (slot.status == 'Failed') {
                status.removeClass().addClass('icon-remove').attr('title', slot.fail_message)
            }
            $('#downloads_table_body').append(
                $('
').append(
                    $('').html(slot.name).attr('title', slot.name),
                    $('').html(status)
                )
            )
        })
    })
}
function loadWantedMovies() {
    if (!$('#wantedmovies_table_body').length) return
    $.getJSON(WEBDIR + 'couchpotato/GetMovieList?limit=5', function (result) {
        if (result == null) {
            $('#wantedmovies_table_body').append(
                $('
').append($('').html('No wanted movies found').attr('colspan', '2'))
            )
            return
        }
        $.each(result.movies, function(i, item) {
            $('#wantedmovies_table_body').append(
                $('
').append(
                    $('').html(item.library.info.original_title),
                    $('').addClass('alignright').html(item.library.year)
                )
            )
        })
    })
}
function loadNextAired(options) {
    if (!$('#nextaired_table_body').length) return
    $.getJSON(WEBDIR + 'sickbeard/GetNextAired', function (result) {
        if (result == null || result.data.soon.legth == 0) {
            $('#nextaired_table_body').append(
                $('
').append($('').html('No future episodes found'))
            )
            return
        }
        var soonaired = result.data.soon
        var todayaired = result.data.today
        var nextaired = todayaired.concat(soonaired)
        $.each(nextaired, function (i, tvshow) {
            if (i >= 5) return
            var name = $('').attr('href', 'sickbeard/view/' + tvshow.tvdbid).html(tvshow.show_name)
            $('#nextaired_table_body').append(
                $('
').append(
                    $('').append(name),
                    $('').html(tvshow.ep_name),
                    $('').html(tvshow.airdate)
                )
            )
        })
    })
}<|endoftext|>


<commit_before>(function () {
  'use strict';

  require.config({
    // # Paths
    paths: {
      // ## Requirejs plugins
      text: '../../bower_components/requirejs-text/text',
      hbs: '../../bower_components/require-handlebars-plugin/hbs',
      cs: '../../bower_components/require-cs/cs',

      // ## Core Libraries
      jquery: '../../bower_components/jquery/jquery',
      underscore: '../../bower_components/lodash/dist/lodash',
      backbone: '../../bower_components/backbone/backbone',
      'hbs/handlebars': '../../bower_components/require-handlebars-plugin/hbs/handlebars',

      // ## Backbone plugins
      'backbone-associations': '../../bower_components/backbone-associations/backbone-associations',

      // ## MathJax
      mathjax: 'http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=MML_HTMLorMML',

      // ## UI Libraries and Helpers
      tooltip: 'helpers/backbone/views/attached/tooltip/tooltip',
      popover: 'helpers/backbone/views/attached/popover/popover',
      // Boostrap Plugins
      bootstrapAffix: '../../bower_components/bootstrap/js/affix',
      bootstrapAlert: '../../bower_components/bootstrap/js/alert',
      bootstrapButton: '../../bower_components/bootstrap/js/button',
      bootstrapCarousel: '../../bower_components/bootstrap/js/carousel',
      bootstrapCollapse: '../../bower_components/bootstrap/js/collapse',
      bootstrapDropdown: '../../bower_components/bootstrap/js/dropdown',
      bootstrapModal: '../../bower_components/bootstrap/js/modal',
      bootstrapPopover: '../../bower_components/bootstrap/js/popover',
      bootstrapScrollspy: '../../bower_components/bootstrap/js/scrollspy',
      bootstrapTab: '../../bower_components/bootstrap/js/tab',
      bootstrapTooltip: '../../bower_components/bootstrap/js/tooltip',
      bootstrapTransition: '../../bower_components/bootstrap/js/transition',

      // ## CoffeeScript Compiler
      'coffee-script': '../../bower_components/coffee-script/index'
    },

    // # Packages
    packages: [{
      name: 'less',
      location: '../../bower_components/require-less',
      main: 'less'
    }],

    // # Shims
    shim: {
      // ## Core Libraries
      backbone: {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      },

      // ## Backbone plugins
      'backbone-associations': {
        deps: ['backbone']
      },

      // ## MathJax
      mathjax: {
        exports: 'MathJax'
      },

      // ## UI Libraries
      // # Bootstrap Plugins
      bootstrapAffix: ['jquery'],
      bootstrapAlert: ['jquery'],
      bootstrapButton: ['jquery'],
      bootstrapCarousel: ['jquery'],
      bootstrapCollapse: ['jquery', 'bootstrapTransition'],
      bootstrapDropdown: ['jquery'],
      bootstrapModal: ['jquery'],
      bootstrapPopover: ['jquery', 'bootstrapTooltip'],
      bootstrapScrollspy: ['jquery'],
      bootstrapTab: ['jquery'],
      bootstrapTooltip: ['jquery'],
      bootstrapTransition: ['jquery']
    },

    // Handlebars Requirejs Plugin Configuration
    // Used when loading templates `'hbs!...'`.
    hbs: {
      templateExtension: 'html',
      helperPathCallback: function (name) {
        return 'cs!helpers/handlebars/' + name;
      }
    }
  });

})();
<commit_msg>Remove shims for backbone and backbone-associations<commit_after>(function () {
  'use strict';

  require.config({
    // # Paths
    paths: {
      // ## Requirejs plugins
      text: '../../bower_components/requirejs-text/text',
      hbs: '../../bower_components/require-handlebars-plugin/hbs',
      cs: '../../bower_components/require-cs/cs',

      // ## Core Libraries
      jquery: '../../bower_components/jquery/jquery',
      underscore: '../../bower_components/lodash/dist/lodash',
      backbone: '../../bower_components/backbone/backbone',
      'hbs/handlebars': '../../bower_components/require-handlebars-plugin/hbs/handlebars',

      // ## Backbone plugins
      'backbone-associations': '../../bower_components/backbone-associations/backbone-associations',

      // ## MathJax
      mathjax: 'http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=MML_HTMLorMML',

      // ## UI Libraries and Helpers
      tooltip: 'helpers/backbone/views/attached/tooltip/tooltip',
      popover: 'helpers/backbone/views/attached/popover/popover',
      // Boostrap Plugins
      bootstrapAffix: '../../bower_components/bootstrap/js/affix',
      bootstrapAlert: '../../bower_components/bootstrap/js/alert',
      bootstrapButton: '../../bower_components/bootstrap/js/button',
      bootstrapCarousel: '../../bower_components/bootstrap/js/carousel',
      bootstrapCollapse: '../../bower_components/bootstrap/js/collapse',
      bootstrapDropdown: '../../bower_components/bootstrap/js/dropdown',
      bootstrapModal: '../../bower_components/bootstrap/js/modal',
      bootstrapPopover: '../../bower_components/bootstrap/js/popover',
      bootstrapScrollspy: '../../bower_components/bootstrap/js/scrollspy',
      bootstrapTab: '../../bower_components/bootstrap/js/tab',
      bootstrapTooltip: '../../bower_components/bootstrap/js/tooltip',
      bootstrapTransition: '../../bower_components/bootstrap/js/transition',

      // ## CoffeeScript Compiler
      'coffee-script': '../../bower_components/coffee-script/index'
    },

    // # Packages
    packages: [{
      name: 'less',
      location: '../../bower_components/require-less',
      main: 'less'
    }],

    // # Shims
    shim: {
      // ## MathJax
      mathjax: {
        exports: 'MathJax'
      },

      // ## UI Libraries
      // # Bootstrap Plugins
      bootstrapAffix: ['jquery'],
      bootstrapAlert: ['jquery'],
      bootstrapButton: ['jquery'],
      bootstrapCarousel: ['jquery'],
      bootstrapCollapse: ['jquery', 'bootstrapTransition'],
      bootstrapDropdown: ['jquery'],
      bootstrapModal: ['jquery'],
      bootstrapPopover: ['jquery', 'bootstrapTooltip'],
      bootstrapScrollspy: ['jquery'],
      bootstrapTab: ['jquery'],
      bootstrapTooltip: ['jquery'],
      bootstrapTransition: ['jquery']
    },

    // Handlebars Requirejs Plugin Configuration
    // Used when loading templates `'hbs!...'`.
    hbs: {
      templateExtension: 'html',
      helperPathCallback: function (name) {
        return 'cs!helpers/handlebars/' + name;
      }
    }
  });

})();
<|endoftext|>