<commit_before>#!/usr/bin/env node
'use strict';

var program = require('commander');
var fs = require('fs');
var os = require('os');
var xml2js = require('xml2js');

const child_process = require('child_process');
var wd = '/Users/hiro/Desktop/ios-triage';

program
  .version('0.1.0')
  .description('Incident response tool for iPhone or iPad')
  .option('-o, --output [directory]', 'Set output directory')
  .option('-v, --verbose', 'Display verbose output')

program
  .command('collect')
  .description('Collect IR artifacts from iPhone or iPad')
  .action(collectArtifacts);

program
  .command('process')
  .description('Process collected artifacts')
  .action(processArtifacts);

program
  .command('report')
  .description('Generate iOS IR report')
  .action(generateReport);

program.parse(process.argv);

// if program was called with no arguments, show help.
if (program.args.length === 0) program.help();

function collectArtifacts () {
  // let's first get the UDID...if we can't do this successfully, we have a problem
  console.log("starting data run at " + new Date().getTime());
  getUDID(function getDeviceData(error, udid) {
    if (error) { return console.error(error); }

    // no error getting UDID so time to fetch data

    // start and keep device syslog running until extraction done
    // in future, maybe allow user to set amount of time to run to track overnight
    var deviceSyslog = getDeviceSyslog(udid);
    var deviceInfo = getDeviceInfo(udid);
    var installedApps = getInstalledApps(udid);
    var provisioningProfiles = listProvisioningProfiles(udid);
    // idevicebackup2 backup --full . (make backup dir)
    // idevicecrashreport -e -k .
  });
};

function getUDID (callback) {
  var retval = '';
  var udid = child_process.spawn('idevice_id', ['-l']);

  udid.stdout.on('data', (chunk) => {
    // FIXME: if idevice_id fires the data event more than once the this would overwrite
    // retval which is likley problematic
    retval = chunk;
  });

  udid.on('close', code => {
    /*
    Unfortunately idevice_id returns a 0 in all situations I checked
    which differs from how ideviceinfo works. If you call idevice_id with
    an invalid parameter or no device is attached, it still returns a 0.
    I'm going to keep this return code != 0 in here for now in case they fix
    in the future. The work around is to test the length for retval and if it is
    41, then we have a UDID returned!
    */
    if (retval.length === 41) {
      // found a valid udid so return null error and uuid value
      // first let's make this a string and trim any newlines
      var udid_str = String.fromCharCode.apply(null, retval);
      console.log("Authorized iDevice found, UDID: " + udid_str.trim());
      callback(null, udid_str.trim());
    } else {
      // encountered some sort of error. If 0 len then no device attached, otherwise something else
      if (retval.length === 0) {
        callback(new Error("No authorized iDevice found. Plug in and authorize a device first."));
      } else {
        callback(new Error(retval));
      };
    };
  });
};

function getDeviceSyslog(udid) {

  var file_name = 'syslog.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call idevicesyslog binary
  var idevicesyslog = child_process.execFile('idevicesyslog', [], { timeout: 10000 });

  // on data events, write chunks to file
  idevicesyslog.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  idevicesyslog.stdout.on('end', () => {
    file.end();
    console.log('iOS Device syslog saved to: ' + file.path);
  });

  // should this event be on exit or on close?
  // per documentation, not all Streams emit a close event
  // https://nodejs.org/api/stream.html#stream_event_close
  idevicesyslog.on('close', function(code) {
    if (code != 0) {
      console.error('idevicesyslog returned error code ' + code);
    }
  });
  return(idevicesyslog);
};

function getDeviceInfo(udid) {

  var file_name = 'ideviceinfo.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceinfo binary
  var ideviceinfo = child_process.spawn('ideviceinfo', []);

  // on data events, write chunks to file
  ideviceinfo.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceinfo.stdout.on('end', () => {
    file.end();
    console.log('iOS Device info saved to: ' + file.path);
  });

  // should this event be on exit or on close?
  // per documentation, not all Streams emit a close event
  // https://nodejs.org/api/stream.html#stream_event_close
  ideviceinfo.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceinfo returned error code ' + code);
    }
  });
};

function getInstalledApps(udid) {

  var file_name = 'installed-apps.xml';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceinstaller binary
  var ideviceinstaller = child_process.spawn('ideviceinstaller', ['--list-apps', '-o','list_all', '-o', 'xml']);

  // on data events, write chunks to file
  ideviceinstaller.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceinstaller.stdout.on('end', () => {
    file.end();
    console.log('iOS Device installed apps saved to: ' + file.path);
  });

  ideviceinstaller.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceinstaller returned error code ' + code);
    }
  });
};

function listProvisioningProfiles(udid) {

  var file_name = 'provisioning-profiles.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceprovision binary
  var ideviceprovision = child_process.spawn('ideviceprovision', ['list']);

  // on data events, write chunks to file
  ideviceprovision.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceprovision.stdout.on('end', () => {
    file.end();
    console.log('Installed provisioning profiles saved to: ' + file.path);
  });

  ideviceprovision.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceprovision returned error code ' + code);
    }
  });
};

function processArtifacts () {
  console.log("process artifacts");
}

function generateReport () {
  //console.log("generate report");
  var parser = new xml2js.Parser();
  fs.readFile(wd + '/artifacts/installed-apps.xml', function(err, data) {
    parser.parseString(data, function (err, result) {
      console.dir(JSON.stringify(result));
    });
  });

}

<commit_msg>working on setting dynamic working directory<commit_after>#!/usr/bin/env node
'use strict';

var program = require('commander');
var fs = require('fs');
var os = require('os');
var xml2js = require('xml2js');

const child_process = require('child_process');
var wd = '/Users/hiro/Desktop/ios-triage';

program
  .version('0.1.0')
  .description('Incident response tool for iPhone or iPad')
  .option('-o, --output [directory]', 'Set output directory')
  .option('-v, --verbose', 'Display verbose output')

program
  .command('collect')
  .description('Collect IR artifacts from iPhone or iPad')
  .action(collectArtifacts);

program
  .command('process')
  .description('Process collected artifacts')
  .action(processArtifacts);

program
  .command('report')
  .description('Generate iOS IR report')
  .action(generateReport);

program.parse(process.argv);

// if program was called with no arguments, show help.
if (program.args.length === 0) program.help();

function setWorkingDirectory (useOutputDir, udid) {
  wd = ""
  if (userOutputDir) {
    wd = useOutputDir;
  } else {
    wd = __dirname;
  }
  wd = wd + "/" + udid;
  console.log("working directory set to " + wd);
}

function collectArtifacts () {
  // let's first get the UDID...if we can't do this successfully, we have a problem
  console.log("starting data run in " + __dirname + " at " + new Date().getTime());
  getUDID(function getDeviceData(error, udid) {
    if (error) { return console.error(error); }

    // no error getting UDID so time to fetch data
    wd = setWorkingDirectory(program.output, udid);

    // start and keep device syslog running until extraction done
    // in future, maybe allow user to set amount of time to run to track overnight
    var deviceSyslog = getDeviceSyslog(udid);
    var deviceInfo = getDeviceInfo(udid);
    var installedApps = getInstalledApps(udid);
    var provisioningProfiles = listProvisioningProfiles(udid);
    // idevicebackup2 backup --full . (make backup dir)
    // idevicecrashreport -e -k .
  });
};

function getUDID (callback) {
  var retval = '';
  var udid = child_process.spawn('idevice_id', ['-l']);

  udid.stdout.on('data', (chunk) => {
    // FIXME: if idevice_id fires the data event more than once the this would overwrite
    // retval which is likley problematic
    retval = chunk;
  });

  udid.on('close', code => {
    /*
    Unfortunately idevice_id returns a 0 in all situations I checked
    which differs from how ideviceinfo works. If you call idevice_id with
    an invalid parameter or no device is attached, it still returns a 0.
    I'm going to keep this return code != 0 in here for now in case they fix
    in the future. The work around is to test the length for retval and if it is
    41, then we have a UDID returned!
    */
    if (retval.length === 41) {
      // found a valid udid so return null error and uuid value
      // first let's make this a string and trim any newlines
      var udid_str = String.fromCharCode.apply(null, retval);
      console.log("Authorized iDevice found, UDID: " + udid_str.trim());
      callback(null, udid_str.trim());
    } else {
      // encountered some sort of error. If 0 len then no device attached, otherwise something else
      if (retval.length === 0) {
        callback(new Error("No authorized iDevice found. Plug in and authorize a device first."));
      } else {
        callback(new Error(retval));
      };
    };
  });
};

function getDeviceSyslog(udid) {

  var file_name = 'syslog.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call idevicesyslog binary
  var idevicesyslog = child_process.execFile('idevicesyslog', [], { timeout: 10000 });

  // on data events, write chunks to file
  idevicesyslog.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  idevicesyslog.stdout.on('end', () => {
    file.end();
    console.log('iOS Device syslog saved to: ' + file.path);
  });

  // should this event be on exit or on close?
  // per documentation, not all Streams emit a close event
  // https://nodejs.org/api/stream.html#stream_event_close
  idevicesyslog.on('close', function(code) {
    if (code != 0) {
      console.error('idevicesyslog returned error code ' + code);
    }
  });
  return(idevicesyslog);
};

function getDeviceInfo(udid) {

  var file_name = 'ideviceinfo.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceinfo binary
  var ideviceinfo = child_process.spawn('ideviceinfo', []);

  // on data events, write chunks to file
  ideviceinfo.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceinfo.stdout.on('end', () => {
    file.end();
    console.log('iOS Device info saved to: ' + file.path);
  });

  // should this event be on exit or on close?
  // per documentation, not all Streams emit a close event
  // https://nodejs.org/api/stream.html#stream_event_close
  ideviceinfo.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceinfo returned error code ' + code);
    }
  });
};

function getInstalledApps(udid) {

  var file_name = 'installed-apps.xml';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceinstaller binary
  var ideviceinstaller = child_process.spawn('ideviceinstaller', ['--list-apps', '-o','list_all', '-o', 'xml']);

  // on data events, write chunks to file
  ideviceinstaller.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceinstaller.stdout.on('end', () => {
    file.end();
    console.log('iOS Device installed apps saved to: ' + file.path);
  });

  ideviceinstaller.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceinstaller returned error code ' + code);
    }
  });
};

function listProvisioningProfiles(udid) {

  var file_name = 'provisioning-profiles.txt';
  var file = fs.createWriteStream(wd + '/' + udid + '/artifacts/' + file_name);

  // call ideviceprovision binary
  var ideviceprovision = child_process.spawn('ideviceprovision', ['list']);

  // on data events, write chunks to file
  ideviceprovision.stdout.on('data', (chunk) => {
    file.write(chunk);
  });

  // after Stream ends, close the file, inform user of saved file
  ideviceprovision.stdout.on('end', () => {
    file.end();
    console.log('Installed provisioning profiles saved to: ' + file.path);
  });

  ideviceprovision.on('close', function(code) {
    if (code != 0) {
      console.error('ideviceprovision returned error code ' + code);
    }
  });
};

function processArtifacts () {
  console.log("process artifacts");
}

function generateReport () {
  //console.log("generate report");
  var parser = new xml2js.Parser();
  fs.readFile(wd + '/artifacts/installed-apps.xml', function(err, data) {
    parser.parseString(data, function (err, result) {
      console.dir(JSON.stringify(result));
    });
  });

}

<|endoftext|>


<commit_before>import Future from 'fibers/future'
import Fiber from 'fibers'

const SYNC_COMMANDS = ['domain', '_events', '_maxListeners', 'setMaxListeners', 'emit',
    'addListener', 'on', 'once', 'removeListener', 'removeAllListeners', 'listeners']
const NOOP = function () {}

let commandIsRunning = false

/**
 * helper method to execute a row of hooks with certain parameters
 * @param  {Function|Function[]} hooks  list of hooks
 * @param  {Object[]} args  list of parameter for hook functions
 * @return {Promise}  promise that gets resolved once all hooks finished running
 */
let executeHooksWithArgs = (hooks, args) => {
    /**
     * make sure hooks are an array of functions
     */
    if (typeof hooks === 'function') {
        hooks = [hooks]
    }

    /**
     * make sure args is an array since we are calling apply
     */
    if (!Array.isArray(args)) {
        args = [args]
    }

    hooks = hooks.map((hook) => new Promise((resolve) => {
        let _commandIsRunning = commandIsRunning
        try {
            /**
             * after command hooks require additional Fiber environment
             */
            return Fiber(() => {
                commandIsRunning = true
                resolve(hook.apply(null, args))
                commandIsRunning = _commandIsRunning
            }).run()
        } catch (e) {
            // here could be your error message
        }

        resolve()
    }))

    return Promise.all(hooks)
}

/**
 * wraps a function into a Fiber ready context to enable sync execution and hooks
 * @param  {Function}   fn             function to be executed
 * @param  {String}     commandName    name of that function
 * @param  {Function[]} beforeCommand  method to be executed before calling the actual function
 * @param  {Function[]} afterCommand   method to be executed after calling the actual function
 * @return {Function}   actual wrapped function
 */
let wrapCommand = function (fn, commandName, beforeCommand, afterCommand) {
    return function (...commandArgs) {
        let future = new Future()

        /**
         * don't execute [before/after]Command hook if a command was executed
         * in these hooks
         */
        if (commandIsRunning) {
            fn.apply(this, commandArgs).then(future.return.bind(future), future.throw.bind(future))
            return future.wait()
        }

        commandIsRunning = true
        let commandResult, commandError
        new Promise((r) => r(beforeCommand(commandName, commandArgs)))
            .then(() => {
                return fn.apply(this, commandArgs)
            })
            .then(
                (result) => {
                    commandResult = result
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, result])
                },
                (e) => {
                    commandError = e
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, null, e])
                }
            )
            .then(() => {
                commandIsRunning = false

                if (commandError) {
                    return future.throw(commandError)
                }
                return future.return(commandResult)
            })

        return future.wait()
    }
}

/**
 * wraps all WebdriverIO commands
 * @param  {Object}     instance       WebdriverIO client instance (browser)
 * @param  {Function[]} beforeCommand  before command hook
 * @param  {Function[]} afterCommand   after command hook
 */
let wrapCommands = function (instance, beforeCommand, afterCommand) {
    Object.keys(Object.getPrototypeOf(instance)).forEach((commandName) => {
        if (SYNC_COMMANDS.indexOf(commandName) > -1) {
            return
        }

        let origFn = instance[commandName]
        instance[commandName] = wrapCommand(origFn, commandName, beforeCommand, afterCommand)
    })

    /**
     * Adding a command within fiber context doesn't require a special routine
     * since everything runs sync. There is no need to promisify the command.
     */
    instance.addCommand = function (fnName, fn, forceOverwrite) {
        let commandGroup = instance
        let namespace

        if (typeof fn === 'string') {
            namespace = arguments[0]
            fnName = arguments[1]
            fn = arguments[2]
            forceOverwrite = arguments[3]

            switch (typeof commandGroup[namespace]) {
            case 'function':
                throw new Error(`Command namespace "${namespace}" is used internally, and can't be overwritten!`)
            case 'undefined':
                commandGroup[namespace] = {}
                break
            }

            commandGroup = commandGroup[namespace]
        }

        if (commandGroup[fnName] && !forceOverwrite) {
            throw new Error(`Command ${fnName} is already defined!`)
        }

        commandGroup[fnName] = wrapCommand(fn, fnName, beforeCommand, afterCommand)
    }
}

let runInFiberContext = function (testInterface, ui, before, after, fnName) {
    let origFn = global[fnName]
    let testInterfaceFnName = testInterface[ui][2]

    let runSpec = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                specFn.call(this)
                done()
            }).run()
        })
    }

    let runHook = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                before()
                specFn.call(this)
                after()
                done()
            }).run()
        })
    }

    global[fnName] = function (...specArguments) {
        let specFn = typeof specArguments[0] === 'function' ? specArguments.shift() : specArguments.pop()
        let specTitle = specArguments[0]

        /**
         * if specFn is undefined we are dealing with a pending function
         */
        if (fnName === testInterfaceFnName && arguments.length === 1) {
            return origFn(specTitle)
        }

        if (fnName === testInterfaceFnName) {
            return runSpec(specTitle, specFn)
        }

        return runHook(specTitle, specFn)
    }

    if (fnName === testInterfaceFnName) {
        global[fnName].skip = origFn.skip
        global[fnName].only = origFn.only
    }
}

let runHook = function (hookFn, cb = NOOP) {
    return new Promise((resolve, reject) => {
        Fiber(() => {
            try {
                hookFn()
                cb()
                resolve()
            } catch (e) {
                reject(e)
            }
        }).run()
    })
}

/**
 * wraps a function that returns a promise to be used within Fiber
 * @param  {Function} origFn  actual function to be executed (needs to return a Promise)
 * @return {Object}           Fiber wait object
 */
let wrapFn = function (origFn) {
    return function (...commandArgs) {
        let future = new Future()
        let result = origFn.apply(this, commandArgs)

        result.then(future.return.bind(future), future.throw.bind(future))
        return future.wait()
    }
}

export { wrapCommand, wrapCommands, runInFiberContext, runHook, wrapFn }
<commit_msg>no need for spec title for hooks<commit_after>import Future from 'fibers/future'
import Fiber from 'fibers'

const SYNC_COMMANDS = ['domain', '_events', '_maxListeners', 'setMaxListeners', 'emit',
    'addListener', 'on', 'once', 'removeListener', 'removeAllListeners', 'listeners']
const NOOP = function () {}

let commandIsRunning = false

/**
 * helper method to execute a row of hooks with certain parameters
 * @param  {Function|Function[]} hooks  list of hooks
 * @param  {Object[]} args  list of parameter for hook functions
 * @return {Promise}  promise that gets resolved once all hooks finished running
 */
let executeHooksWithArgs = (hooks, args) => {
    /**
     * make sure hooks are an array of functions
     */
    if (typeof hooks === 'function') {
        hooks = [hooks]
    }

    /**
     * make sure args is an array since we are calling apply
     */
    if (!Array.isArray(args)) {
        args = [args]
    }

    hooks = hooks.map((hook) => new Promise((resolve) => {
        let _commandIsRunning = commandIsRunning
        try {
            /**
             * after command hooks require additional Fiber environment
             */
            return Fiber(() => {
                commandIsRunning = true
                resolve(hook.apply(null, args))
                commandIsRunning = _commandIsRunning
            }).run()
        } catch (e) {
            // here could be your error message
        }

        resolve()
    }))

    return Promise.all(hooks)
}

/**
 * wraps a function into a Fiber ready context to enable sync execution and hooks
 * @param  {Function}   fn             function to be executed
 * @param  {String}     commandName    name of that function
 * @param  {Function[]} beforeCommand  method to be executed before calling the actual function
 * @param  {Function[]} afterCommand   method to be executed after calling the actual function
 * @return {Function}   actual wrapped function
 */
let wrapCommand = function (fn, commandName, beforeCommand, afterCommand) {
    return function (...commandArgs) {
        let future = new Future()

        /**
         * don't execute [before/after]Command hook if a command was executed
         * in these hooks
         */
        if (commandIsRunning) {
            fn.apply(this, commandArgs).then(future.return.bind(future), future.throw.bind(future))
            return future.wait()
        }

        commandIsRunning = true
        let commandResult, commandError
        new Promise((r) => r(beforeCommand(commandName, commandArgs)))
            .then(() => {
                return fn.apply(this, commandArgs)
            })
            .then(
                (result) => {
                    commandResult = result
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, result])
                },
                (e) => {
                    commandError = e
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, null, e])
                }
            )
            .then(() => {
                commandIsRunning = false

                if (commandError) {
                    return future.throw(commandError)
                }
                return future.return(commandResult)
            })

        return future.wait()
    }
}

/**
 * wraps all WebdriverIO commands
 * @param  {Object}     instance       WebdriverIO client instance (browser)
 * @param  {Function[]} beforeCommand  before command hook
 * @param  {Function[]} afterCommand   after command hook
 */
let wrapCommands = function (instance, beforeCommand, afterCommand) {
    Object.keys(Object.getPrototypeOf(instance)).forEach((commandName) => {
        if (SYNC_COMMANDS.indexOf(commandName) > -1) {
            return
        }

        let origFn = instance[commandName]
        instance[commandName] = wrapCommand(origFn, commandName, beforeCommand, afterCommand)
    })

    /**
     * Adding a command within fiber context doesn't require a special routine
     * since everything runs sync. There is no need to promisify the command.
     */
    instance.addCommand = function (fnName, fn, forceOverwrite) {
        let commandGroup = instance
        let namespace

        if (typeof fn === 'string') {
            namespace = arguments[0]
            fnName = arguments[1]
            fn = arguments[2]
            forceOverwrite = arguments[3]

            switch (typeof commandGroup[namespace]) {
            case 'function':
                throw new Error(`Command namespace "${namespace}" is used internally, and can't be overwritten!`)
            case 'undefined':
                commandGroup[namespace] = {}
                break
            }

            commandGroup = commandGroup[namespace]
        }

        if (commandGroup[fnName] && !forceOverwrite) {
            throw new Error(`Command ${fnName} is already defined!`)
        }

        commandGroup[fnName] = wrapCommand(fn, fnName, beforeCommand, afterCommand)
    }
}

let runInFiberContext = function (testInterface, ui, before, after, fnName) {
    let origFn = global[fnName]
    let testInterfaceFnName = testInterface[ui][2]

    let runSpec = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                specFn.call(this)
                done()
            }).run()
        })
    }

    let runHook = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                before()
                specFn.call(this)
                after()
                done()
            }).run()
        })
    }

    global[fnName] = function (...specArguments) {
        let specFn = typeof specArguments[0] === 'function' ? specArguments.shift() : specArguments.pop()
        let specTitle = specArguments[0]

        /**
         * if specFn is undefined we are dealing with a pending function
         */
        if (fnName === testInterfaceFnName && arguments.length === 1) {
            return origFn(specTitle)
        }

        if (fnName === testInterfaceFnName) {
            return runSpec(specTitle, specFn)
        }

        return runHook(specFn)
    }

    if (fnName === testInterfaceFnName) {
        global[fnName].skip = origFn.skip
        global[fnName].only = origFn.only
    }
}

let runHook = function (hookFn, cb = NOOP) {
    return new Promise((resolve, reject) => {
        Fiber(() => {
            try {
                hookFn()
                cb()
                resolve()
            } catch (e) {
                reject(e)
            }
        }).run()
    })
}

/**
 * wraps a function that returns a promise to be used within Fiber
 * @param  {Function} origFn  actual function to be executed (needs to return a Promise)
 * @return {Object}           Fiber wait object
 */
let wrapFn = function (origFn) {
    return function (...commandArgs) {
        let future = new Future()
        let result = origFn.apply(this, commandArgs)

        result.then(future.return.bind(future), future.throw.bind(future))
        return future.wait()
    }
}

export { wrapCommand, wrapCommands, runInFiberContext, runHook, wrapFn }
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

let fs = require('fs');

module.exports = {
  name: 'ember-cli-ifa',

  isDevelopingAddon: function() {
    return false;
  },

  postBuild: function (build) {
    let indexFilePath = build.directory + '/index.html';
    let indexFileBuffer = fs.readFileSync(indexFilePath);
    let indexFile = indexFileBuffer.toString('utf8');

    let files = fs.readdirSync(build.directory + '/assets');
    let totalFiles = files.length;

    let assetFileName = null;
    for (let i = 0; i < totalFiles; i++) {
      if (files[i].match(/^assetMap-/i)) {
        assetFileName = files[i];
        break;
      }
    }

    if (assetFileName) {
      fs.writeFileSync(
        indexFilePath,
        indexFile.replace(/__asset_map_placeholder__/, '/assets/' + assetFileName)
      );
    }
  },

  contentFor(type, config) {
    if (type === 'head-footer' && config.ifa && config.ifa.enabled) {
      return '<script>var __assetMapFilename__ = "__asset_map_placeholder__";</script>';
    }
  }
};
<commit_msg>Remove - from assetMap file name<commit_after>/* jshint node: true */
'use strict';

let fs = require('fs');

module.exports = {
  name: 'ember-cli-ifa',

  isDevelopingAddon: function() {
    return false;
  },

  postBuild: function (build) {
    let indexFilePath = build.directory + '/index.html';
    let indexFileBuffer = fs.readFileSync(indexFilePath);
    let indexFile = indexFileBuffer.toString('utf8');

    let files = fs.readdirSync(build.directory + '/assets');
    let totalFiles = files.length;

    let assetFileName = null;
    for (let i = 0; i < totalFiles; i++) {
      if (files[i].match(/^assetMap/i)) {
        assetFileName = files[i];
        break;
      }
    }

    if (assetFileName) {
      fs.writeFileSync(
        indexFilePath,
        indexFile.replace(/__asset_map_placeholder__/, '/assets/' + assetFileName)
      );
    }
  },

  contentFor(type, config) {
    if (type === 'head-footer' && config.ifa && config.ifa.enabled) {
      return '<script>var __assetMapFilename__ = "__asset_map_placeholder__";</script>';
    }
  }
};
<|endoftext|>


<commit_before>const EventEmitter = require("events");

if (!document) {
    throw Error("electron-tabs module must be called in renderer process");
}

// Inject styles
(function () {
    const styles = `
        webview {
            visibility: hidden;
            width: 0px;
            height: 0px;
        }
        webview.visible {
            visibility: visible;
            width: 100%;
            height: 100%;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
        }
    `;
    let styleTag = document.createElement("style");
    styleTag.innerHTML = styles;
    document.getElementsByTagName("head")[0].appendChild(styleTag);
})();

class TabGroup extends EventEmitter {
    constructor (args = {}) {
        super();
        let options = this.options = {
            tabContainerSelector: args.tabContainerSelector || ".etabs-tabs",
            buttonsContainerSelector: args.buttonsContainerSelector || ".etabs-buttons",
            viewContainerSelector: args.viewContainerSelector || ".etabs-views",
            tabClass: args.tabClass || "etabs-tab",
            viewClass: args.viewClass || "etabs-view",
            closeButtonText: args.closeButtonText || "✖",
            newTab: args.newTab,
            newTabButtonText: args.newTabButtonText || "＋",
            ready: args.ready
        };
        this.tabContainer = document.querySelector(options.tabContainerSelector);
        this.viewContainer = document.querySelector(options.viewContainerSelector);
        this.tabs = [];
        this.newTabId = 0;
        TabGroupPrivate.initNewTabButton.bind(this)();
        if (typeof this.options.ready === "function") {
            this.options.ready(this);
        }
    }

    addTab (args = this.options.newTab) {
        if (typeof args === "function") {
            args = args(this);
        }
        let id = this.newTabId;
        this.newTabId++;
        let tab = new Tab(this, id, args);
        this.tabs.push(tab);
        // Don't call tab.activate() before a tab is referenced in this.tabs
        if (args.active === true) {
            tab.activate();
        }
        this.emit("tab-added", tab, this);
        return tab;
    }

    getTab (id, idIsPosition) {
        if (idIsPosition !== true) {
            return this.getTabById(id);
        } else {
            return this.getTabByPosition(id);
        }
    }

    getTabById (id) {
        for (let i in this.tabs) {
            if (this.tabs[i].id === id) {
                return this.tabs[i];
            }
        }
        return null;
    }

    getTabByPosition (position) {
        let fromRight = position < 0;
        for (let i in this.tabs) {
            if (this.tabs[i].getPosition(fromRight) === position) {
                return this.tabs[i];
            }
        }
        return null;
    }

    getTabByRelPosition (position) {
        position = this.getActiveTab().getPosition() + position;
        if (position <= 0) {
            return null;
        }
        return this.getTabByPosition(position);
    }

    getNextTab () {
        return this.getTabByRelPosition(1);
    }

    getPreviousTab () {
        return this.getTabByRelPosition(-1);
    }

    getTabs () {
      return this.tabs;
    }

    eachTab (fn) {
      this.tabs.forEach(fn);
      return this;
    }

    getActiveTab () {
        if (this.tabs.length === 0) return null;
        return this.tabs[0];
    }
}

const TabGroupPrivate = {
    initNewTabButton: function () {
        if (!this.options.newTab) return;
        let container = document.querySelector(this.options.buttonsContainerSelector);
        let button = container.appendChild(document.createElement("button"));
        button.classList.add(`${this.options.tabClass}-button-new`);
        button.innerHTML = this.options.newTabButtonText;
        button.addEventListener("click", this.addTab.bind(this, undefined), false);
    },

    removeTab: function (tab, triggerEvent) {
        let id = tab.id;
        for (let i in this.tabs) {
            if (this.tabs[i].id === id) {
                this.tabs.splice(i, 1);
                break;
            }
        }
        if (triggerEvent) {
            this.emit("tab-removed", tab, this);
        }
        return this;
    },

    setActiveTab: function (tab) {
        TabGroupPrivate.removeTab.bind(this)(tab);
        this.tabs.unshift(tab);
        this.emit("tab-active", tab, this);
        return this;
    },

    activateRecentTab: function (tab) {
        if (this.tabs.length > 0) {
            this.tabs[0].activate();
        }
        return this;
    }
};

class Tab extends EventEmitter {
    constructor (tabGroup, id, args) {
        super();
        this.tabGroup = tabGroup;
        this.id = id;
        this.title = args.title;
        this.badge = args.badge;
        this.iconURL = args.iconURL;
        this.icon = args.icon;
        this.closable = args.closable === false ? false : true;
        this.webviewAttributes = args.webviewAttributes || {};
        this.webviewAttributes.src = args.src;
        this.tabElements = {};
        TabPrivate.initTab.bind(this)();
        TabPrivate.initWebview.bind(this)();
        if (args.visible !== false) {
            this.show();
        }
        if (typeof args.ready === "function") {
            args.ready(this);
        }
    }

    setTitle (title) {
        if (this.isClosed) return;
        let span = this.tabElements.title;
        span.innerHTML = title;
        this.title = title;
        this.emit("title-changed", title, this);
        return this;
    }

    getTitle () {
        if (this.isClosed) return;
        return this.title;
    }

    setBadge (badge) {
        if (this.isClosed) return;
        let span = this.tabElements.badge;
        this.badge = badge;

        if (badge) {
            span.innerHTML = badge;
            span.classList.remove('hidden');
        } else {
            span.classList.add('hidden');
        }

        this.emit("badge-changed", badge, this);
    }

    getBadge () {
      if (this.isClosed) return;
      return this.badge;
    }

    setIcon (iconURL, icon) {
        if (this.isClosed) return;
        this.iconURL = iconURL;
        this.icon = icon;
        let span = this.tabElements.icon;
        if (iconURL) {
            span.innerHTML = `<img src="${iconURL}" />`;
            this.emit("icon-changed", iconURL, this);
        } else if (icon) {
            span.innerHTML = `<i class="${icon}"></i>`;
            this.emit("icon-changed", icon, this);
        }

        return this;
    }

    getIcon () {
        if (this.isClosed) return;
        if (this.iconURL) return this.iconURL;
        return this.icon;
    }

    setPosition (newPosition) {
        if (newPosition === 0 || newPosition === undefined) {
            return null;
        }
        let tabContainer = this.tabGroup.tabContainer;
        let tabs = tabContainer.children;
        let oldPosition = this.getPosition() - 1;

        if (newPosition < 0) {
            newPosition += tabContainer.childElementCount;

            if (newPosition < 0) {
                newPosition = 0;
            }
        } else {
            if (newPosition > tabContainer.childElementCount) {
                newPosition = tabContainer.childElementCount;
            }

            // Make 1 be leftmost position
            newPosition--;
        }

        if (newPosition > oldPosition) {
            newPosition++;
        }

        tabContainer.insertBefore(tabs[oldPosition], tabs[newPosition]);

        return this;
    }

    getPosition (fromRight) {
        let position = 0;
        let tab = this.tab;
        while ((tab = tab.previousSibling) != null) position++;

        if (fromRight === true) {
            position -= this.tabGroup.tabContainer.childElementCount;
        }

        if (position >= 0) {
            position++;
        }

        return position;
    }

    activate () {
        if (this.isClosed) return;
        let activeTab = this.tabGroup.getActiveTab();
        if (activeTab) {
            activeTab.tab.classList.remove("active");
            activeTab.webview.classList.remove("visible");
        }
        TabGroupPrivate.setActiveTab.bind(this.tabGroup)(this);
        this.tab.classList.add("active");
        this.webview.classList.add("visible");
        this.webview.focus();
        this.emit("active", this);
        return this;
    }

    show (flag) {
        if (this.isClosed) return;
        if (flag !== false) {
            this.tab.classList.add("visible");
            this.emit("visible", this);
        } else {
            this.tab.classList.remove("visible");
            this.emit("hidden", this);
        }
        return this;
    }

    hide () {
        return this.show(false);
    }

    flash (flag) {
        if (this.isClosed) return;
        if (flag !== false) {
            this.tab.classList.add("flash");
            this.emit("flash", this);
        } else {
            this.tab.classList.remove("flash");
            this.emit("unflash", this);
        }
        return this;
    }

    unflash () {
        return this.flash(false);
    }

    close (force) {
        this.emit("closing", this);
        if (this.isClosed || (!this.closable && !force)) return;
        this.isClosed = true;
        let tabGroup = this.tabGroup;
        tabGroup.tabContainer.removeChild(this.tab);
        tabGroup.viewContainer.removeChild(this.webview);
        let activeTab = this.tabGroup.getActiveTab();
        TabGroupPrivate.removeTab.bind(tabGroup)(this, true);
        this.emit("close", this);

        if (activeTab.id === this.id) {
            TabGroupPrivate.activateRecentTab.bind(tabGroup)();
        }
    }
}

const TabPrivate = {
    initTab: function () {
        let tabClass = this.tabGroup.options.tabClass;

        // Create tab element
        let tab = this.tab = document.createElement("div");
        tab.classList.add(tabClass);
        for (let el of ["icon", "title", "buttons", "badge"]) {
            let span = tab.appendChild(document.createElement("span"));
            span.classList.add(`${tabClass}-${el}`);
            this.tabElements[el] = span;
        }

        this.setTitle(this.title);
        this.setBadge(this.badge);
        this.setIcon(this.iconURL, this.icon);
        TabPrivate.initTabButtons.bind(this)();
        TabPrivate.initTabClickHandler.bind(this)();

        this.tabGroup.tabContainer.appendChild(this.tab);
    },

    initTabButtons: function () {
        let container = this.tabElements.buttons;
        let tabClass = this.tabGroup.options.tabClass;
        if (this.closable) {
            let button = container.appendChild(document.createElement("button"));
            button.classList.add(`${tabClass}-button-close`);
            button.innerHTML = this.tabGroup.options.closeButtonText;
            button.addEventListener("click", this.close.bind(this, false), false);
        }
    },

    initTabClickHandler: function () {
        // Click
        const tabClickHandler = function (e) {
            if (this.isClosed) return;
            if (e.which === 2) {
                this.close();
            }
        };
        this.tab.addEventListener("click", tabClickHandler.bind(this), false);
        // Mouse down
        const tabMouseDownHandler = function (e) {
            if (this.isClosed) return;
            if (e.which === 1) {
                if (e.target.matches("button")) return;
                this.activate();
            }
        };
        this.tab.addEventListener("mousedown", tabMouseDownHandler.bind(this), false);
    },

    initWebview: function () {
        this.webview = document.createElement("webview");

        const tabWebviewDidFinishLoadHandler = function (e) {
            this.emit("webview-ready", this);
        };

        this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);

        this.webview.classList.add(this.tabGroup.options.viewClass);
        if (this.webviewAttributes) {
            let attrs = this.webviewAttributes;
            for (let key in attrs) {
                this.webview.setAttribute(key, attrs[key]);
            }
        }

        this.tabGroup.viewContainer.appendChild(this.webview);
    }
};

module.exports = TabGroup;
<commit_msg>Change tabGroup.getTabById to tabGroup.getTab<commit_after>const EventEmitter = require("events");

if (!document) {
    throw Error("electron-tabs module must be called in renderer process");
}

// Inject styles
(function () {
    const styles = `
        webview {
            visibility: hidden;
            width: 0px;
            height: 0px;
        }
        webview.visible {
            visibility: visible;
            width: 100%;
            height: 100%;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
        }
    `;
    let styleTag = document.createElement("style");
    styleTag.innerHTML = styles;
    document.getElementsByTagName("head")[0].appendChild(styleTag);
})();

class TabGroup extends EventEmitter {
    constructor (args = {}) {
        super();
        let options = this.options = {
            tabContainerSelector: args.tabContainerSelector || ".etabs-tabs",
            buttonsContainerSelector: args.buttonsContainerSelector || ".etabs-buttons",
            viewContainerSelector: args.viewContainerSelector || ".etabs-views",
            tabClass: args.tabClass || "etabs-tab",
            viewClass: args.viewClass || "etabs-view",
            closeButtonText: args.closeButtonText || "✖",
            newTab: args.newTab,
            newTabButtonText: args.newTabButtonText || "＋",
            ready: args.ready
        };
        this.tabContainer = document.querySelector(options.tabContainerSelector);
        this.viewContainer = document.querySelector(options.viewContainerSelector);
        this.tabs = [];
        this.newTabId = 0;
        TabGroupPrivate.initNewTabButton.bind(this)();
        if (typeof this.options.ready === "function") {
            this.options.ready(this);
        }
    }

    addTab (args = this.options.newTab) {
        if (typeof args === "function") {
            args = args(this);
        }
        let id = this.newTabId;
        this.newTabId++;
        let tab = new Tab(this, id, args);
        this.tabs.push(tab);
        // Don't call tab.activate() before a tab is referenced in this.tabs
        if (args.active === true) {
            tab.activate();
        }
        this.emit("tab-added", tab, this);
        return tab;
    }

    getTab (id) {
        for (let i in this.tabs) {
            if (this.tabs[i].id === id) {
                return this.tabs[i];
            }
        }
        return null;
    }

    getTabByPosition (position) {
        let fromRight = position < 0;
        for (let i in this.tabs) {
            if (this.tabs[i].getPosition(fromRight) === position) {
                return this.tabs[i];
            }
        }
        return null;
    }

    getTabByRelPosition (position) {
        position = this.getActiveTab().getPosition() + position;
        if (position <= 0) {
            return null;
        }
        return this.getTabByPosition(position);
    }

    getNextTab () {
        return this.getTabByRelPosition(1);
    }

    getPreviousTab () {
        return this.getTabByRelPosition(-1);
    }

    getTabs () {
      return this.tabs;
    }

    eachTab (fn) {
      this.tabs.forEach(fn);
      return this;
    }

    getActiveTab () {
        if (this.tabs.length === 0) return null;
        return this.tabs[0];
    }
}

const TabGroupPrivate = {
    initNewTabButton: function () {
        if (!this.options.newTab) return;
        let container = document.querySelector(this.options.buttonsContainerSelector);
        let button = container.appendChild(document.createElement("button"));
        button.classList.add(`${this.options.tabClass}-button-new`);
        button.innerHTML = this.options.newTabButtonText;
        button.addEventListener("click", this.addTab.bind(this, undefined), false);
    },

    removeTab: function (tab, triggerEvent) {
        let id = tab.id;
        for (let i in this.tabs) {
            if (this.tabs[i].id === id) {
                this.tabs.splice(i, 1);
                break;
            }
        }
        if (triggerEvent) {
            this.emit("tab-removed", tab, this);
        }
        return this;
    },

    setActiveTab: function (tab) {
        TabGroupPrivate.removeTab.bind(this)(tab);
        this.tabs.unshift(tab);
        this.emit("tab-active", tab, this);
        return this;
    },

    activateRecentTab: function (tab) {
        if (this.tabs.length > 0) {
            this.tabs[0].activate();
        }
        return this;
    }
};

class Tab extends EventEmitter {
    constructor (tabGroup, id, args) {
        super();
        this.tabGroup = tabGroup;
        this.id = id;
        this.title = args.title;
        this.badge = args.badge;
        this.iconURL = args.iconURL;
        this.icon = args.icon;
        this.closable = args.closable === false ? false : true;
        this.webviewAttributes = args.webviewAttributes || {};
        this.webviewAttributes.src = args.src;
        this.tabElements = {};
        TabPrivate.initTab.bind(this)();
        TabPrivate.initWebview.bind(this)();
        if (args.visible !== false) {
            this.show();
        }
        if (typeof args.ready === "function") {
            args.ready(this);
        }
    }

    setTitle (title) {
        if (this.isClosed) return;
        let span = this.tabElements.title;
        span.innerHTML = title;
        this.title = title;
        this.emit("title-changed", title, this);
        return this;
    }

    getTitle () {
        if (this.isClosed) return;
        return this.title;
    }

    setBadge (badge) {
        if (this.isClosed) return;
        let span = this.tabElements.badge;
        this.badge = badge;

        if (badge) {
            span.innerHTML = badge;
            span.classList.remove('hidden');
        } else {
            span.classList.add('hidden');
        }

        this.emit("badge-changed", badge, this);
    }

    getBadge () {
      if (this.isClosed) return;
      return this.badge;
    }

    setIcon (iconURL, icon) {
        if (this.isClosed) return;
        this.iconURL = iconURL;
        this.icon = icon;
        let span = this.tabElements.icon;
        if (iconURL) {
            span.innerHTML = `<img src="${iconURL}" />`;
            this.emit("icon-changed", iconURL, this);
        } else if (icon) {
            span.innerHTML = `<i class="${icon}"></i>`;
            this.emit("icon-changed", icon, this);
        }

        return this;
    }

    getIcon () {
        if (this.isClosed) return;
        if (this.iconURL) return this.iconURL;
        return this.icon;
    }

    setPosition (newPosition) {
        if (newPosition === 0 || newPosition === undefined) {
            return null;
        }
        let tabContainer = this.tabGroup.tabContainer;
        let tabs = tabContainer.children;
        let oldPosition = this.getPosition() - 1;

        if (newPosition < 0) {
            newPosition += tabContainer.childElementCount;

            if (newPosition < 0) {
                newPosition = 0;
            }
        } else {
            if (newPosition > tabContainer.childElementCount) {
                newPosition = tabContainer.childElementCount;
            }

            // Make 1 be leftmost position
            newPosition--;
        }

        if (newPosition > oldPosition) {
            newPosition++;
        }

        tabContainer.insertBefore(tabs[oldPosition], tabs[newPosition]);

        return this;
    }

    getPosition (fromRight) {
        let position = 0;
        let tab = this.tab;
        while ((tab = tab.previousSibling) != null) position++;

        if (fromRight === true) {
            position -= this.tabGroup.tabContainer.childElementCount;
        }

        if (position >= 0) {
            position++;
        }

        return position;
    }

    activate () {
        if (this.isClosed) return;
        let activeTab = this.tabGroup.getActiveTab();
        if (activeTab) {
            activeTab.tab.classList.remove("active");
            activeTab.webview.classList.remove("visible");
        }
        TabGroupPrivate.setActiveTab.bind(this.tabGroup)(this);
        this.tab.classList.add("active");
        this.webview.classList.add("visible");
        this.webview.focus();
        this.emit("active", this);
        return this;
    }

    show (flag) {
        if (this.isClosed) return;
        if (flag !== false) {
            this.tab.classList.add("visible");
            this.emit("visible", this);
        } else {
            this.tab.classList.remove("visible");
            this.emit("hidden", this);
        }
        return this;
    }

    hide () {
        return this.show(false);
    }

    flash (flag) {
        if (this.isClosed) return;
        if (flag !== false) {
            this.tab.classList.add("flash");
            this.emit("flash", this);
        } else {
            this.tab.classList.remove("flash");
            this.emit("unflash", this);
        }
        return this;
    }

    unflash () {
        return this.flash(false);
    }

    close (force) {
        this.emit("closing", this);
        if (this.isClosed || (!this.closable && !force)) return;
        this.isClosed = true;
        let tabGroup = this.tabGroup;
        tabGroup.tabContainer.removeChild(this.tab);
        tabGroup.viewContainer.removeChild(this.webview);
        let activeTab = this.tabGroup.getActiveTab();
        TabGroupPrivate.removeTab.bind(tabGroup)(this, true);
        this.emit("close", this);

        if (activeTab.id === this.id) {
            TabGroupPrivate.activateRecentTab.bind(tabGroup)();
        }
    }
}

const TabPrivate = {
    initTab: function () {
        let tabClass = this.tabGroup.options.tabClass;

        // Create tab element
        let tab = this.tab = document.createElement("div");
        tab.classList.add(tabClass);
        for (let el of ["icon", "title", "buttons", "badge"]) {
            let span = tab.appendChild(document.createElement("span"));
            span.classList.add(`${tabClass}-${el}`);
            this.tabElements[el] = span;
        }

        this.setTitle(this.title);
        this.setBadge(this.badge);
        this.setIcon(this.iconURL, this.icon);
        TabPrivate.initTabButtons.bind(this)();
        TabPrivate.initTabClickHandler.bind(this)();

        this.tabGroup.tabContainer.appendChild(this.tab);
    },

    initTabButtons: function () {
        let container = this.tabElements.buttons;
        let tabClass = this.tabGroup.options.tabClass;
        if (this.closable) {
            let button = container.appendChild(document.createElement("button"));
            button.classList.add(`${tabClass}-button-close`);
            button.innerHTML = this.tabGroup.options.closeButtonText;
            button.addEventListener("click", this.close.bind(this, false), false);
        }
    },

    initTabClickHandler: function () {
        // Click
        const tabClickHandler = function (e) {
            if (this.isClosed) return;
            if (e.which === 2) {
                this.close();
            }
        };
        this.tab.addEventListener("click", tabClickHandler.bind(this), false);
        // Mouse down
        const tabMouseDownHandler = function (e) {
            if (this.isClosed) return;
            if (e.which === 1) {
                if (e.target.matches("button")) return;
                this.activate();
            }
        };
        this.tab.addEventListener("mousedown", tabMouseDownHandler.bind(this), false);
    },

    initWebview: function () {
        this.webview = document.createElement("webview");

        const tabWebviewDidFinishLoadHandler = function (e) {
            this.emit("webview-ready", this);
        };

        this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);

        this.webview.classList.add(this.tabGroup.options.viewClass);
        if (this.webviewAttributes) {
            let attrs = this.webviewAttributes;
            for (let key in attrs) {
                this.webview.setAttribute(key, attrs[key]);
            }
        }

        this.tabGroup.viewContainer.appendChild(this.webview);
    }
};

module.exports = TabGroup;
<|endoftext|>


<commit_before>// Load dotenv first
require('dotenv').config({silent: true});

var Accuser = require('accuser');

var accuser = new Accuser();

var githubAuthToken = {
  "type": "oauth",
  "token": process.env.GITHUB_TOKEN
};

accuser.authenticate(githubAuthToken);

var initializeSemesterRepositories = require('./src/semester');
initializeSemesterRepositories(accuser, 'addressbook-level1');
initializeSemesterRepositories(accuser, 'addressbook-level2');
initializeSemesterRepositories(accuser, 'addressbook-level3');
initializeSemesterRepositories(accuser, 'addressbook-level4');

var intializeSeEduRepositories = require('./src/seedu');
intializeSeEduRepositories(accuser, 'addressbook-level1');
intializeSeEduRepositories(accuser, 'addressbook-level2');
intializeSeEduRepositories(accuser, 'addressbook-level3');
intializeSeEduRepositories(accuser, 'addressbook-level4');

console.log ("Server has started");

accuser
  .run({assignee: "none"});
<commit_msg>added rcs<commit_after>// Load dotenv first
require('dotenv').config({silent: true});

var Accuser = require('accuser');

var accuser = new Accuser();

var githubAuthToken = {
  "type": "oauth",
  "token": process.env.GITHUB_TOKEN
};

accuser.authenticate(githubAuthToken);

var initializeSemesterRepositories = require('./src/semester');
initializeSemesterRepositories(accuser, 'addressbook-level1');
initializeSemesterRepositories(accuser, 'addressbook-level2');
initializeSemesterRepositories(accuser, 'addressbook-level3');
initializeSemesterRepositories(accuser, 'addressbook-level4');

var intializeSeEduRepositories = require('./src/seedu');
intializeSeEduRepositories(accuser, 'rcs');
intializeSeEduRepositories(accuser, 'addressbook-level1');
intializeSeEduRepositories(accuser, 'addressbook-level2');
intializeSeEduRepositories(accuser, 'addressbook-level3');
intializeSeEduRepositories(accuser, 'addressbook-level4');

console.log ("Server has started");

accuser
  .run({assignee: "none"});
<|endoftext|>


<commit_before>exports.core = require('captain-core');

exports.admin = require('captain-admin');

exports = exports.core;

<commit_msg>Fixed exposing core as the default app<commit_after>exports.core = require('captain-core');

exports.admin = require('captain-admin');

exports.PROJECT_ROOT = __dirname;

module.exports = exports.core;
<|endoftext|>


<commit_before>L.TileLayer.OsmTileAccessLogLayer = L.TileLayer.Canvas.extend({
    options: {
        async: true,
        maxZoom:19-8,
        overzoom: 0,
        data: null
    },
    canvasCache: {},
    parserWorker: new Worker('parser.js'),
    numWorkers: navigator.hardwareConcurrency || 1,
    workers: [],
    overzoom: function (overzoom) {
        if (this.options.overzoom === overzoom) return
        this.options.overzoom = overzoom
        this.redraw()
    },
    initialize: function (arrayBuffer, doneCallback) {
        var self = this
        console.time("parse data by worker")
        this.workers = Array.apply(null, new Array(this.numWorkers)).map(function() {return new Worker('worker.js')})
        this.parserWorker.postMessage({numWorkers:this.numWorkers, data:arrayBuffer}, [arrayBuffer])
        this.parserWorker.onmessage = function(e) {
            if (typeof e.data === 'string') {
                var processingDiv = document.getElementById('processing')
                processingDiv.textContent = e.data
                return
            }
            console.timeEnd("parse data by worker")

            self.workers.forEach(function(worker, index) {
                e.data[index].request = 'init'
                worker.postMessage(e.data[index], [e.data[index].x, e.data[index].y, e.data[index].z, e.data[index].count])
                worker.onmessage = tileHandler
            })
            self._map.on('click', function(e) {
                var coords = self._map.project(e.latlng)
                coords.x = Math.floor(coords.x/Math.pow(2,self.options.overzoom))
                coords.y = Math.floor(coords.y/Math.pow(2,self.options.overzoom))
                var worker = self.workers[Math.floor(coords.x/self.options.tileSize) % self.numWorkers]
                worker.postMessage({
                    request: 'query',
                    x: coords.x,
                    y: coords.y,
                    z: self._map.getZoom()+8-self.options.overzoom
                })
                //worker.onmessage(
                map.openPopup(
                    '
Tile '+(self._map.getZoom()+8-self.options.overzoom)+'/'+coords.x+'/'+coords.y+' was accessed '+'? times'+'.
' +
                    '',
                    e.latlng, {
                    minWidth:256
                })
            })
        }
        function tileHandler(e) {
            if (typeof e.data === 'string') {
                var processingDiv = document.getElementById('processing')
                processingDiv.count = (processingDiv.count || 0)+1
                processingDiv.textContent = e.data + ' (' + Math.round(100*processingDiv.count/self.numWorkers) + '%)'
                if (doneCallback && processingDiv.count == self.numWorkers) doneCallback()
            } else if (e.data.answer === 'render') {
                var array = new Uint8Array(e.data.pixels)
                var canvas = self.canvasCache[e.data.tileId]
                if (canvas === undefined) return
                delete self.canvasCache[e.data.tileId]
                var ctx = canvas.getContext('2d')
                var imagedata = ctx.getImageData(0, 0, self.options.tileSize, self.options.tileSize)
                imagedata.data.set(array)
                ctx.putImageData(imagedata, 0, 0)
                self.tileDrawn(canvas)
            } else if (e.data.answer === 'query') {
                document.getElementById('clicked-count').textContent = e.data.result ? e.data.result+'times' : 'less than 10 times or from less than 3 different IP addresses'
            } else {
                throw "Undefined answer returned by worker"
            }
        }
    },
    drawTile: function(canvas, tilePoint, zoom) {
        var tileId=tilePoint.x+":"+tilePoint.y+":"+zoom
        this.canvasCache[tileId]=canvas
        var worker = this.workers[((Math.floor(tilePoint.x/Math.pow(2,this.options.overzoom)) % this.numWorkers) + this.numWorkers) % this.numWorkers]
        worker.postMessage({
            request: 'render',
            tileId: tileId,
            zoom: zoom,
            overzoom: this.options.overzoom,
            tilePoint: tilePoint,
            tileSize: this.options.tileSize
        })
    }
});
L.tileLayer.osmTileAccessLogLayer = function(data, doneCallback) {
    return new L.TileLayer.OsmTileAccessLogLayer(data, doneCallback);
}
<commit_msg>add space between number and "times" in popup<commit_after>L.TileLayer.OsmTileAccessLogLayer = L.TileLayer.Canvas.extend({
    options: {
        async: true,
        maxZoom:19-8,
        overzoom: 0,
        data: null
    },
    canvasCache: {},
    parserWorker: new Worker('parser.js'),
    numWorkers: navigator.hardwareConcurrency || 1,
    workers: [],
    overzoom: function (overzoom) {
        if (this.options.overzoom === overzoom) return
        this.options.overzoom = overzoom
        this.redraw()
    },
    initialize: function (arrayBuffer, doneCallback) {
        var self = this
        console.time("parse data by worker")
        this.workers = Array.apply(null, new Array(this.numWorkers)).map(function() {return new Worker('worker.js')})
        this.parserWorker.postMessage({numWorkers:this.numWorkers, data:arrayBuffer}, [arrayBuffer])
        this.parserWorker.onmessage = function(e) {
            if (typeof e.data === 'string') {
                var processingDiv = document.getElementById('processing')
                processingDiv.textContent = e.data
                return
            }
            console.timeEnd("parse data by worker")

            self.workers.forEach(function(worker, index) {
                e.data[index].request = 'init'
                worker.postMessage(e.data[index], [e.data[index].x, e.data[index].y, e.data[index].z, e.data[index].count])
                worker.onmessage = tileHandler
            })
            self._map.on('click', function(e) {
                var coords = self._map.project(e.latlng)
                coords.x = Math.floor(coords.x/Math.pow(2,self.options.overzoom))
                coords.y = Math.floor(coords.y/Math.pow(2,self.options.overzoom))
                var worker = self.workers[Math.floor(coords.x/self.options.tileSize) % self.numWorkers]
                worker.postMessage({
                    request: 'query',
                    x: coords.x,
                    y: coords.y,
                    z: self._map.getZoom()+8-self.options.overzoom
                })
                //worker.onmessage(
                map.openPopup(
                    '
Tile '+(self._map.getZoom()+8-self.options.overzoom)+'/'+coords.x+'/'+coords.y+' was accessed '+'? times'+'.
' +
                    '',
                    e.latlng, {
                    minWidth:256
                })
            })
        }
        function tileHandler(e) {
            if (typeof e.data === 'string') {
                var processingDiv = document.getElementById('processing')
                processingDiv.count = (processingDiv.count || 0)+1
                processingDiv.textContent = e.data + ' (' + Math.round(100*processingDiv.count/self.numWorkers) + '%)'
                if (doneCallback && processingDiv.count == self.numWorkers) doneCallback()
            } else if (e.data.answer === 'render') {
                var array = new Uint8Array(e.data.pixels)
                var canvas = self.canvasCache[e.data.tileId]
                if (canvas === undefined) return
                delete self.canvasCache[e.data.tileId]
                var ctx = canvas.getContext('2d')
                var imagedata = ctx.getImageData(0, 0, self.options.tileSize, self.options.tileSize)
                imagedata.data.set(array)
                ctx.putImageData(imagedata, 0, 0)
                self.tileDrawn(canvas)
            } else if (e.data.answer === 'query') {
                document.getElementById('clicked-count').textContent = e.data.result ? e.data.result+' times' : 'less than 10 times or from less than 3 different IP addresses'
            } else {
                throw "Undefined answer returned by worker"
            }
        }
    },
    drawTile: function(canvas, tilePoint, zoom) {
        var tileId=tilePoint.x+":"+tilePoint.y+":"+zoom
        this.canvasCache[tileId]=canvas
        var worker = this.workers[((Math.floor(tilePoint.x/Math.pow(2,this.options.overzoom)) % this.numWorkers) + this.numWorkers) % this.numWorkers]
        worker.postMessage({
            request: 'render',
            tileId: tileId,
            zoom: zoom,
            overzoom: this.options.overzoom,
            tilePoint: tilePoint,
            tileSize: this.options.tileSize
        })
    }
});
L.tileLayer.osmTileAccessLogLayer = function(data, doneCallback) {
    return new L.TileLayer.OsmTileAccessLogLayer(data, doneCallback);
}
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var fs = require( 'fs' );
var mergeTrees = require( 'broccoli-merge-trees' );
var path = require( 'path' );
var writeFile = require( 'broccoli-file-creator' );

module.exports = {

    /**
     * Name of addon
     *
     * @type {String}
     */
    name: 'ember-forge-ui',

    /**
     * Name of companion ember-forge-ui addon
     *
     * @type {?String}
     */
    emberForgeUiCompanionAddonName: null,

    /**
     * Set name of ember-forge-ui companion addon to local context if exists
     *
     * @param {String} environment
     * @param {Object} appConfig
     * @returns {undefined}
     */
    config: function( environment, appConfig ) {
        if ( appConfig[this.name] && appConfig[this.name].addonName ) {
            this.emberForgeUiCompanionAddonName = appConfig[this.name].addonName;
        }
    },

    /**
     * Return templates if ember-forge-ui companion addon is installed, default ones if not
     *
     * @param {Object} tree
     * @returns {Object}
     */
    treeForAddonTemplates: function() {
        if ( this.emberForgeUiCompanionAddonName ) {
            return this.treeGenerator(
                path.join( this.nodeModulesPath, this.emberForgeUiCompanionAddonName, 'addon', 'templates' )
            );

        } else {
            var componentTemplateTrees = [];
            var files = fs.readdirSync( path.join( this.nodeModulesPath, '../', 'addon', 'components' ) );
            var placeholderContentPath = path.join(
                this.nodeModulesPath,
                '../',
                'addon',
                'templates',
                'components'
            ) + path.sep + 'placeholder-content.hbs';
            var placeholderContent = require( placeholderContentPath );

            files.forEach( function( element ) {
                componentTemplateTrees.push(
                    writeFile( '/components/' + element.replace( '.js', '' ) + '.hbs', placeholderContent() )
                );
            });

            return mergeTrees( componentTemplateTrees );
        }
    }
};
<commit_msg>Update paths<commit_after>/* jshint node: true */
'use strict';

var fs = require( 'fs' );
var mergeTrees = require( 'broccoli-merge-trees' );
var path = require( 'path' );
var writeFile = require( 'broccoli-file-creator' );

module.exports = {

    /**
     * Name of addon
     *
     * @type {String}
     */
    name: 'ember-forge-ui',

    /**
     * Name of companion ember-forge-ui addon
     *
     * @type {?String}
     */
    emberForgeUiCompanionAddonName: null,

    /**
     * Set name of ember-forge-ui companion addon to local context if exists
     *
     * @param {String} environment
     * @param {Object} appConfig
     * @returns {undefined}
     */
    config: function( environment, appConfig ) {
        if ( appConfig[this.name] && appConfig[this.name].addonName ) {
            this.emberForgeUiCompanionAddonName = appConfig[this.name].addonName;
        }
    },

    /**
     * Return templates if ember-forge-ui companion addon is installed, default ones if not
     *
     * @param {Object} tree
     * @returns {Object}
     */
    treeForAddonTemplates: function() {
        if ( this.emberForgeUiCompanionAddonName ) {
            return this.treeGenerator(
                path.join( this.nodeModulesPath, '../../', this.emberForgeUiCompanionAddonName, 'addon', 'templates' )
            );

        } else {
            var componentTemplateTrees = [];
            var files = fs.readdirSync( path.join( this.nodeModulesPath, '../', 'addon', 'components' ) );
            var placeholderContentPath = path.join(
                this.nodeModulesPath,
                '../',
                'addon',
                'templates',
                'components'
            ) + path.sep + 'placeholder-content.hbs';
            var placeholderContent = require( placeholderContentPath );

            files.forEach( function( element ) {
                componentTemplateTrees.push(
                    writeFile( '/components/' + element.replace( '.js', '' ) + '.hbs', placeholderContent() )
                );
            });

            return mergeTrees( componentTemplateTrees );
        }
    }
};
<|endoftext|>


<commit_before>var tracking = [];

function isVisible(elm) {
  var rect = elm.getBoundingClientRect();

  return rect.bottom > 0 &&
    rect.right > 0 &&
    rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
    rect.top < (window.innerHeight || document.documentElement.clientHeight);
}

function _onScroll() {
  window.requestAnimationFrame(_checkForVisibleElements);
}

function _handleVisible(elm, options) {
  untrack(elm);

  if (options.handler !== void 0) {
    options.handler(elm);
  }
}

function _trackNewElement(elm, options) {
  if (isVisible(elm)) {
    return _handleVisible(elm, options);
  }

  tracking.push({elm: elm, options: options});
}

function _checkForVisibleElements() {
  tracking.forEach((v) => {
    if (isVisible(v.elm)) {
      _handleVisible(v.elm, v.options);
    }
  });

  if (tracking.length === 0) {
    window.removeEventListener('scroll', _onScroll);
  }
}

function track(elm, options) {
  window.requestAnimationFrame(() => _trackNewElement(elm, options));

  if (tracking.length === 0) {
    window.addEventListener('scroll', _onScroll);
  }
}

function untrackAll() {
  tracking = [];
}

function untrack(elm) {
  var elmIndex = -1;

  tracking.some((v, i) => {
    if (v.elm == elm) {
      elmIndex = i;
      return true;
    }
  });

  if (elmIndex !== -1) {
    tracking.splice(elmIndex, 1);
  }
}

export default {track, untrackAll, untrack};
<commit_msg>Use let for scoped methods<commit_after>var tracking = [];

function isVisible(elm) {
  let rect = elm.getBoundingClientRect();

  return rect.bottom > 0 &&
    rect.right > 0 &&
    rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
    rect.top < (window.innerHeight || document.documentElement.clientHeight);
}

function _onScroll() {
  window.requestAnimationFrame(_checkForVisibleElements);
}

function _handleVisible(elm, options) {
  untrack(elm);

  if (options.handler !== void 0) {
    options.handler(elm);
  }
}

function _trackNewElement(elm, options) {
  if (isVisible(elm)) {
    return _handleVisible(elm, options);
  }

  tracking.push({elm: elm, options: options});
}

function _checkForVisibleElements() {
  tracking.forEach((v) => {
    if (isVisible(v.elm)) {
      _handleVisible(v.elm, v.options);
    }
  });

  if (tracking.length === 0) {
    window.removeEventListener('scroll', _onScroll);
  }
}

function track(elm, options) {
  window.requestAnimationFrame(() => _trackNewElement(elm, options));

  if (tracking.length === 0) {
    window.addEventListener('scroll', _onScroll);
  }
}

function untrackAll() {
  tracking = [];
}

function untrack(elm) {
  let elmIndex = -1;

  tracking.some((v, i) => {
    if (v.elm == elm) {
      elmIndex = i;
      return true;
    }
  });

  if (elmIndex !== -1) {
    tracking.splice(elmIndex, 1);
  }
}

export default {track, untrackAll, untrack};
<|endoftext|>


<commit_before>'use strict';

var Module = require('module');
var hooks = Object.create(null);
var interceptors = [];
var moduleInterceptors = {};

/**
 * The `barney` module itself.
 * @typedef {object} barney
 */

/**
 * A module interceptor function. It accepts the same params as the original
 * loader function.
 * @see https://github.com/joyent/node/blob/master/lib/module.js#L275
 * @typedef {function(request, parent, isMain)} Interceptor
 */

/**
 * Original loader
 * @private
 */
var originalLoadMethod = Module._load;

/**
 * Hooked loader.
 *
 * @see https://github.com/joyent/node/blob/master/lib/module.js#L275
 * @param request
 * @param parent
 * @param isMain
 * @returns {*}
 * @private
 */
function hookedLoadMethod(request/*, parent, isMain*/) {
  var args = arguments;
  var resolved = resolve(request);

  return intercept(interceptors, args) ||
      intercept(moduleInterceptors[resolved], args) ||
      hooks[resolved] ||
      originalLoadMethod.apply(Module, args);
}

/**
 * A generic method for adding hooks and interceptors:
 *
 * Adds a generic interceptor that will be triggered in every call to
 * `require()`.
 *
 * @param {Interceptor} module
 * @returns {barney}
 *
 * @throws {TypeError} If an invalid interceptor is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 *
 *
 * @also
 *
 *
 * Adds a hook to a specific module.
 *
 * @param {string} module
 * @param {*} value
 *
 * @throws {TypeError} If an invalid module name is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 *
 *
 * @also
 *
 *
 * Adds an interceptor to a specific module.
 *
 * @param {string} module
 * @param {Interceptor} value
 * @param {boolean} cache Cache must be **EXPLICITLY** set to `false`.
 *
 * @throws {TypeError} If an invalid module name is provided.
 * @throws {TypeError} if an invalid interceptor is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 */
exports.use = function (module, value, cache) {
  if (typeof module === 'function') {
    value = module;
    module = null;
  }

  if (arguments.length < 3) {
    cache = true;
  }

  if (module) {
    if (typeof value === 'function' && !cache) {
      exports.intercept(module, value);
    } else {
      exports.hook(module, value);
    }
  } else {
    exports.intercept(value);
  }

  return this;
};

/**
 * Adds a hook to the given module.
 *
 * @param {string} module
 * @param {*} value The value to be returned when `require`-ing the module.
 * Beware that returning a falsy value will cause the hook to be ignored.
 *
 * @returns {barney} Returns the `barney` module itself.
 */
exports.hook = function (module, value) {
  if (typeof module !== 'string') {
    throw new TypeError('Invalid module');
  }

  hooks[resolve(module)] = value;
  return this;
};

/**
 * Adds a generic interceptor (called by every call to `require()`).
 *
 * @param {Interceptor} interceptor
 * @param {number} [index] Index at which the interceptor should be added.
 *
 * @throws {TypeError} If an invalid interceptor is provided
 *
 * @returns {barney}
 *
 *
 * @also
 *
 *
 * Adds an interceptor for a specific module.
 *
 * @param {string} module
 * @param {Interceptor} interceptor
 * @param {number} [index] Index at which the interceptor should be added.
 *
 * @throws {TypeError} If an invalid module is provided.
 * @throws {TypeError} If an invalid interceptor is provided.
 *
 * @returns {barney}
 */
exports.intercept = function (module, interceptor, index) {
  if (arguments.length < 3 && typeof module === 'function') {
    index = interceptor;
    interceptor = module;
    module = null;
  }

  if (typeof interceptor !== 'function') {
    throw new TypeError('Invalid interceptor');
  }

  if (module) {
    addModuleInterceptor(module, interceptor, index);
  } else {
    addInterceptor(interceptor, index);
  }

  return this;
};

/**
 * Removes all hooks and interceptors.
 * @returns {barney}
 *
 * @also
 *
 * Removes all hooks and interceptors for a specific module.
 *
 * @param {string} module
 * @returns {barney}
 */
exports.restore = function (module) {
  var resolved;

  if (module) {
    resolved = resolve(module);
    delete hooks[resolved];
    delete moduleInterceptors[resolved];
  } else {
    hooks = {};
    interceptors = [];
    moduleInterceptors = {};
  }

  return this;
};

/**
 * Activates the barney module.
 * @returns {barney}
 */
exports.activate = function () {
  Module._load = hookedLoadMethod;
  return this;
};

/**
 * Deactivates the barney module. This does **not** remove hooks nor
 * interceptors, it just restores the original loader function.
 * @see {@link .restore}
 * @returns {barney}
 */
exports.deactivate = function () {
  Module._load = originalLoadMethod;
  return this;
};

/**
 * Removes the cached module value from node's cache.
 * @param module
 * @returns {barney}
 */
exports.unload = function (module) {
  delete require.cache[resolve(module)];
  return this;
};

/**
 * Checks if barney is active.
 * @returns {boolean}
 */
exports.isActive = function () {
  return Module._load === hookedLoadMethod;
};

/**
 * Throws a `module not found` error. Just a helper for simulating missing
 * modules, e.g.:
 *
 *     barney.intercept('foo', barney.notFound);
 *
 */
exports.notFound = function () {
  var err = new Error('Module not found');
  err.code = 'MODULE_NOT_FOUND';
  throw(err);
};

exports.activate();

// HELPERS /////////////////////////////////////////////////////////////////////

/** @private */
function addModuleInterceptor(module, interceptor, index) {
  var resolved = resolve(module);
  var interceptors = moduleInterceptors[resolved];

  if (!interceptors) {
    interceptors = moduleInterceptors[resolved] = [];
  }

  addInterceptor(interceptors, interceptor, index);
}

/** @private */
function addInterceptor(list, interceptor, index) {
  if (typeof list === 'function') {
    index = interceptor;
    interceptor = list;
    list = null;
  }

  list = list || interceptors;

  if (list.indexOf(interceptor) === -1) {
    if (index || index === 0) {
      list.splice(index, 0, interceptor);
    } else {
      list.push(interceptor);
    }
  }
}

/** @private */
function intercept(list, args) {
  var i, len, val;

  if (list) {
    for (i = 0, len = list.length; i < len; i += 1) {
      val = list[i].apply(null, args);
      if (val) { return val; }
    }
  }
}

/** @private */
function resolve(module) {
  try {
    return require.resolve(module);
  } catch (err) {
    if (err.code === 'MODULE_NOT_FOUND') {
      return module;
    }

    throw err;
  }
}
<commit_msg>refactor(coverage): ignore untestable branch<commit_after>'use strict';

var Module = require('module');
var hooks = Object.create(null);
var interceptors = [];
var moduleInterceptors = {};

/**
 * The `barney` module itself.
 * @typedef {object} barney
 */

/**
 * A module interceptor function. It accepts the same params as the original
 * loader function.
 * @see https://github.com/joyent/node/blob/master/lib/module.js#L275
 * @typedef {function(request, parent, isMain)} Interceptor
 */

/**
 * Original loader
 * @private
 */
var originalLoadMethod = Module._load;

/**
 * Hooked loader.
 *
 * @see https://github.com/joyent/node/blob/master/lib/module.js#L275
 * @param request
 * @param parent
 * @param isMain
 * @returns {*}
 * @private
 */
function hookedLoadMethod(request/*, parent, isMain*/) {
  var args = arguments;
  var resolved = resolve(request);

  return intercept(interceptors, args) ||
      intercept(moduleInterceptors[resolved], args) ||
      hooks[resolved] ||
      originalLoadMethod.apply(Module, args);
}

/**
 * A generic method for adding hooks and interceptors:
 *
 * Adds a generic interceptor that will be triggered in every call to
 * `require()`.
 *
 * @param {Interceptor} module
 * @returns {barney}
 *
 * @throws {TypeError} If an invalid interceptor is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 *
 *
 * @also
 *
 *
 * Adds a hook to a specific module.
 *
 * @param {string} module
 * @param {*} value
 *
 * @throws {TypeError} If an invalid module name is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 *
 *
 * @also
 *
 *
 * Adds an interceptor to a specific module.
 *
 * @param {string} module
 * @param {Interceptor} value
 * @param {boolean} cache Cache must be **EXPLICITLY** set to `false`.
 *
 * @throws {TypeError} If an invalid module name is provided.
 * @throws {TypeError} if an invalid interceptor is provided.
 *
 * @returns {barney} Returns the `barney` module itself.
 */
exports.use = function (module, value, cache) {
  if (typeof module === 'function') {
    value = module;
    module = null;
  }

  if (arguments.length < 3) {
    cache = true;
  }

  if (module) {
    if (typeof value === 'function' && !cache) {
      exports.intercept(module, value);
    } else {
      exports.hook(module, value);
    }
  } else {
    exports.intercept(value);
  }

  return this;
};

/**
 * Adds a hook to the given module.
 *
 * @param {string} module
 * @param {*} value The value to be returned when `require`-ing the module.
 * Beware that returning a falsy value will cause the hook to be ignored.
 *
 * @returns {barney} Returns the `barney` module itself.
 */
exports.hook = function (module, value) {
  if (typeof module !== 'string') {
    throw new TypeError('Invalid module');
  }

  hooks[resolve(module)] = value;
  return this;
};

/**
 * Adds a generic interceptor (called by every call to `require()`).
 *
 * @param {Interceptor} interceptor
 * @param {number} [index] Index at which the interceptor should be added.
 *
 * @throws {TypeError} If an invalid interceptor is provided
 *
 * @returns {barney}
 *
 *
 * @also
 *
 *
 * Adds an interceptor for a specific module.
 *
 * @param {string} module
 * @param {Interceptor} interceptor
 * @param {number} [index] Index at which the interceptor should be added.
 *
 * @throws {TypeError} If an invalid module is provided.
 * @throws {TypeError} If an invalid interceptor is provided.
 *
 * @returns {barney}
 */
exports.intercept = function (module, interceptor, index) {
  if (arguments.length < 3 && typeof module === 'function') {
    index = interceptor;
    interceptor = module;
    module = null;
  }

  if (typeof interceptor !== 'function') {
    throw new TypeError('Invalid interceptor');
  }

  if (module) {
    addModuleInterceptor(module, interceptor, index);
  } else {
    addInterceptor(interceptor, index);
  }

  return this;
};

/**
 * Removes all hooks and interceptors.
 * @returns {barney}
 *
 * @also
 *
 * Removes all hooks and interceptors for a specific module.
 *
 * @param {string} module
 * @returns {barney}
 */
exports.restore = function (module) {
  var resolved;

  if (module) {
    resolved = resolve(module);
    delete hooks[resolved];
    delete moduleInterceptors[resolved];
  } else {
    hooks = {};
    interceptors = [];
    moduleInterceptors = {};
  }

  return this;
};

/**
 * Activates the barney module.
 * @returns {barney}
 */
exports.activate = function () {
  Module._load = hookedLoadMethod;
  return this;
};

/**
 * Deactivates the barney module. This does **not** remove hooks nor
 * interceptors, it just restores the original loader function.
 * @see {@link .restore}
 * @returns {barney}
 */
exports.deactivate = function () {
  Module._load = originalLoadMethod;
  return this;
};

/**
 * Removes the cached module value from node's cache.
 * @param module
 * @returns {barney}
 */
exports.unload = function (module) {
  delete require.cache[resolve(module)];
  return this;
};

/**
 * Checks if barney is active.
 * @returns {boolean}
 */
exports.isActive = function () {
  return Module._load === hookedLoadMethod;
};

/**
 * Throws a `module not found` error. Just a helper for simulating missing
 * modules, e.g.:
 *
 *     barney.intercept('foo', barney.notFound);
 *
 */
exports.notFound = function () {
  var err = new Error('Module not found');
  err.code = 'MODULE_NOT_FOUND';
  throw(err);
};

exports.activate();

// HELPERS /////////////////////////////////////////////////////////////////////

/** @private */
function addModuleInterceptor(module, interceptor, index) {
  var resolved = resolve(module);
  var interceptors = moduleInterceptors[resolved];

  if (!interceptors) {
    interceptors = moduleInterceptors[resolved] = [];
  }

  addInterceptor(interceptors, interceptor, index);
}

/** @private */
function addInterceptor(list, interceptor, index) {
  if (typeof list === 'function') {
    index = interceptor;
    interceptor = list;
    list = null;
  }

  list = list || interceptors;

  if (list.indexOf(interceptor) === -1) {
    if (index || index === 0) {
      list.splice(index, 0, interceptor);
    } else {
      list.push(interceptor);
    }
  }
}

/** @private */
function intercept(list, args) {
  var i, len, val;

  if (list) {
    for (i = 0, len = list.length; i < len; i += 1) {
      val = list[i].apply(null, args);
      if (val) { return val; }
    }
  }
}

/** @private */
function resolve(module) {
  try {
    return require.resolve(module);
  } catch (err) {
    // As long as `module` is a string, this should be the only
    // error thrown by `require.resolve()`
    /* istanbul ignore else */
    if (err.code === 'MODULE_NOT_FOUND') {
      return module;
    } else {
      throw err;
    }
  }
}
<|endoftext|>


<commit_before>var { setInterval, clearInterval } = require("sdk/timers");
var { ToggleButton } = require('sdk/ui/button/toggle');
var notifications = require("sdk/notifications");
var persistent = require("sdk/simple-storage");
var panels = require("sdk/panel");
var self = require("sdk/self");
var tabs = require("sdk/tabs");

// objeto com os dados mais importantes (não persistentes)
var twitch = {
    name: 'Cogumelando',
    username: 'cogumelandooficial',
    streamTitle: 'LIVE',
    offAirTitle: 'OFF',
    offAirMessage: 'Aguarde e Xonfie',
    notifySfx: '../assets/adanado.ogg'
};

var configs = {
    badgeLabel: twitch.name+' 🔁',
    mainLoop: undefined
};

// Storage do twitch. Simbólico por enquanto
persistent.storage.twitch = twitch;

setPersistent('streaming', false);

if (persistent.storage.notify === undefined) {
    setPersistent('notify', true);
}
if (persistent.storage.sound === undefined) {
    setPersistent('sound', true);
}
if (persistent.storage.interval === undefined) {
    setPersistent('interval', 1);
}
if (persistent.storage.installed === undefined) {
    liveNotify(
        "Notificações estão ativadas, se quiser desativar entre nas opções.",
        "options"
    );
    setPersistent('installed', true);
}

var button = ToggleButton({
  id: "cogux",
  label: configs.badgeLabel,
  icon: {
    "24": "./icon-24.png",
    "32": "./icon-32.png",
    "48": "./icon-48.png"
  },
  onChange: handleChange,
  badge: "...",
  badgeColor: "rgba(153, 153, 153, 0.46)"
});

var panel = panels.Panel({
    contentURL: self.data.url("pages/panel.html"),
    contentScriptFile: [
        self.data.url("scripts/jquery.min.js"),
        self.data.url("scripts/img_loader.min.js"),
        self.data.url("scripts/howler.min.js"),
        self.data.url("scripts/panel-controller.js")
    ],
    onHide: handleHide,
    width: 320,
    height: 210
});

function handleChange(state) {
    if (state.checked) {
        panel.show({
            position: button
        });
        panel.port.emit('open', persistent.storage, twitch);
    }
}

function handleHide() {
    button.state('window', {
        checked: false,
        label: configs.badgeLabel
    });
}

function setPersistent(name, value) {
    persistent.storage[name] = value;
}

function getPersistent(name) {
    return persistent.storage[name];
}

function liveNotify(msg, url) {
    notifications.notify({
        title: "Cogumelando",
        text: msg,
        iconURL: self.data.url("icon128.png"),
        data: url,
        onClick: function (data) {
            if (data === 'options') {
                showOptions('pages/options.html');
            }else {
                tabs.open(data);
            }
        }
    });
}

function showOptions(_url){
    tabs.open({
        url: _url,
        onReady: function(tab) {
            var options = tab.attach({
                contentScriptFile: self.data.url("scripts/options-controller.js")
            });
            options.port.on("html", function(message) {
                console.log(message);
            });
        }
    });
}

function setBadgeStatus(label, txt, color){
    configs.badgeLabel = label;
    button.state('window', {"label" : label});
    button.badge = txt;
    button.badgeColor = color;
}

function setBadgeIdle() {
    setBadgeStatus(twitch.name+' 🔁', '...', 'rgba(153,153,153,0.46)');
}

function setBadgeStream(game) {
    var label = twitch.name;
    if(game) label += ' 🎮 '+game;
    setBadgeStatus(label, twitch.streamTitle, 'rgba(0,221,0,0.46)');
}

function setBadgeOff() {
    setBadgeStatus(twitch.name+' ☕ '+twitch.offAirMessage, twitch.offAirTitle, 'rgba(221,0,0,0.46)');
}

function setMainInterval(min) {
    if (configs.mainLoop) {
        clearInterval(configs.mainLoop);
    }
    configs.mainLoop = setInterval(mainLoop, min * 60000);
}

// Intervalos //
function mainLoop(){
    panel.port.emit('livecheck', persistent.storage);
}

setMainInterval(getPersistent('interval'));

// Events //
panel.port.on('tab', function (url) {
    tabs.open(url);
});

panel.port.on('options', function (_url) {
    showOptions(_url);
});

panel.port.on('resize', function (x, y) {
    console.log('x = '+x);
    console.log('y = '+y);
    panel.width = x + 19;
    panel.height = y + 19;
});

panel.port.on('persist', function (name, value) {
    setPersistent(name, value);
});

panel.port.on('twitch-received', function (twitchJson) {
    // checa se está acontecendo uma live
    if(twitchJson.stream){ // live acontecendo
        // joga todos os dados da live nos dados persistentes
        setPersistent('channel', twitchJson.stream);
        // cria um link para o nome do jogo
        var game = twitchJson.stream.game;

        // faz uma checagem pra saber se no loop anterior já estava em live
        if(!getPersistent('streaming')){
            // muda o estado de live para true
            setPersistent('streaming', true);

            // se as notificações estiverem ativadas
            if(getPersistent('notify')){
                var liveGame = game != null ? game : "live";
                liveNotify(
                    "É TEMPO! Começando "+liveGame+" ao vivo agora!",
                    'http://www.twitch.tv/cogumelandooficial/'
                );
            }
            // se as notificações sonoras estiverem ativadas
            if (getPersistent('sound')) {
                // toca o ADANADO
                panel.port.emit('sound-notify', twitch.notifySfx);
            }
        }

        // altera as informações do botão
        setBadgeStream(game);

    }else{ // canal offline
        // altera o estado de stream pra offline
        setPersistent('streaming', false);
        // altera as informações do botão (parecido com o que está acima)
        setBadgeOff();
    }
});

panel.port.on('connection-error', setBadgeIdle);
<commit_msg>Hide panel on tab-open<commit_after>var { setInterval, clearInterval } = require("sdk/timers");
var { ToggleButton } = require('sdk/ui/button/toggle');
var notifications = require("sdk/notifications");
var persistent = require("sdk/simple-storage");
var panels = require("sdk/panel");
var self = require("sdk/self");
var tabs = require("sdk/tabs");

// objeto com os dados mais importantes (não persistentes)
var twitch = {
    name: 'Cogumelando',
    username: 'cogumelandooficial',
    streamTitle: 'LIVE',
    offAirTitle: 'OFF',
    offAirMessage: 'Aguarde e Xonfie',
    notifySfx: '../assets/adanado.ogg'
};

var configs = {
    badgeLabel: twitch.name+' 🔁',
    mainLoop: undefined
};

// Storage do twitch. Simbólico por enquanto
persistent.storage.twitch = twitch;

setPersistent('streaming', false);

if (persistent.storage.notify === undefined) {
    setPersistent('notify', true);
}
if (persistent.storage.sound === undefined) {
    setPersistent('sound', true);
}
if (persistent.storage.interval === undefined) {
    setPersistent('interval', 1);
}
if (persistent.storage.installed === undefined) {
    liveNotify(
        "Notificações estão ativadas, se quiser desativar entre nas opções.",
        "options"
    );
    setPersistent('installed', true);
}

var button = ToggleButton({
  id: "cogux",
  label: configs.badgeLabel,
  icon: {
    "24": "./icon-24.png",
    "32": "./icon-32.png",
    "48": "./icon-48.png"
  },
  onChange: handleChange,
  badge: "...",
  badgeColor: "rgba(153, 153, 153, 0.46)"
});

var panel = panels.Panel({
    contentURL: self.data.url("pages/panel.html"),
    contentScriptFile: [
        self.data.url("scripts/jquery.min.js"),
        self.data.url("scripts/img_loader.min.js"),
        self.data.url("scripts/howler.min.js"),
        self.data.url("scripts/panel-controller.js")
    ],
    onHide: handleHide,
    width: 320,
    height: 210
});

function handleChange(state) {
    if (state.checked) {
        panel.show({
            position: button
        });
        panel.port.emit('open', persistent.storage, twitch);
    }
}

function handleHide() {
    button.state('window', {
        checked: false,
        label: configs.badgeLabel
    });
}

function setPersistent(name, value) {
    persistent.storage[name] = value;
}

function getPersistent(name) {
    return persistent.storage[name];
}

function liveNotify(msg, url) {
    notifications.notify({
        title: "Cogumelando",
        text: msg,
        iconURL: self.data.url("icon128.png"),
        data: url,
        onClick: function (data) {
            if (data === 'options') {
                showOptions('pages/options.html');
            }else {
                tabs.open(data);
            }
        }
    });
}

function showOptions(_url){
    tabs.open({
        url: _url,
        onReady: function(tab) {
            var options = tab.attach({
                contentScriptFile: self.data.url("scripts/options-controller.js")
            });
            options.port.on("html", function(message) {
                console.log(message);
            });
        }
    });
}

function setBadgeStatus(label, txt, color){
    configs.badgeLabel = label;
    button.state('window', {"label" : label});
    button.badge = txt;
    button.badgeColor = color;
}

function setBadgeIdle() {
    setBadgeStatus(twitch.name+' 🔁', '...', 'rgba(153,153,153,0.46)');
}

function setBadgeStream(game) {
    var label = twitch.name;
    if(game) label += ' 🎮 '+game;
    setBadgeStatus(label, twitch.streamTitle, 'rgba(0,221,0,0.46)');
}

function setBadgeOff() {
    setBadgeStatus(twitch.name+' ☕ '+twitch.offAirMessage, twitch.offAirTitle, 'rgba(221,0,0,0.46)');
}

function setMainInterval(min) {
    if (configs.mainLoop) {
        clearInterval(configs.mainLoop);
    }
    configs.mainLoop = setInterval(mainLoop, min * 60000);
}

// Intervalos //
function mainLoop(){
    panel.port.emit('livecheck', persistent.storage);
}

setMainInterval(getPersistent('interval'));

// Events //
panel.port.on('tab', function (url) {
    tabs.open(url);
    panel.hide();
});

panel.port.on('options', function (_url) {
    showOptions(_url);
    panel.hide();
});

panel.port.on('resize', function (x, y) {
    console.log('x = '+x);
    console.log('y = '+y);
    panel.width = x + 19;
    panel.height = y + 19;
});

panel.port.on('persist', function (name, value) {
    setPersistent(name, value);
});

panel.port.on('twitch-received', function (twitchJson) {
    // checa se está acontecendo uma live
    if(twitchJson.stream){ // live acontecendo
        // joga todos os dados da live nos dados persistentes
        setPersistent('channel', twitchJson.stream);
        // cria um link para o nome do jogo
        var game = twitchJson.stream.game;

        // faz uma checagem pra saber se no loop anterior já estava em live
        if(!getPersistent('streaming')){
            // muda o estado de live para true
            setPersistent('streaming', true);

            // se as notificações estiverem ativadas
            if(getPersistent('notify')){
                var liveGame = game != null ? game : "live";
                liveNotify(
                    "É TEMPO! Começando "+liveGame+" ao vivo agora!",
                    'http://www.twitch.tv/cogumelandooficial/'
                );
            }
            // se as notificações sonoras estiverem ativadas
            if (getPersistent('sound')) {
                // toca o ADANADO
                panel.port.emit('sound-notify', twitch.notifySfx);
            }
        }

        // altera as informações do botão
        setBadgeStream(game);

    }else{ // canal offline
        // altera o estado de stream pra offline
        setPersistent('streaming', false);
        // altera as informações do botão (parecido com o que está acima)
        setBadgeOff();
    }
});

panel.port.on('connection-error', setBadgeIdle);
<|endoftext|>