<commit_before>frappe.ready(async () => {
    initialise_select_date();
})

window.holiday_list = [];

async function initialise_select_date() {
    navigate_to_page(1);
    await get_global_variables();
    setup_date_picker();
    setup_timezone_selector();
    hide_next_button();
}

async function get_global_variables() {
    // Using await
    window.appointment_settings = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_appointment_settings'
    })).message;
    window.timezones = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_timezones'
    })).message;
    window.holiday_list = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_holiday_list',
        args: {
            'holiday_list_name': window.appointment_settings.holiday_list
        }
    })).message;
}

function setup_timezone_selector() {
    let timezones_element = document.getElementById('appointment-timezone');
    let offset = new Date().getTimezoneOffset();
    window.timezones.forEach(timezone => {
        let opt = document.createElement('option');
        opt.value = timezone;
        if (timezone == moment.tz.guess()) {
            opt.selected = true;
        }
        opt.innerHTML = timezone;
        timezones_element.appendChild(opt)
    });
}

function setup_date_picker() {
    let date_picker = document.getElementById('appointment-date');
    let today = new Date();
    date_picker.min = today.toISOString().substr(0, 10);
    today.setDate(today.getDate() + window.appointment_settings.advance_booking_days);
    date_picker.max = today.toISOString().substr(0, 10);
}

function hide_next_button() {
    let next_button = document.getElementById('next-button');
    next_button.disabled = true;
    next_button.onclick = () => frappe.msgprint("Please select a date and time");
}

function show_next_button() {
    let next_button = document.getElementById('next-button');
    next_button.disabled = false;
    next_button.onclick = setup_details_page;
}

function on_date_or_timezone_select() {
    let date_picker = document.getElementById('appointment-date');
    let timezone = document.getElementById('appointment-timezone');
    if (date_picker.value === '') {
        clear_time_slots();
        hide_next_button();
        frappe.throw('Please select a date');
    }
    window.selected_date = date_picker.value;
    window.selected_timezone = timezone.value;
    update_time_slots(date_picker.value, timezone.value);
    let lead_text = document.getElementById('lead-text');
    lead_text.innerHTML = "Select Time"
}

async function get_time_slots(date, timezone) {
    let slots = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_appointment_slots',
        args: {
            date: date,
            timezone: timezone
        }
    })).message;
    return slots;
}

async function update_time_slots(selected_date, selected_timezone) {
    let timeslot_container = document.getElementById('timeslot-container');
    window.slots = await get_time_slots(selected_date, selected_timezone);
    clear_time_slots();
    if (window.slots.length <= 0) {
        let message_div = document.createElement('p');
        message_div.innerHTML = "There are no slots available on this date";
        timeslot_container.appendChild(message_div);
        return
    }
    window.slots.forEach((slot, index) => {
        // Get and append timeslot div
        let timeslot_div = get_timeslot_div_layout(slot)
        timeslot_container.appendChild(timeslot_div);
    });
    set_default_timeslot();
}

function get_timeslot_div_layout(timeslot) {
    let start_time = new Date(timeslot.time)
    let timeslot_div = document.createElement('div');
    timeslot_div.classList.add('time-slot');
    if (!timeslot.availability) {
        timeslot_div.classList.add('unavailable')
    }
    timeslot_div.innerHTML = get_slot_layout(start_time);
    timeslot_div.id = timeslot.time.substr(11, 20);
    timeslot_div.addEventListener('click', select_time);
    return timeslot_div
}

function clear_time_slots() {
    // Clear any existing divs in timeslot container
    let timeslot_container = document.getElementById('timeslot-container');
    while (timeslot_container.firstChild) {
        timeslot_container.removeChild(timeslot_container.firstChild);
    }
}

function get_slot_layout(time) {
    time = new Date(time);
    let start_time_string = moment(time).format("LT");
    let end_time = moment(time).add(window.appointment_settings.appointment_duration, 'minutes');
    let end_time_string = end_time.format("LT");
    return `<span style="font-size: 1.2em;">${start_time_string}</span><br><span class="text-muted small">to ${end_time_string}</span>`;
}

function select_time() {
    if (this.classList.contains('unavailable')) {
        return;
    }
    let selected_element = document.getElementsByClassName('selected');
    if (!(selected_element.length > 0)) {
        this.classList.add('selected');
        show_next_button();
        return;
    }
    selected_element = selected_element[0]
    window.selected_time = this.id;
    selected_element.classList.remove('selected');
    this.classList.add('selected');
    show_next_button();
}

function set_default_timeslot() {
    let timeslots = document.getElementsByClassName('time-slot')
    // Can't use a forEach here since, we need to break the loop after a timeslot is selected
    for (let i = 0; i < timeslots.length; i++) {
        const timeslot = timeslots[i];
        if (!timeslot.classList.contains('unavailable')) {
            timeslot.classList.add('selected');
            break;
        }
    }
}

function navigate_to_page(page_number) {
    let page1 = document.getElementById('select-date-time');
    let page2 = document.getElementById('enter-details');
    switch (page_number) {
        case 1:
            page1.style.display = 'block';
            page2.style.display = 'none';
            break;
        case 2:
            page1.style.display = 'none';
            page2.style.display = 'block';
            break;
        default:
            break;
    }
}

function setup_details_page() {
    navigate_to_page(2)
    let date_container = document.getElementsByClassName('date-span')[0];
    let time_container = document.getElementsByClassName('time-span')[0];
    date_container.innerHTML = moment(window.selected_date).format("MMM Do YYYY");
    time_container.innerHTML = moment(window.selected_time, "HH:mm:ss").format("LT");
}

async function submit() {
    let form = document.querySelector('#customer-form');
    if (!form.checkValidity()) {
        form.reportValidity();
        return;
    }
    get_form_data();
    let appointment = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.create_appointment',
        args: {
            'date': window.selected_date,
            'time': window.selected_time,
            'contact': window.contact
        }
    })).message;
    frappe.msgprint(__('Appointment Created Successfully'));
    let button = document.getElementById('submit-button');
    button.disabled = true;
    button.onclick = null
}

function get_form_data() {
    contact = {};
    contact.name = document.getElementById('customer_name').value;
    contact.number = document.getElementById('customer_number').value;
    contact.skype = document.getElementById('customer_skype').value;
    contact.notes = document.getElementById('customer_notes').value;
    contact.email = document.getElementById('customer_email').value;
    window.contact = contact
}
<commit_msg>fix: merge settings into one call<commit_after>frappe.ready(async () => {
    initialise_select_date();
})

window.holiday_list = [];

async function initialise_select_date() {
    navigate_to_page(1);
    await get_global_variables();
    setup_date_picker();
    setup_timezone_selector();
    hide_next_button();
}

async function get_global_variables() {
    // Using await
    window.appointment_settings = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_appointment_settings'
    })).message;
    window.timezones = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_timezones'
    })).message;
    window.holiday_list = window.appointment_settings.holiday_list;
}

function setup_timezone_selector() {
    let timezones_element = document.getElementById('appointment-timezone');
    let offset = new Date().getTimezoneOffset();
    window.timezones.forEach(timezone => {
        let opt = document.createElement('option');
        opt.value = timezone;
        if (timezone == moment.tz.guess()) {
            opt.selected = true;
        }
        opt.innerHTML = timezone;
        timezones_element.appendChild(opt)
    });
}

function setup_date_picker() {
    let date_picker = document.getElementById('appointment-date');
    let today = new Date();
    date_picker.min = today.toISOString().substr(0, 10);
    today.setDate(today.getDate() + window.appointment_settings.advance_booking_days);
    date_picker.max = today.toISOString().substr(0, 10);
}

function hide_next_button() {
    let next_button = document.getElementById('next-button');
    next_button.disabled = true;
    next_button.onclick = () => frappe.msgprint("Please select a date and time");
}

function show_next_button() {
    let next_button = document.getElementById('next-button');
    next_button.disabled = false;
    next_button.onclick = setup_details_page;
}

function on_date_or_timezone_select() {
    let date_picker = document.getElementById('appointment-date');
    let timezone = document.getElementById('appointment-timezone');
    if (date_picker.value === '') {
        clear_time_slots();
        hide_next_button();
        frappe.throw('Please select a date');
    }
    window.selected_date = date_picker.value;
    window.selected_timezone = timezone.value;
    update_time_slots(date_picker.value, timezone.value);
    let lead_text = document.getElementById('lead-text');
    lead_text.innerHTML = "Select Time"
}

async function get_time_slots(date, timezone) {
    let slots = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.get_appointment_slots',
        args: {
            date: date,
            timezone: timezone
        }
    })).message;
    return slots;
}

async function update_time_slots(selected_date, selected_timezone) {
    let timeslot_container = document.getElementById('timeslot-container');
    window.slots = await get_time_slots(selected_date, selected_timezone);
    clear_time_slots();
    if (window.slots.length <= 0) {
        let message_div = document.createElement('p');
        message_div.innerHTML = "There are no slots available on this date";
        timeslot_container.appendChild(message_div);
        return
    }
    window.slots.forEach((slot, index) => {
        // Get and append timeslot div
        let timeslot_div = get_timeslot_div_layout(slot)
        timeslot_container.appendChild(timeslot_div);
    });
    set_default_timeslot();
}

function get_timeslot_div_layout(timeslot) {
    let start_time = new Date(timeslot.time)
    let timeslot_div = document.createElement('div');
    timeslot_div.classList.add('time-slot');
    if (!timeslot.availability) {
        timeslot_div.classList.add('unavailable')
    }
    timeslot_div.innerHTML = get_slot_layout(start_time);
    timeslot_div.id = timeslot.time.substr(11, 20);
    timeslot_div.addEventListener('click', select_time);
    return timeslot_div
}

function clear_time_slots() {
    // Clear any existing divs in timeslot container
    let timeslot_container = document.getElementById('timeslot-container');
    while (timeslot_container.firstChild) {
        timeslot_container.removeChild(timeslot_container.firstChild);
    }
}

function get_slot_layout(time) {
    time = new Date(time);
    let start_time_string = moment(time).format("LT");
    let end_time = moment(time).add(window.appointment_settings.appointment_duration, 'minutes');
    let end_time_string = end_time.format("LT");
    return `<span style="font-size: 1.2em;">${start_time_string}</span><br><span class="text-muted small">to ${end_time_string}</span>`;
}

function select_time() {
    if (this.classList.contains('unavailable')) {
        return;
    }
    let selected_element = document.getElementsByClassName('selected');
    if (!(selected_element.length > 0)) {
        this.classList.add('selected');
        show_next_button();
        return;
    }
    selected_element = selected_element[0]
    window.selected_time = this.id;
    selected_element.classList.remove('selected');
    this.classList.add('selected');
    show_next_button();
}

function set_default_timeslot() {
    let timeslots = document.getElementsByClassName('time-slot')
    // Can't use a forEach here since, we need to break the loop after a timeslot is selected
    for (let i = 0; i < timeslots.length; i++) {
        const timeslot = timeslots[i];
        if (!timeslot.classList.contains('unavailable')) {
            timeslot.classList.add('selected');
            break;
        }
    }
}

function navigate_to_page(page_number) {
    let page1 = document.getElementById('select-date-time');
    let page2 = document.getElementById('enter-details');
    switch (page_number) {
        case 1:
            page1.style.display = 'block';
            page2.style.display = 'none';
            break;
        case 2:
            page1.style.display = 'none';
            page2.style.display = 'block';
            break;
        default:
            break;
    }
}

function setup_details_page() {
    navigate_to_page(2)
    let date_container = document.getElementsByClassName('date-span')[0];
    let time_container = document.getElementsByClassName('time-span')[0];
    date_container.innerHTML = moment(window.selected_date).format("MMM Do YYYY");
    time_container.innerHTML = moment(window.selected_time, "HH:mm:ss").format("LT");
}

async function submit() {
    let form = document.querySelector('#customer-form');
    if (!form.checkValidity()) {
        form.reportValidity();
        return;
    }
    get_form_data();
    let appointment = (await frappe.call({
        method: 'erpnext.www.book-appointment.index.create_appointment',
        args: {
            'date': window.selected_date,
            'time': window.selected_time,
            'contact': window.contact,
            'tz':window.selected_timezone
        }
    })).message;
    frappe.msgprint(__('Appointment Created Successfully'));
    let button = document.getElementById('submit-button');
    button.disabled = true;
    button.onclick = null
}

function get_form_data() {
    contact = {};
    contact.name = document.getElementById('customer_name').value;
    contact.number = document.getElementById('customer_number').value;
    contact.skype = document.getElementById('customer_skype').value;
    contact.notes = document.getElementById('customer_notes').value;
    contact.email = document.getElementById('customer_email').value;
    window.contact = contact
}
<|endoftext|>


<commit_before>'use strict'
const OBJ = 'object'

module.exports = function merge (a, b, checked) {
  if (checked || typeof a === OBJ) {
    for (let key in b) {
      let bProp = b[key]
      if (typeof bProp === OBJ) {
        let aProp = a[key]
        if (typeof aProp !== OBJ) {
          a[key] = aProp = {}
        }
        merge(aProp, bProp, true)
      } else {
        a[key] = bProp
      }
    }
    return a
  }
}
<commit_msg>deprecate merge<commit_after>'use strict'
const OBJ = 'object'

module.exports = function merge (a, b, checked) {
  console.warn('`vigour-util/merge` is deprecated, consider using `lodash.merge` instead')
  if (checked || typeof a === OBJ) {
    for (let key in b) {
      let bProp = b[key]
      if (typeof bProp === OBJ) {
        let aProp = a[key]
        if (typeof aProp !== OBJ) {
          a[key] = aProp = {}
        }
        merge(aProp, bProp, true)
      } else {
        a[key] = bProp
      }
    }
    return a
  }
}
<|endoftext|>


<commit_before>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var Config = require('./Config');
var DebugHeader = require('./DebugHeader');
var Device = require('../device');

var AddToDOM = require('../dom/AddToDOM');
var DOMContentLoaded = require('../dom/DOMContentLoaded');

var MainLoop = require('./MainLoop');
var CreateRenderer = require('./CreateRenderer');
var GlobalInputManager = require('../input/GlobalInputManager');
var GlobalStateManager = require('../state/GlobalStateManager');
var AnimationManager = require('../animation/AnimationManager');
var TextureManager = require('../textures/TextureManager');
var Data = require('../components/Data');
var Cache = require('../cache/Cache');

var Game = function (config)
{
    this.config = new Config(config);

    this.renderer = null;
    this.canvas = null;
    this.context = null;

    this.isBooted = false;
    this.isRunning = false;

    /**
    * @property {Phaser.AnimationManager} anims - Reference to the Phaser Animation Manager.
    */
    this.anims = new AnimationManager(this);

    /**
    * @property {Phaser.TextureManager} textures - Reference to the Phaser Texture Manager.
    */
    this.textures = new TextureManager(this);

    /**
    * @property {Phaser.Cache} cache - Reference to the assets cache.
    */
    this.cache = new Cache();

    /**
    * @property {Phaser.Data} registry - Game wide data store.
    */
    this.registry = new Data(this);

    /**
    * @property {Phaser.Input} input - Reference to the input manager
    */
    this.input = new GlobalInputManager(this, this.config);

    /**
    * @property {Phaser.GlobalStateManager} state - The StateManager. Phaser instance specific.
    */
    this.state = new GlobalStateManager(this, this.config.stateConfig);

    /**
    * @property {Phaser.Device} device - Contains device information and capabilities (singleton)
    */
    this.device = Device;

    /**
    * @property {Phaser.MainLoop} mainloop - Main Loop handler.
    * @protected
    */
    this.mainloop = new MainLoop(this, this.config.fps);

    //  Wait for the DOM Ready event, then call boot.
    DOMContentLoaded(this.boot.bind(this));

    //  For debugging only
    window.game = this;
};

Game.prototype.constructor = Game;

Game.prototype = {

    boot: function ()
    {
        this.isBooted = true;

        this.config.preBoot();

        DebugHeader(this);

        CreateRenderer(this);

        AddToDOM(this.canvas, this.config.parent);

        this.state.boot();

        this.input.boot();

        this.isRunning = true;

        this.config.postBoot();

        this.mainloop.start();
    }

};

module.exports = Game;
<commit_msg>Animation Manager boot state call.<commit_after>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var Config = require('./Config');
var DebugHeader = require('./DebugHeader');
var Device = require('../device');

var AddToDOM = require('../dom/AddToDOM');
var DOMContentLoaded = require('../dom/DOMContentLoaded');

var MainLoop = require('./MainLoop');
var CreateRenderer = require('./CreateRenderer');
var GlobalInputManager = require('../input/GlobalInputManager');
var GlobalStateManager = require('../state/GlobalStateManager');
var AnimationManager = require('../animation/AnimationManager');
var TextureManager = require('../textures/TextureManager');
var Data = require('../components/Data');
var Cache = require('../cache/Cache');

var Game = function (config)
{
    this.config = new Config(config);

    this.renderer = null;
    this.canvas = null;
    this.context = null;

    this.isBooted = false;
    this.isRunning = false;

    /**
    * @property {Phaser.AnimationManager} anims - Reference to the Phaser Animation Manager.
    */
    this.anims = new AnimationManager(this);

    /**
    * @property {Phaser.TextureManager} textures - Reference to the Phaser Texture Manager.
    */
    this.textures = new TextureManager(this);

    /**
    * @property {Phaser.Cache} cache - Reference to the assets cache.
    */
    this.cache = new Cache();

    /**
    * @property {Phaser.Data} registry - Game wide data store.
    */
    this.registry = new Data(this);

    /**
    * @property {Phaser.Input} input - Reference to the input manager
    */
    this.input = new GlobalInputManager(this, this.config);

    /**
    * @property {Phaser.GlobalStateManager} state - The StateManager. Phaser instance specific.
    */
    this.state = new GlobalStateManager(this, this.config.stateConfig);

    /**
    * @property {Phaser.Device} device - Contains device information and capabilities (singleton)
    */
    this.device = Device;

    /**
    * @property {Phaser.MainLoop} mainloop - Main Loop handler.
    * @protected
    */
    this.mainloop = new MainLoop(this, this.config.fps);

    //  Wait for the DOM Ready event, then call boot.
    DOMContentLoaded(this.boot.bind(this));

    //  For debugging only
    window.game = this;
};

Game.prototype.constructor = Game;

Game.prototype = {

    boot: function ()
    {
        this.isBooted = true;

        this.config.preBoot();

        DebugHeader(this);

        CreateRenderer(this);

        AddToDOM(this.canvas, this.config.parent);

        this.anims.boot(this.textures);

        this.state.boot();

        this.input.boot();

        this.isRunning = true;

        this.config.postBoot();

        this.mainloop.start();
    }

};

module.exports = Game;
<|endoftext|>


<commit_before>const Twitter = require('twitter');

class Stream {
  constructor(controller) {
    this.controller = controller;
    this.client = new Twitter({
      consumer_key: process.env.TWITTER_CONSUMER_KEY,
      consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
      access_token_key: process.env.TWITTER_ACCESS_TOKEN,
      access_token_secret: process.env.TWITTER_ACCESS_SECRET,
    });
  }

  run() {
    this.controller.hears('start', 'direct_mention', (bot, msg) => {
      if (this.stream) {
        bot.reply(msg, `already streaming by '${this.stream.track}'`);
      } else {
        bot.reply(msg, 'start streaming');
        this.startStreaming(bot, msg);
      }
    });

    this.controller.hears('stop', 'direct_mention', (bot, msg) => {
      if (this.stream) {
        this.stream.destroy();
        this.stream = null;
        bot.reply(msg, 'stop streaming');
      } else {
        bot.reply(msg, 'stream is not found');
      }
    });
  }

  startStreaming(bot, msg) {
    const track = 'プレミアムフライデー';

    this.stream = this.client.stream('statuses/filter', { track });
    this.stream.track = track;
    this.stream.on('data', (tweet) => {
      bot.reply(msg, {
        attachments: [
          this.buildTweetAttachment(tweet),
        ],
      });
    });
    this.stream.on('error', (error) => {
      bot.botkit.log('Error: Twitter Stream ', error);
    });
  }

  buildTweetAttachment(tweet) {
    return {
      author_name: `${tweet.user.name} @${tweet.user.screen_name}`,
      author_icon: tweet.user.profile_image_url_https,
      author_link: `https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`,
      text: tweet.text,
      footer: 'Twitter',
      footer_icon: 'https://a.slack-edge.com/6e067/img/services/twitter_pixel_snapped_32.png',
      ts: new Date(Date.parse(tweet.created_at)).getTime() / 1000,
      fallback: tweet.text,
      callback_id: tweet.id_str,
      actions: [
        {
          name: 'like',
          text: 'Like',
          type: 'button',
        },
        {
          name: 'retweet',
          text: 'Retweet',
          type: 'button',
        },
      ],
    };
  }
}

module.exports = Stream;
<commit_msg>Open stream by specify query<commit_after>const Twitter = require('twitter');

class Stream {
  constructor(controller) {
    this.controller = controller;
    this.client = new Twitter({
      consumer_key: process.env.TWITTER_CONSUMER_KEY,
      consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
      access_token_key: process.env.TWITTER_ACCESS_TOKEN,
      access_token_secret: process.env.TWITTER_ACCESS_SECRET,
    });
  }

  run() {
    this.controller.hears('^start streaming(.*)$', 'direct_mention', (bot, msg) => {
      const query = msg.match[1].trim();
      if (this.stream) {
        bot.reply(msg, `Already streaming by "${this.stream.query}" :no_mouth:`);
        return;
      } else if (query.length < 1) {
        bot.reply(msg, 'No filter specified :cry:\nUsage: start streaming "Twitter search query"')
        return;
      }

      bot.botkit.log('Streaming Query:', query);
      bot.reply(msg, `OK:ok_hand: Start streaming by ${query}`);
      this.startStreaming(bot, msg, query);
    });

    this.controller.hears('stop streaming', 'direct_mention', (bot, msg) => {
      if (this.stream) {
        this.stream.destroy();
        this.stream = null;
        bot.reply(msg, 'OK:ok_hand: Stop streaming');
      } else {
        bot.reply(msg, 'Stream is not found :no_mouth:');
      }
    });
  }

  startStreaming(bot, msg, track) {
    this.stream = this.client.stream('statuses/filter', { track });
    this.stream.query = track;
    this.stream.on('data', (tweet) => {
      bot.reply(msg, {
        attachments: [
          this.buildTweetAttachment(tweet),
        ],
      });
    });
    this.stream.on('error', (error) => {
      bot.botkit.log('Error: Twitter Stream ', error);
    });
  }

  buildTweetAttachment(tweet) {
    return {
      author_name: `${tweet.user.name} @${tweet.user.screen_name}`,
      author_icon: tweet.user.profile_image_url_https,
      author_link: `https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`,
      text: tweet.text,
      footer: 'Twitter',
      footer_icon: 'https://a.slack-edge.com/6e067/img/services/twitter_pixel_snapped_32.png',
      ts: new Date(Date.parse(tweet.created_at)).getTime() / 1000,
      fallback: tweet.text,
      callback_id: tweet.id_str,
      actions: [
        {
          name: 'like',
          text: 'Like',
          type: 'button',
        },
        {
          name: 'retweet',
          text: 'Retweet',
          type: 'button',
        },
      ],
    };
  }
}

module.exports = Stream;
<|endoftext|>


<commit_before>'use strict';

// date output of |date "+DATE: %m/%d/%y TIME: %H:%M:%S"| command.
var LAST_UPDATE = '';

var DEBUG = true;
var CACHE_NAME = 'foo';
var cached = [
  '/index.html',
  '/test.html',
  '/css/app.css',
  '/js/app.js',
  '/img/mozilla.png'
];

if (!self.debug) {
  self.debug = function debug(message) {
    dump("Execution context(" + LAST_UPDATE + "): " + message + "\n");
  };
}

self.addEventListener('message', msg => {
  debug('event from client - ' + msg.data);
  self.clients.matchAll().then(function(res) {
    if (!res.length) {
      debug("no clients are currently controlled!");
      return;
    }
    res[0].postMessage(msg.data === 'ping' ? 'pong' : msg.data);
  });
});

self.addEventListener('install', evt => {
  if (DEBUG) {
    debug('install event fired!');
  }

  function delaysAsInstalled() {
    debug('opening cache...');
    return caches.open(CACHE_NAME).then((cache) => {
      debug('opened cache so adding content!');
      return cache.addAll(cached);
    });
  }
  evt.waitUntil(delaysAsInstalled());
});

self.addEventListener('activate', evt => {
  if (DEBUG) {
    debug('activate event fired!');
  }
  function delaysAsActivated() {
    return Promise.resolve();
  }
  evt.waitUntil(delaysAsActivated());
});

self.addEventListener('fetch', evt => {
  var request = evt.request;
  var url = new URL(request.url);

  if (DEBUG) {
    debug('fetching ' + url.pathname);
  }

  evt.respondWith(
    caches.match(request).then((response) => {
      if (response) {
        return response;
      } else {
        var fetchRequest = request.clone();
        return fetch(fetchRequest).then((response) => {
          if (!response ||
              (response.status !== 200) || (response.type !== 'basic')) {
            return response;
          }
          var responseToCache = response.clone();
          caches.open(CACHE_NAME).then((cache) => {
            cache.put(request, responseToCache);
          });
          return response;
        });
      }
    })
  );
});
<commit_msg>Update service worker script<commit_after>'use strict';

// date output of |date "+DATE: %m/%d/%y TIME: %H:%M:%S"| command.
var LAST_UPDATE = 'DATE: 04/29/15 TIME: 16:30:22';

var DEBUG = true;
var CACHE_NAME = 'foo';
var cached = [
  '/index.html',
  '/test.html',
  '/css/app.css',
  '/js/app.js',
  '/img/mozilla.png'
];

if (!self.debug) {
  self.debug = function debug(message) {
    dump("Execution context(" + LAST_UPDATE + "): " + message + "\n");
  };
}

self.addEventListener('message', msg => {
  debug('event from client - ' + msg.data);
  self.clients.matchAll().then(function(res) {
    if (!res.length) {
      debug("no clients are currently controlled!");
      return;
    }
    res[0].postMessage(msg.data === 'ping' ? 'pong' : msg.data);
  });
});

self.addEventListener('install', evt => {
  if (DEBUG) {
    debug('install event fired!');
  }

  function delaysAsInstalled() {
    debug('opening cache...');
    return caches.open(CACHE_NAME).then((cache) => {
      debug('opened cache so adding content!');
      return cache.addAll(cached);
    });
  }
  evt.waitUntil(delaysAsInstalled());
});

self.addEventListener('activate', evt => {
  if (DEBUG) {
    debug('activate event fired!');
  }
  function delaysAsActivated() {
    return Promise.resolve();
  }
  evt.waitUntil(delaysAsActivated());
});

self.addEventListener('fetch', evt => {
  var request = evt.request;
  var url = new URL(request.url);

  if (DEBUG) {
    debug('fetching ' + url.pathname);
  }

  evt.respondWith(
    caches.match(request).then((response) => {
      if (response) {
        return response;
      } else {
        var fetchRequest = request.clone();
        return fetch(fetchRequest).then((response) => {
          if (!response ||
              (response.status !== 200) || (response.type !== 'basic')) {
            return response;
          }
          var responseToCache = response.clone();
          caches.open(CACHE_NAME).then((cache) => {
            cache.put(request, responseToCache);
          });
          return response;
        });
      }
    })
  );
});
<|endoftext|>


<commit_before><commit_msg>update app/util/fileTree — cosmetic changes<commit_after><|endoftext|>


<commit_before>const dir = require("node-dir");
const path = require('path');
const chalk = require('chalk');

function fileFilter(file) {
    return true;
}

/**
 * Normalize a file path
 *
 * @param {string} filePath file path to normalize
 * @param {string} basePath base path used to perform relative path resolution
 * @returns {string} the normalized file path
 */
function normalizeFile(filePath, basePath) {
    return path.relative(basePath, filePath).replace(/\\/g, '/');
}

/**
 * Extract tags from a file path
 * @param {string} filePath the file path to process
 * @returns {Array<TMD.Tag>}
 */
function extractTagsFromPath(filePath) {
    const tags = filePath.split('/')
    .filter( (tag) => ['.', '..'].indexOf(tag) === -1)
    .map( (tag, index, list) => ({
        'name' : tag,
        'level' : index
    }));

    tags.pop();
    return tags;
}

/**
 * Creates and returns a *Document* object for the given file path argument.
 *
 * @param {string} filePath path to the document
 * @returns {TMD.document} the document object
 */
function createDocument(filePath) {
    return {
        "file" : filePath,
        "tags" : extractTagsFromPath(filePath)
    };
}

/**
 * Creates and returns an array of object representing all the
 * documents located inside the basePath folder or in one of its subfolder.
 *
 * @param {string} basePath path to the folder containing files to process
 * @returns {Array<TMD.Document>} list of extracted documents
 */
function readDocuments( basePath) {
    return dir.promiseFiles(basePath)
    .then( (files) => files
            .map( (filePath) => normalizeFile(filePath, basePath))
            .filter( (filePath => fileFilter(filePath)))
            .map( (filePath) => createDocument(filePath))
    );
}

function buildTagIndex(documents) {
    let index = {};
    documents.forEach( (document) => {
        document.tags.forEach( (tag) => {
            if( !index.hasOwnProperty(tag.name)) {
                index[tag.name] = {
                    "index"    : tag.index,
                    "docCount" : 1
                };
            } else {
                index[tag.name].index += tag.index;
                index[tag.name].docCount += 1;
            }
        });
    });
    return index;
}

readDocuments('./test')
.then( (documents) => {
    console.log(JSON.stringify(documents));
    const tagIndex = buildTagIndex(documents);
    console.log(JSON.stringify(tagIndex));
});

/*

const basePath = './test/data';

console.log(chalk.blue(`${basePath}`));
console.log(path.resolve(basePath));

const resPath = path.resolve(basePath);

console.log(path.relative(basePath,"./test/data/base/c"));

dir.promiseFiles('./test/data/base')
    .then( (files) => {
        //files.map( (file) => )
        console.log(files);
    })
*/<commit_msg>rename index to level property<commit_after>const dir = require("node-dir");
const path = require('path');
const chalk = require('chalk');

function fileFilter(file) {
    return true;
}

/**
 * Normalize a file path
 *
 * @param {string} filePath file path to normalize
 * @param {string} basePath base path used to perform relative path resolution
 * @returns {string} the normalized file path
 */
function normalizeFile(filePath, basePath) {
    return path.
        relative(basePath, filePath).
        replace(/\\/g, '/');
}

/**
 * Extract tags from a file path
 * @param {string} filePath the file path to process
 * @returns {Array<TMD.Tag>}
 */
function extractTagsFromPath(filePath) {
    const tags = filePath.split('/')
    .filter( (tag) => ['.', '..'].indexOf(tag) === -1)
    .map( (tag, index, list) => ({
        'name' : tag,
        'level' : index
    }));

    // remove last item which is the filename
    tags.pop();
    return tags;
}

/**
 * Creates and returns a *Document* object for the given file path argument.
 *
 * @param {string} filePath path to the document
 * @returns {TMD.document} the document object
 */
function createDocument(filePath) {
    return {
        "filePath" : filePath,
        "tags" : extractTagsFromPath(filePath)
    };
}

/**
 * Creates and returns an array of object representing all the
 * documents located inside the basePath folder or in one of its subfolder.
 *
 * @param {string} basePath path to the folder containing files to process
 * @returns {Array<TMD.Document>} list of extracted documents
 */
function readDocuments( basePath) {
    return dir.promiseFiles(basePath)
    .then( (files) => files
            .map( (filePath) => normalizeFile(filePath, basePath))
            .filter( (filePath => fileFilter(filePath)))
            .map( (filePath) => createDocument(filePath))
    );
}

/**
 * Extract the tag index from a list of Documents.
 * The Tag Index is an object where each property is a tag name with a value being an object :
 * ```json
{
    "tagName1" : {
        "index" : 1,
        "docCount" : 12
    },
    "tagName2" : {
        "index" : 0,
        "docCount" : 50
    },
    // etc ...
}
 * ```
 * @param {Array<TMD.Document>} documents set of documents to process
 * @returns {any}
 */
function buildTagIndex(documents) {
    let index = {};
    documents.forEach( (document) => {
        document.tags.forEach( (tag) => {
            if( !index.hasOwnProperty(tag.name)) {
                index[tag.name] = {
                    "index"    : tag.level,
                    "docCount" : 1
                };
            } else {
                index[tag.name].index += tag.level;
                index[tag.name].docCount += 1;
            }
        });
    });
    return index;
}

console.log(chalk.blue('building document list ...'));
readDocuments('./test')
    .then( (documents) => {
        console.log(JSON.stringify(documents));
        const tagIndex = buildTagIndex(documents);
        console.log(JSON.stringify(tagIndex));
    })
    .catch( (error) => {
        console.error(error);
    });

<|endoftext|>


<commit_before>var LevelCompiler = require('./compiler');

var LevelSession = module.exports = function(collectionMap, cache) {
  this.collectionMap = collectionMap;
  this.cache = cache || {};
};

function convertToModel(config, entity, isBare) {
  return entity;
  /*var obj;
  if (isBare) {
    obj = entity;
  } else {
    obj = Object.create(config.constructor.prototype);
    var keys = Object.keys(config.fieldMap || {});
    keys.forEach(function(key) {
      var prop = config.fieldMap[key] || key;
      if (key.indexOf('.') === -1) {
        obj[key] = entity[prop];
      } else {
        var parts = prop.split('.');
        var part = parts.reduce(function(prev, cur) {
          if (Array.isArray(prev)) {
            return prev.map(function(item) {
              return item[cur];
            });
          } else if (prev.hasOwnProperty(cur)) {
            return prev[cur];
          }
        }, entity)

        obj[key] = part;
      }
    });
  }

  return obj;*/
}

LevelSession.prototype.find = function(query, cb) {
  if (typeof query === 'function') {
    cb = query;
    query = null;
  }

  if (!query) {
    query = 'select *';
  }

  var collection = query.modelConfig.collection;
  var db = this.collectionMap[collection];

  var compiler = new LevelCompiler(this.cache);
  var compiled = compiler.compile(query.build(), query.modelConfig);

  var buffer = [];

  db.createReadStream({ valueEncoding: 'json' })
    .on('data', function(data) {
      if (result = compiled.filterOne(data.value)) {
        buffer.push(result);
      }
    })
    .on('end', function() {
      var sorted = compiled.sort(buffer);
      var entities = sorted.map(function(value) {
        return convertToModel(query.modelConfig, value, query.modelConfig.isBare);
      });

      cb(null, entities);
    })
    .on('error', function(err) {
      cb(err);
    });
};

LevelSession.prototype.get = function(query, id, cb) {
  var collection = query.modelConfig.collection;
  var db = this.collectionMap[collection];

  var config = query.modelConfig;

  db.get(id, function(err, value) {
    if (err) {
      cb(err);
      return;
    }

    var model = convertToModel(config, value, config.isBare);
    cb(null, model);
  });
};

LevelSession.create = function(options) {
  return new LevelSession(options);
};
<commit_msg>Cleaning up old code.<commit_after>var LevelCompiler = require('./compiler');

var LevelSession = module.exports = function(collectionMap, cache) {
  this.collectionMap = collectionMap;
  this.cache = cache || {};
};

LevelSession.prototype.find = function(query, cb) {
  if (typeof query === 'function') {
    cb = query;
    query = null;
  }

  if (!query) {
    query = 'select *';
  }

  var collection = query.modelConfig.collection;
  var db = this.collectionMap[collection];

  var compiler = new LevelCompiler(this.cache);
  var compiled = compiler.compile(query.build(), query.modelConfig);

  var buffer = [];

  db.createReadStream({ valueEncoding: 'json' })
    .on('data', function(data) {
      if (result = compiled.filterOne(data.value)) {
        buffer.push(result);
      }
    })
    .on('end', function() {
      var sorted = compiled.sort(buffer);

      cb(null, sorted);
    })
    .on('error', function(err) {
      cb(err);
    });
};

LevelSession.prototype.get = function(query, id, cb) {
  var collection = query.modelConfig.collection;
  var db = this.collectionMap[collection];

  var config = query.modelConfig;

  db.get(id, function(err, value) {
    if (err) {
      cb(err);
      return;
    }

    cb(null, value);
  });
};

LevelSession.create = function(options) {
  return new LevelSession(options);
};
<|endoftext|>


<commit_before>(function (document, window) {
  var _ = window._ = {};

  _.findEl = function findEl(root, selector) {
    return root.querySelector(selector);
  }

  /*
   * param root is optional
   */
  _.findEls = function findEls(root, selector) {
    if (selector == null) {
      selector = root;
      root = document;
    }
    return _.array(root.querySelectorAll(selector));
  }

  _.byId = function byId(id) {
    return document.getElementById(id);
  }

  _.array = function array(arr) {
      return [].slice.call(arr);
  }

  _.fillEls = function fillEls(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function (el) { el.textContent = value; });
  }

  _.addClass = function addClass(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function(el){el.classList.add(value);});
  }

  _.removeClass = function removeClass(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function(el){el.classList.remove(value);});
  }

})(document, window);
<commit_msg>add client-side 404<commit_after>(function (document, window) {
  var _ = window._ = {};

  _.findEl = function findEl(root, selector) {
    return root.querySelector(selector);
  }

  /*
   * param root is optional
   */
  _.findEls = function findEls(root, selector) {
    if (selector == null) {
      selector = root;
      root = document;
    }
    return _.array(root.querySelectorAll(selector));
  }

  _.byId = function byId(id) {
    return document.getElementById(id);
  }

  _.array = function array(arr) {
      return [].slice.call(arr);
  }

  _.fillEls = function fillEls(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function (el) { el.textContent = value; });
  }

  _.addClass = function addClass(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function(el){el.classList.add(value);});
  }

  _.removeClass = function removeClass(root, selector, value) {
    if (value == null) {
      value = selector;
      selector = root;
      root = document;
    }
    _.findEls(root, selector).forEach(function(el){el.classList.remove(value);});
  }

  _.notFound = function notFound() {
    document.body.innerHTML = '';
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/404');
    xhr.onload = function () {
      document.open();
      document.write(xhr.responseText);
      document.close();
    };
    xhr.send();
  }

})(document, window);
<|endoftext|>


<commit_before>// Inspired by: http://www.davidflanagan.com/2009/08/typeof-isfuncti.html

'use strict';

var forEach = Array.prototype.forEach.bind([]);

module.exports = function (obj) {
	var type;
	if (!obj) return false;
	type = typeof obj;
	if (type === 'function') return true;
	if (type !== 'object') return false;

	try {
		forEach(obj);
		return true;
	} catch (e) {
		if (e instanceof TypeError) return false;
		throw e;
	}
};
<commit_msg>Simplify isCallable<commit_after>'use strict';

module.exports = function (obj) { return typeof obj === 'function'; };
<|endoftext|>


<commit_before>/**
 * Created by truthlighting on 9/20/2016.
 */
/**
 * This guys does the other half of energy collection. The miner gets it from the source, and the helper does the
 * transportation. We don't want them just going for the nearest source, as that means that if we have more than one
 * miner, all the helpers will only go for the first miner. To counter this, we assign them to a miner the same way
 * we assign a miner to a source
 */

var helper = {
    parts: [
        [MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY, MOVE, CARRY]
    ],

    assignMiner: function () {
        var creep = this.creep;

        var miner = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (miner) {
                if (miner.memory.role == 'miner' && miner.memory.helpers.length < miner.memory.helpersNeeded)
                    return true;

                return false;
            }
        });

        if (miner == undefined)
            return;

        creep.memory.miner = miner.id;
        miner.memory.helpers.push(creep.id);
    },

    /**
     * @TODO: Make helpers smarter about avoiding miners, instead of just waiting till they're 5 tiles away
     * @TODO: When spawns are at .25, and extensions have >= 200, help builders before filling shit up
     */
    action: function () {
        var creep = this.creep;

        if (creep.memory.courier !== undefined && creep.memory.courier == true) {
            creep.memory.courier = false;
            return;
        }

        //If this helper isn't assigned to a miner, find one and assign him to it. If it is assigned to a miner,
        //then find that miner by his id
        if (creep.memory.miner == undefined)
            this.assignMiner();

        var miner = Game.getObjectById(creep.memory.miner);

        if (miner == null) {
            creep.suicide();
            return;
        }
        //console.log("i'm here");
        //If we can still pick up energy, let's do that
        //console.log("miner: " + miner);
        console.log("creep:" + creep);
        console.log("creep.carry: (" + _.sum(creep.carry) + ") < creep.carryCapacity (" + creep.carryCapacity + ")");
        console.log(creep.carry < creep.carryCapacity);
        if (creep.carry < creep.carryCapacity) {
            console.log("i'm here");
            if (creep.pos.isNearTo(miner)) {
                var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 1)[0];
                console.log("energy: " + energy);
                creep.pickup(energy);
            }
            else {
                console.log("miner.memory.isNearSource: " + miner.memory.isNearSource);
                if (miner.memory.isNearSource)
                    creep.moveTo(miner);
            }

            return;
        }

        var target = null;

        //Okay, everything below is for dropping energy off

        if (!target) {
            var spawn = creep.pos.findClosestByPath(FIND_MY_SPAWNS);

            //If we found it, set it as our target
            if (spawn)
                target = spawn;
        }

        //Let's get the direction we want to go in
        var targetDirection = creep.pos.findPathTo(target, { ignoreCreeps: true })[0].direction;

        //Let's look for a courier in that direction. We'll check on making sure they're the right
        //role, if they can hold any energy, if they're in range and if they're in the same direction
        var leftDir = targetDirection - 1;
        var rightDir = targetDirection + 1;

        if (leftDir < 1)
            leftDir += 8;
        if (leftDir > 8)
            leftDir -= 8;

        if (rightDir < 1)
            rightDir += 8;
        if (rightDir > 8)
            rightDir -= 8;

        var courier = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (possibleTarget) {
                return (
                    possibleTarget.memory.role == creep.memory.role
//					&& possibleTarget.memory.miner == creep.memory.miner
                    && _.sum(possibleTarget.carry) < possibleTarget.carryCapacity
                    && creep.pos.inRangeTo(possibleTarget, 1)
                    && (
                        creep.pos.getDirectionTo(possibleTarget) == targetDirection
                        || creep.pos.getDirectionTo(possibleTarget) == leftDir
                        || creep.pos.getDirectionTo(possibleTarget) == rightDir
                    )
                );
            }
        });

        //If we found a courier, make that courier our new target
        if (courier !== null && !creep.pos.isNearTo(target)) {
            target = courier;
            target.memory.courier = true;
        }

        //If we're near to the target, either give it our energy or drop it
        if (creep.pos.isNearTo(target)) {
            if (target.energy < target.energyCapacity) {
                creep.transfer(target, RESOURCE_ENERGY);
            }
            else
                creep.drop(RESOURCE_ENERGY);
        }
        //Let's do the moving
        else {
            creep.moveTo(target);
        }
    }
};

module.exports = helper;<commit_msg>Fixing miner_helper<commit_after>/**
 * Created by truthlighting on 9/20/2016.
 */
/**
 * This guys does the other half of energy collection. The miner gets it from the source, and the helper does the
 * transportation. We don't want them just going for the nearest source, as that means that if we have more than one
 * miner, all the helpers will only go for the first miner. To counter this, we assign them to a miner the same way
 * we assign a miner to a source
 */

var helper = {
    parts: [
        [MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY],
        [MOVE, CARRY, MOVE, CARRY, MOVE, CARRY]
    ],

    assignMiner: function () {
        var creep = this.creep;

        var miner = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (miner) {
                if (miner.memory.role == 'miner' && miner.memory.helpers.length < miner.memory.helpersNeeded)
                    return true;

                return false;
            }
        });

        if (miner == undefined)
            return;

        creep.memory.miner = miner.id;
        miner.memory.helpers.push(creep.id);
    },

    /**
     * @TODO: Make helpers smarter about avoiding miners, instead of just waiting till they're 5 tiles away
     * @TODO: When spawns are at .25, and extensions have >= 200, help builders before filling shit up
     */
    action: function () {
        var creep = this.creep;

        if (creep.memory.courier !== undefined && creep.memory.courier == true) {
            creep.memory.courier = false;
            return;
        }

        //If this helper isn't assigned to a miner, find one and assign him to it. If it is assigned to a miner,
        //then find that miner by his id
        if (creep.memory.miner == undefined)
            this.assignMiner();

        var miner = Game.getObjectById(creep.memory.miner);

        if (miner == null) {
            creep.suicide();
            return;
        }
        //console.log("i'm here");
        //If we can still pick up energy, let's do that
        //console.log("miner: " + miner);
        console.log("creep:" + creep);
        console.log("creep.carry: (" + _.sum(creep.carry) + ") < creep.carryCapacity (" + creep.carryCapacity + ")");
        console.log(creep.carry < creep.carryCapacity);
        if (_sum(creep.carry) < creep.carryCapacity) {
            console.log("i'm here");
            if (creep.pos.isNearTo(miner)) {
                var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 1)[0];
                console.log("energy: " + energy);
                creep.pickup(energy);
            }
            else {
                console.log("miner.memory.isNearSource: " + miner.memory.isNearSource);
                if (miner.memory.isNearSource)
                    creep.moveTo(miner);
            }

            return;
        }

        var target = null;

        //Okay, everything below is for dropping energy off

        if (!target) {
            var spawn = creep.pos.findClosestByPath(FIND_MY_SPAWNS);

            //If we found it, set it as our target
            if (spawn)
                target = spawn;
        }

        //Let's get the direction we want to go in
        var targetDirection = creep.pos.findPathTo(target, { ignoreCreeps: true })[0].direction;

        //Let's look for a courier in that direction. We'll check on making sure they're the right
        //role, if they can hold any energy, if they're in range and if they're in the same direction
        var leftDir = targetDirection - 1;
        var rightDir = targetDirection + 1;

        if (leftDir < 1)
            leftDir += 8;
        if (leftDir > 8)
            leftDir -= 8;

        if (rightDir < 1)
            rightDir += 8;
        if (rightDir > 8)
            rightDir -= 8;

        var courier = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
            filter: function (possibleTarget) {
                return (
                    possibleTarget.memory.role == creep.memory.role
//					&& possibleTarget.memory.miner == creep.memory.miner
                    && _.sum(possibleTarget.carry) < possibleTarget.carryCapacity
                    && creep.pos.inRangeTo(possibleTarget, 1)
                    && (
                        creep.pos.getDirectionTo(possibleTarget) == targetDirection
                        || creep.pos.getDirectionTo(possibleTarget) == leftDir
                        || creep.pos.getDirectionTo(possibleTarget) == rightDir
                    )
                );
            }
        });

        //If we found a courier, make that courier our new target
        if (courier !== null && !creep.pos.isNearTo(target)) {
            target = courier;
            target.memory.courier = true;
        }

        //If we're near to the target, either give it our energy or drop it
        if (creep.pos.isNearTo(target)) {
            if (target.energy < target.energyCapacity) {
                creep.transfer(target, RESOURCE_ENERGY);
            }
            else
                creep.drop(RESOURCE_ENERGY);
        }
        //Let's do the moving
        else {
            creep.moveTo(target);
        }
    }
};

module.exports = helper;<|endoftext|>


<commit_before>var io;
var rooms = {};
var sockets = {};

function RoomManager (server) {
	var that = this;
	io = require('socket.io')(server);

	var lobbyCon = io.of('/lobby');
	lobbyCon.on('connection', function (socket) {
		socket.emit('lobby.state', rooms);
	});

	var that = this;
	this.connections = {};
	var playerId = 0;

	var roomCon = io.of('/game');
	roomCon.on('connection', function (socket) {
		var Player = require('./player');
		var player = null;
		var roomId;
		var thisPlayerId = playerId;

		socket.on('player.join', function (data) {
			roomId = data.roomId;
			socket.join(roomId);
			if (!rooms[roomId]) {
				rooms[roomId] = {};
			}
			player = new Player(data.name, roomId, thisPlayerId, socket, socket.id);
			rooms[roomId][thisPlayerId] = player.getState();
			sockets[thisPlayerId] = socket;
			socket.emit('player.connected.self', player.getState());
			socket.broadcast.to(roomId).emit('player.connected.new', player.getState());
			lobbyCon.emit('lobby.state', rooms);
		});

		socket.on('disconnect', function () {
			socket.broadcast.to(roomId).emit('player.disconnected', player.getState());
			var room = rooms[player.roomId];
			delete room[player.playerId];
			delete sockets[player.playerId];
			if (Object.keys(room).length === 0) {
				delete rooms[player.roomId];
			}
			lobbyCon.emit('lobby.state', rooms);
		});

		socket.on('player.update', function (data) {
			// TODO: implement IM here
			/*// Update the server game state
			var room = rooms[roomId];
			var myId = data.playerId;
			if (room[myId] != undefined) {
				room[myId].gameState = data;
			}

			for (playerId in room) {

			}*/

			// Boardcast to all player in room
			socket.broadcast.to(roomId).emit('player.updated', data);
		});

		socket.on('player.shoot', function (data) {
			data.latency = player.latency;
			socket.broadcast.to(roomId).emit('player.shoot', data);

			// var room = rooms[roomId];
			// for (playerId in room) {
			// 	if (playerId != data.playerId) {
			// 		sockets[playerId].emit('player.shoot', data);
			// 	}
			// }
		});

		playerId++;
	});
}

module.exports = RoomManager;
<commit_msg>Add template for selective sending player.update<commit_after>var io;
var rooms = {};
var sockets = {};

function RoomManager (server) {
	var that = this;
	io = require('socket.io')(server);

	var lobbyCon = io.of('/lobby');
	lobbyCon.on('connection', function (socket) {
		socket.emit('lobby.state', rooms);
	});

	var that = this;
	this.connections = {};
	var playerId = 0;

	var roomCon = io.of('/game');
	roomCon.on('connection', function (socket) {
		var Player = require('./player');
		var player = null;
		var roomId;
		var thisPlayerId = playerId;

		socket.on('player.join', function (data) {
			roomId = data.roomId;
			socket.join(roomId);
			if (!rooms[roomId]) {
				rooms[roomId] = {};
			}
			player = new Player(data.name, roomId, thisPlayerId, socket, socket.id);
			rooms[roomId][thisPlayerId] = player.getState();
			sockets[thisPlayerId] = socket;
			socket.emit('player.connected.self', player.getState());
			socket.broadcast.to(roomId).emit('player.connected.new', player.getState());
			lobbyCon.emit('lobby.state', rooms);
		});

		socket.on('disconnect', function () {
			socket.broadcast.to(roomId).emit('player.disconnected', player.getState());
			var room = rooms[player.roomId];
			delete room[player.playerId];
			delete sockets[player.playerId];
			if (Object.keys(room).length === 0) {
				delete rooms[player.roomId];
			}
			lobbyCon.emit('lobby.state', rooms);
		});

		socket.on('player.update', function (data) {
			/*// Update the server game state
			var room = rooms[roomId];
			var myId = data.playerId;
			if (room[myId] != undefined) {
				room[myId].gameState = data;
			}

			for (playerId in room) {
				var forward = false;

				// Simple distance calculation
				var distance = Math.abs (room[myId].x - room[playerId].x) + Math.abs (room[myId].y - room[playerId].y);

				if (distance < 5 * 1000) {
					// Close enough! Send everything
					forward = true;

				} else if (distance < 10 * 1000) {
					// Quite far away, not interested
					// But might still be visible in large screen

					// 30% chance to discard all optional fields
					// Effectively reduce package size
					var discardChance = Math.random () < 0.3;
					if (discardChance) {
						delete data.vx;
						delete data.vy;
						delete data.landed;
						delete data.onLadder;
						delete data.ducked;
					}

					// Only forward 70% of the package
					var forwardChance = Math.random () < 0.7;
					forward = true;

				} else {
					// Super far away, definitely not interested

					// Don't even bother sending optional fields
					delete data.vx;
					delete data.vy;
					delete data.landed;
					delete data.onLadder;
					delete data.ducked;

					// Only forward 40% of the package
					var forwardChance = Math.random () < 0.4;
					forward = true;
				}

				// Forward the package to the recipient
				if (forward) {
					room[playerId].socket.emit ("player.update", data);
				}
			}*/

			// Boardcast to all player in room
			socket.broadcast.to(roomId).emit('player.updated', data);
		});

		socket.on('player.shoot', function (data) {
			data.latency = player.latency;
			socket.broadcast.to(roomId).emit('player.shoot', data);

			// var room = rooms[roomId];
			// for (playerId in room) {
			// 	if (playerId != data.playerId) {
			// 		sockets[playerId].emit('player.shoot', data);
			// 	}
			// }
		});

		playerId++;
	});
}

module.exports = RoomManager;
<|endoftext|>


<commit_before>/*

Sets up a connect server to work from the /build folder. May also set up a
livereload server at some point.

*/

module.exports = function(grunt) {

  grunt.loadNpmTasks("grunt-contrib-connect");

  grunt.config.merge({
    connect: {
      dev: {
        options: {
          livereload: true,
          base: "./build"
        }
      }
    }
  })

};
<commit_msg>Add a filter for case sensitivity<commit_after>/*

Sets up a connect server to work from the /build folder. May also set up a
livereload server at some point.

*/

var fs = require("fs");
var path = require("path");

module.exports = function(grunt) {

  grunt.loadNpmTasks("grunt-contrib-connect");

  grunt.config.merge({
    connect: {
      dev: {
        options: {
          livereload: true,
          base: "./build",
          //middleware to protect against case-insensitive file systems
          middleware: function(connect, options, ware) {
            var base = options.base.pop();
            ware.unshift(function(req, response, next) {
              var location = path.join(base, req.url);
              var filename = path.basename(req.url);
              if (!filename) return next();
              var dir = path.dirname(location);
              fs.readdir(dir, function(err, list) {
                if (list.indexOf(filename) == -1) {
                  response.statusCode = 404;
                  response.end();
                } else {
                  next();
                }
              })
            });
            return ware;
          }
        }
      }
    }
  })

};
<|endoftext|>


<commit_before>/**
 * Demo for the GameClosure DevKit Billing Module
 * https://github.com/gameclosure/billing
 *
 */

import ui.TextView as TextView;
import src.views.LogView as LogView;
import src.views.ToggleView as ToggleView;
import src.views.ButtonView as ButtonView;
import src.views.Overlay as Overlay;
import device;

import billing;
import amplitude;

var ITEMS = {
  'testpurchase10': {price: .99, quantity: 1},
  'testpurchase50': {price: 1.99, quantity: 1}
};

exports = Class(GC.Application, function () {

  this.initUI = function () {

    this.view.style.backgroundColor = 'white';

    this.marketStatus = new TextView({
      superview: this.view,
      text: "Market Status: Unknown",
      color: "black",
      x: 0,
      y: 100,
      width: this.view.style.width,
      height: 100
    });

    var buttonPadding = 25;
    var buttonWidth = (this.view.style.width - (buttonPadding * 3)) / 2;

    // if in browser, billing is always mock
    this.mockBilling = 'simulate';
    if (device.isSimulator) {
      this.mockText = new TextView({
        superview: this.view,
        x: buttonPadding,
        y: 200,
        width: this.view.style.width - (buttonPadding * 2),
        height: 22 * 2,
        text: "In Simulator - Always Mock Billing"
      });
    } else {
      this.mockToggle = new ToggleView({
        superview: this.view,
        x: buttonPadding,
        y: 200,
        width: 400,
        height: 22 * 2,
        text: "Use Mock Purchases",
        onChange: bind(this, function (mockBilling) {
          if (mockBilling) {
            this.log("Switching to mock billing");
          } else {
            this.log("Enabling Real Billing");
          }
          this.mockBilling = mockBilling && 'simulate' || void 0;
        })
      });
      this.mockBilling = void 0;
    }

    this.handlersToggle = new ToggleView({
      superview: this.view,
      x: buttonPadding,
      y: 300,
      width: 400,
      height: 22 * 2,
      text: "Purchase Handlers Enabled",
      onChange: bind(this, function (enabled) {
        if (enabled) {
          this.log("Enabling Purchase Handlers");
          this.enablePurchaseHandlers();
        } else {
          this.log("Disabling Purchase Handlers");
          this.disablePurchaseHandlers();
        }
      })
    });
    this.handlersToggle.setChecked(true);
    this.enablePurchaseHandlers();

    this.purchaseButton10 = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: 400,
      width: buttonWidth,
      height: 50,
      title: "Purchase 10 Gems",
      onClick: bind(this, function () {
        this.purchase('testpurchase10', this.mockBilling);
      })
    });
    this.purchaseButton50 = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.purchaseButton10.style.y,
      width: buttonWidth,
      height: 50,
      title: "Purchase 50 Gems",
      onClick: bind(this, function () {
        this.purchase('testpurchase50', this.mockBilling);
      })
    });
    this.purchaseButtonFail = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: this.purchaseButton10.style.y + 100,
      width: buttonWidth,
      height: 50,
      title: "Simulate Purchase Failure",
      onClick: bind(this, function () {
        this.purchase('fail', 'failure');
      })
    });
    this.purchaseButtonCancel = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.purchaseButtonFail.style.y,
      width: buttonWidth,
      height: 50,
      title: "Simulate Purchase Cancel",
      onClick: bind(this, function () {
        this.purchase('fail', 'cancel');
      })
    });

    this.localizeButton = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: this.purchaseButtonFail.style.y + 100,
      width: buttonWidth,
      height: 50,
      title: "Localize Purchases",
      onClick: bind(this, function () {
        this.localizePurchases();
      })
    });

    this.restoreButton = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.localizeButton.style.y,
      width: buttonWidth,
      height: 50,
      title: "Restore Purchases",
      onClick: bind(this, function () {
        this.restorePurchases();
      })
    });

    var logViewY = this.restoreButton.style.y +
      this.restoreButton.style.height +
      250;

    this.logView = new LogView({
      superview: this.view,
      x: 0,
      y: logViewY,
      width: this.view.style.width,
      height: this.view.style.height - logViewY
    });

    this.overlay = new Overlay({
      superview: this.view,
      x: 0,
      y: 0,
      width: this.view.style.width,
      height: this.view.style.height,
    });

    // listen for market available events
    billing.on('MarketAvailable', bind(this, function (available) {
      logger.log("billing.MarketAvailable", available);
      this.setMarketStatus(available && 'Available' || 'Unavailable');
    }));

    // check if market is available
    this.setMarketStatus(
      billing.isMarketAvailable  && 'Available' || 'Unavailable'
    );

    // listen for localization events
    billing.on("PurchasesLocalized", bind(this, function (data) {
      logger.log("billing.PurchasesLocalized", data);
      var itemIds = Object.keys(data.purchases);
      for (var i = 0; i < itemIds.length; i++) {
        var itemId = itemIds[i];
        var item = data.purchases[itemId];
        this.log("localized item " + item.title +
                 " price: " + item.displayPrice);
        logger.log(item.displayPrice, item.title, item.description);
      }
    }));

  };

  // called to initiate a purchase
  this.purchase = function (itemName, simulate) {
    var logMessage = "Purchasing " + itemName;
    if (simulate === 'simulate') {
      logMessage += " (simulating)";
    } else if (simulate !== void 0) {
      logMessage += " (simulating failure)";
    }
    this.log(logMessage);

    // if purchase handlers enabled
    if (this.handlersToggle.isChecked()) {
      this.overlay.show("Purchasing " + itemName);
    }

    billing.purchase(itemName, simulate);
  };

  // called when a purchase succeeds
  this.onPurchase = function (itemName, transactionInfo) {
    this.log("Purchase Successful! Item: " + itemName);

    // if no transactionInfo, use empty object
    transactionInfo = transactionInfo || {};

    console.log("Sending transaction data to amplitude", transactionInfo);
    // send to amplitude for tracking and validation
    var item = ITEMS[itemName];
    amplitude.trackRevenue(
      itemName,
      item.price,
      item.quantity,
      transactionInfo.signature,
      transactionInfo.purchaseData
    );

    this.overlay.hide();
  };

  // called when a purchase fails for any reason
  this.onFailure = function (reason, itemName) {
    this.log("Purchase Failed! Item: " + itemName + " Reason: " + reason);
    this.overlay.hide();
  };

  // called after all old purchases are restored
  this.onRestore = function (err) {
    if (err) {
      this.log("Unable to restore purchases: " + err);
    } else {
      this.log("Finished restoring purchases!");
    }
  };

  // send a restore event
  this.restorePurchases = function () {
    this.log("restoring purchases");
    billing.restore(bind(this, this.onRestore));
  };

  // send all the purchases to the store for localization
  this.localizePurchases = function () {
    this.log("localizing purchases");
    billing.getLocalizedPurchases(Object.keys(ITEMS));
  };

  // helper function to wrap up all the demo logging
  this.log = function (text, success) {
    logger.log(text);
    this.logView.log(text, success);
  };

  // set the market status text
  this.setMarketStatus = function (status) {
    this.log("Market Status Updated: " + status);
    this.marketStatus.setText("Market Status: " + status);
  };

  // remove purchase handlers
  this.disablePurchaseHandlers = function () {
    billing.onPurchase = void 0;
    billing.onFailure = void 0;
  };

  // add purchase handlers
  this.enablePurchaseHandlers = function () {
    billing.onPurchase = bind(this, this.onPurchase);
    billing.onFailure = bind(this, this.onFailure)
  };

});
<commit_msg>add localize many<commit_after>/**
 * Demo for the GameClosure DevKit Billing Module
 * https://github.com/gameclosure/billing
 *
 */

import ui.TextView as TextView;
import src.views.LogView as LogView;
import src.views.ToggleView as ToggleView;
import src.views.ButtonView as ButtonView;
import src.views.Overlay as Overlay;
import device;

import billing;
import amplitude;

var ITEMS = {
  'testpurchase10': {price: .99, quantity: 1},
  'testpurchase50': {price: 1.99, quantity: 1}
};

// the google store does not allow localizing more
// than 20 items at once - this demonstrates that
// billing correctly auto-batches these requests
var MANY_ITEMS = {
  'testpurchase10': {price: .99, quantity: 1}
};
for (var i = 0; i < 50; i++) {
  MANY_ITEMS['many_items_test_'+i] = {
    price: 1.00,
    quantity: 1
  }
};
MANY_ITEMS['testpurchase50'] = {price: 1.99, quantity: 1};

exports = Class(GC.Application, function () {

  this.initUI = function () {

    this.view.style.backgroundColor = 'white';

    this.marketStatus = new TextView({
      superview: this.view,
      text: "Market Status: Unknown",
      color: "black",
      x: 0,
      y: 100,
      width: this.view.style.width,
      height: 100
    });

    var buttonPadding = 25;
    var buttonWidth = (this.view.style.width - (buttonPadding * 3)) / 2;

    // if in browser, billing is always mock
    this.mockBilling = 'simulate';
    if (device.isSimulator) {
      this.mockText = new TextView({
        superview: this.view,
        x: buttonPadding,
        y: 200,
        width: this.view.style.width - (buttonPadding * 2),
        height: 22 * 2,
        text: "In Simulator - Always Mock Billing"
      });
    } else {
      this.mockToggle = new ToggleView({
        superview: this.view,
        x: buttonPadding,
        y: 200,
        width: 400,
        height: 22 * 2,
        text: "Use Mock Purchases",
        onChange: bind(this, function (mockBilling) {
          if (mockBilling) {
            this.log("Switching to mock billing");
          } else {
            this.log("Enabling Real Billing");
          }
          this.mockBilling = mockBilling && 'simulate' || void 0;
        })
      });
      this.mockBilling = void 0;
    }

    this.handlersToggle = new ToggleView({
      superview: this.view,
      x: buttonPadding,
      y: 300,
      width: 400,
      height: 22 * 2,
      text: "Purchase Handlers Enabled",
      onChange: bind(this, function (enabled) {
        if (enabled) {
          this.log("Enabling Purchase Handlers");
          this.enablePurchaseHandlers();
        } else {
          this.log("Disabling Purchase Handlers");
          this.disablePurchaseHandlers();
        }
      })
    });
    this.handlersToggle.setChecked(true);
    this.enablePurchaseHandlers();

    this.purchaseButton10 = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: 400,
      width: buttonWidth,
      height: 50,
      title: "Purchase 10 Gems",
      onClick: bind(this, function () {
        this.purchase('testpurchase10', this.mockBilling);
      })
    });
    this.purchaseButton50 = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.purchaseButton10.style.y,
      width: buttonWidth,
      height: 50,
      title: "Purchase 50 Gems",
      onClick: bind(this, function () {
        this.purchase('testpurchase50', this.mockBilling);
      })
    });
    this.purchaseButtonFail = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: this.purchaseButton10.style.y + 100,
      width: buttonWidth,
      height: 50,
      title: "Simulate Purchase Failure",
      onClick: bind(this, function () {
        this.purchase('fail', 'failure');
      })
    });
    this.purchaseButtonCancel = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.purchaseButtonFail.style.y,
      width: buttonWidth,
      height: 50,
      title: "Simulate Purchase Cancel",
      onClick: bind(this, function () {
        this.purchase('fail', 'cancel');
      })
    });

    this.localizeButton = new ButtonView({
      superview: this.view,
      x: buttonPadding,
      y: this.purchaseButtonFail.style.y + 100,
      width: buttonWidth,
      height: 50,
      title: "Localize Purchases",
      onClick: bind(this, function () {
        this.localizePurchases();
      })
    });

    this.localizeManyButton = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.localizeButton.style.y,
      width: buttonWidth,
      height: 50,
      title: "Localize Many Purchases",
      onClick: bind(this, function () {
        this.localizeManyPurchases();
      })
    });

    this.restoreButton = new ButtonView({
      superview: this.view,
      x: buttonPadding + buttonWidth + buttonPadding,
      y: this.localizeManyButton.style.y + 100,
      width: buttonWidth,
      height: 50,
      title: "Restore Purchases",
      onClick: bind(this, function () {
        this.restorePurchases();
      })
    });

    var logViewY = this.restoreButton.style.y +
      this.restoreButton.style.height +
      250;

    this.logView = new LogView({
      superview: this.view,
      x: 0,
      y: logViewY,
      width: this.view.style.width,
      height: this.view.style.height - logViewY
    });

    this.overlay = new Overlay({
      superview: this.view,
      x: 0,
      y: 0,
      width: this.view.style.width,
      height: this.view.style.height,
    });

    // listen for market available events
    billing.on('MarketAvailable', bind(this, function (available) {
      logger.log("billing.MarketAvailable", available);
      this.setMarketStatus(available && 'Available' || 'Unavailable');
    }));

    // check if market is available
    this.setMarketStatus(
      billing.isMarketAvailable  && 'Available' || 'Unavailable'
    );

    // listen for localization events
    billing.on("PurchasesLocalized", bind(this, function (data) {
      logger.log("billing.PurchasesLocalized", data);
      var itemIds = Object.keys(data.purchases);
      for (var i = 0; i < itemIds.length; i++) {
        var itemId = itemIds[i];
        var item = data.purchases[itemId];
        this.log("localized item " + item.title +
                 " price: " + item.displayPrice);
        logger.log(item.displayPrice, item.title, item.description);
      }
    }));

  };

  // called to initiate a purchase
  this.purchase = function (itemName, simulate) {
    var logMessage = "Purchasing " + itemName;
    if (simulate === 'simulate') {
      logMessage += " (simulating)";
    } else if (simulate !== void 0) {
      logMessage += " (simulating failure)";
    }
    this.log(logMessage);

    // if purchase handlers enabled
    if (this.handlersToggle.isChecked()) {
      this.overlay.show("Purchasing " + itemName);
    }

    billing.purchase(itemName, simulate);
  };

  // called when a purchase succeeds
  this.onPurchase = function (itemName, transactionInfo) {
    this.log("Purchase Successful! Item: " + itemName);

    // if no transactionInfo, use empty object
    transactionInfo = transactionInfo || {};

    console.log("Sending transaction data to amplitude", transactionInfo);

    // find item in our various purchase lists
    var item;
    if (itemName in ITEMS) {
      item = ITEMS[itemName];
    } else if (itemName in MANY_ITEMS) {
      item = MANY_ITEMS[itemName];
    }

    // send to amplitude for tracking and validation
    amplitude.trackRevenue(
      itemName,
      item.price,
      item.quantity,
      transactionInfo.signature,
      transactionInfo.purchaseData
    );

    this.overlay.hide();
  };

  // called when a purchase fails for any reason
  this.onFailure = function (reason, itemName) {
    this.log("Purchase Failed! Item: " + itemName + " Reason: " + reason);
    this.overlay.hide();
  };

  // called after all old purchases are restored
  this.onRestore = function (err) {
    if (err) {
      this.log("Unable to restore purchases: " + err);
    } else {
      this.log("Finished restoring purchases!");
    }
  };

  // send a restore event
  this.restorePurchases = function () {
    this.log("restoring purchases");
    billing.restore(bind(this, this.onRestore));
  };

  // send all the purchases to the store for localization
  this.localizePurchases = function () {
    this.log("localizing purchases");
    billing.getLocalizedPurchases(Object.keys(ITEMS));
  };

  // send giant list of purchases to the store for localization
  this.localizeManyPurchases = function () {
    this.log("localizing many purchases");
    billing.getLocalizedPurchases(Object.keys(MANY_ITEMS));
  };

  // helper function to wrap up all the demo logging
  this.log = function (text, success) {
    logger.log(text);
    this.logView.log(text, success);
  };

  // set the market status text
  this.setMarketStatus = function (status) {
    this.log("Market Status Updated: " + status);
    this.marketStatus.setText("Market Status: " + status);
  };

  // remove purchase handlers
  this.disablePurchaseHandlers = function () {
    billing.onPurchase = void 0;
    billing.onFailure = void 0;
  };

  // add purchase handlers
  this.enablePurchaseHandlers = function () {
    billing.onPurchase = bind(this, this.onPurchase);
    billing.onFailure = bind(this, this.onFailure)
  };

});
<|endoftext|>


<commit_before>// Underscore-contrib (underscore.array.builders.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Helpers
  // -------

  // Create quick reference variables for speed access to core prototypes.
  var slice   = Array.prototype.slice,
      concat  = Array.prototype.concat;

  var existy = function(x) { return x != null; };

  // Mixing in the array builders
  // ----------------------------

  _.mixin({
    // Concatenates one or more arrays given as arguments.  If given objects and
    // scalars as arguments `cat` will plop them down in place in the result
    // array.  If given an `arguments` object, `cat` will treat it like an array
    // and concatenate it likewise.
    cat: function() {
      return _.reduce(arguments, function(acc, elem) {
        if (_.isArguments(elem)) {
          return concat.call(acc, slice.call(elem));
        }
        else {
          return concat.call(acc, elem);
        }
      }, []);
    },

    // 'Constructs' an array by putting an element at its front
    cons: function(head, tail) {
      return _.cat([head], tail);
    },

    // Takes an array and chunks it some number of times into
    // sub-arrays of size n.  Allows and optional padding array as
    // the third argument to fill in the tail chunk when n is
    // not sufficient to build chunks of the same size.
    chunk: function(array, n, pad) {
      var p = function(array) {
        if (array == null) return [];

        var part = _.take(array, n);

        if (n === _.size(part)) {
          return _.cons(part, p(_.drop(array, n)));
        }
        else {
          return pad ? [_.take(_.cat(part, pad), n)] : [];
        }
      };

      return p(array);
    },

    // Takes an array and chunks it some number of times into
    // sub-arrays of size n.  If the array given cannot fill the size
    // needs of the final chunk then a smaller chunk is used
    // for the last.
    chunkAll: function(array, n, step) {
      step = (step != null) ? step : n;

      var p = function(array, n, step) {
        if (_.isEmpty(array)) return [];

        return _.cons(_.take(array, n),
                      p(_.drop(array, step), n, step));
      };

      return p(array, n, step);
    },

    // Maps a function over an array and concatenates all of the results.
    mapcat: function(array, fun) {
      return _.cat.apply(null, _.map(array, fun));
    },

    // Returns an array with some item between each element
    // of a given array.
    interpose: function(array, inter) {
      if (!_.isArray(array)) throw new TypeError;
      var sz = _.size(array);
      if (sz === 0) return array;
      if (sz === 1) return array;

      return slice.call(_.mapcat(array, function(elem) {
        return _.cons(elem, [inter]);
      }), 0, -1);
    },

    // Weaves two or more arrays together
    weave: function(/* args */) {
      if (!_.some(arguments)) return [];
      if (arguments.length == 1) return arguments[0];

      return _.filter(_.flatten(_.zip.apply(null, arguments), true), function(elem) {
        return elem != null;
      });
    },
    interleave: _.weave,

    // Returns an array of a value repeated a certain number of
    // times.
    repeat: function(t, elem) {
      return _.times(t, function() { return elem; });
    },

    // Returns an array built from the contents of a given array repeated
    // a certain number of times.
    cycle: function(t, elems) {
      return _.flatten(_.times(t, function() { return elems; }), true);
    },

    // Returns an array with two internal arrays built from
    // taking an original array and spliting it at an index.
    splitAt: function(array, index) {
      return [_.take(array, index), _.drop(array, index)];
    },

    // Call a function recursively f(f(f(args))) until a second
    // given function goes falsey.  Expects a seed value to start.
    iterateUntil: function(doit, checkit, seed) {
      var ret = [];
      var result = doit(seed);

      while (checkit(result)) {
        ret.push(result);
        result = doit(result);
      }

      return ret;
    },

    // Takes every nth item from an array, returning an array of
    // the results.
    takeSkipping: function(array, n) {
      var ret = [];
      var sz = _.size(array);

      if (n <= 0) return [];
      if (n === 1) return array;

      for(var index = 0; index < sz; index += n) {
        ret.push(array[index]);
      }

      return ret;
    },

    // Returns an array of each intermediate stage of a call to
    // a `reduce`-like function.
    reductions: function(array, fun, init) {
      var ret = [];
      var acc = init;

      _.each(array, function(v,k) {
        acc = fun(acc, array[k]);
        ret.push(acc);
      });

      return ret;
    },

    // Runs its given function on the index of the elements rather than
    // the elements themselves, keeping all of the truthy values in the end.
    keepIndexed: function(array, pred) {
      return _.filter(_.map(_.range(_.size(array)), function(i) {
        return pred(i, array[i]);
      }),
      existy);
    },

    // Accepts an array-like object (other than strings) as an argument and
    // returns an array whose elements are in the reverse order. Unlike the
    // built-in `Array.prototype.reverse` method, this does not mutate the
    // original object. Note: attempting to use this method on a string will
    // result in a `TypeError`, as it cannot properly reverse unicode strings.

    reverseOrder: function(obj) {
      if (typeof obj == 'string')
        throw new TypeError('Strings cannot be reversed by _.reverseOrder');
      return slice.call(obj).reverse();
    }
  });

})(this);
<commit_msg>Use shallow _.flatten in place of cat<commit_after>// Underscore-contrib (underscore.array.builders.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Helpers
  // -------

  // Create quick reference variables for speed access to core prototypes.
  var slice   = Array.prototype.slice;

  var existy = function(x) { return x != null; };

  // Mixing in the array builders
  // ----------------------------

  _.mixin({
    // Concatenates one or more arrays given as arguments.  If given objects and
    // scalars as arguments `cat` will plop them down in place in the result
    // array.  If given an `arguments` object, `cat` will treat it like an array
    // and concatenate it likewise.
    cat: function() {
      return _.flatten(arguments, true);
    },

    // 'Constructs' an array by putting an element at its front
    cons: function(head, tail) {
      return _.cat([head], tail);
    },

    // Takes an array and chunks it some number of times into
    // sub-arrays of size n.  Allows and optional padding array as
    // the third argument to fill in the tail chunk when n is
    // not sufficient to build chunks of the same size.
    chunk: function(array, n, pad) {
      var p = function(array) {
        if (array == null) return [];

        var part = _.take(array, n);

        if (n === _.size(part)) {
          return _.cons(part, p(_.drop(array, n)));
        }
        else {
          return pad ? [_.take(_.cat(part, pad), n)] : [];
        }
      };

      return p(array);
    },

    // Takes an array and chunks it some number of times into
    // sub-arrays of size n.  If the array given cannot fill the size
    // needs of the final chunk then a smaller chunk is used
    // for the last.
    chunkAll: function(array, n, step) {
      step = (step != null) ? step : n;

      var p = function(array, n, step) {
        if (_.isEmpty(array)) return [];

        return _.cons(_.take(array, n),
                      p(_.drop(array, step), n, step));
      };

      return p(array, n, step);
    },

    // Maps a function over an array and concatenates all of the results.
    mapcat: function(array, fun) {
      return _.flatten(_.map(array, fun), true);
    },

    // Returns an array with some item between each element
    // of a given array.
    interpose: function(array, inter) {
      if (!_.isArray(array)) throw new TypeError;
      var sz = _.size(array);
      if (sz === 0) return array;
      if (sz === 1) return array;

      return slice.call(_.mapcat(array, function(elem) {
        return _.cons(elem, [inter]);
      }), 0, -1);
    },

    // Weaves two or more arrays together
    weave: function(/* args */) {
      if (!_.some(arguments)) return [];
      if (arguments.length == 1) return arguments[0];

      return _.filter(_.flatten(_.zip.apply(null, arguments), true), function(elem) {
        return elem != null;
      });
    },
    interleave: _.weave,

    // Returns an array of a value repeated a certain number of
    // times.
    repeat: function(t, elem) {
      return _.times(t, function() { return elem; });
    },

    // Returns an array built from the contents of a given array repeated
    // a certain number of times.
    cycle: function(t, elems) {
      return _.flatten(_.times(t, function() { return elems; }), true);
    },

    // Returns an array with two internal arrays built from
    // taking an original array and spliting it at an index.
    splitAt: function(array, index) {
      return [_.take(array, index), _.drop(array, index)];
    },

    // Call a function recursively f(f(f(args))) until a second
    // given function goes falsey.  Expects a seed value to start.
    iterateUntil: function(doit, checkit, seed) {
      var ret = [];
      var result = doit(seed);

      while (checkit(result)) {
        ret.push(result);
        result = doit(result);
      }

      return ret;
    },

    // Takes every nth item from an array, returning an array of
    // the results.
    takeSkipping: function(array, n) {
      var ret = [];
      var sz = _.size(array);

      if (n <= 0) return [];
      if (n === 1) return array;

      for(var index = 0; index < sz; index += n) {
        ret.push(array[index]);
      }

      return ret;
    },

    // Returns an array of each intermediate stage of a call to
    // a `reduce`-like function.
    reductions: function(array, fun, init) {
      var ret = [];
      var acc = init;

      _.each(array, function(v,k) {
        acc = fun(acc, array[k]);
        ret.push(acc);
      });

      return ret;
    },

    // Runs its given function on the index of the elements rather than
    // the elements themselves, keeping all of the truthy values in the end.
    keepIndexed: function(array, pred) {
      return _.filter(_.map(_.range(_.size(array)), function(i) {
        return pred(i, array[i]);
      }),
      existy);
    },

    // Accepts an array-like object (other than strings) as an argument and
    // returns an array whose elements are in the reverse order. Unlike the
    // built-in `Array.prototype.reverse` method, this does not mutate the
    // original object. Note: attempting to use this method on a string will
    // result in a `TypeError`, as it cannot properly reverse unicode strings.

    reverseOrder: function(obj) {
      if (typeof obj == 'string')
        throw new TypeError('Strings cannot be reversed by _.reverseOrder');
      return slice.call(obj).reverse();
    }
  });

})(this);
<|endoftext|>


<commit_before>/// <reference path="../lib/jquery-2.1.1.min.js" />
/// <reference path="../lib/qunit-git.js" />
/// <reference path="../project/zen-query.js" />
/// <reference path="../tests/helpers.js" />

$Q.module('Utilities', {
    setup: function() {},
    teardown: function() {},
});

$Q.test('Validate Arguments', function (assert) {
    assert.throws(function () { $Z.validate(); }, 'Invalid Function Call', 'Error thrown when no arguments are passed');
    assert.throws(function () { $Z.validate(1); }, 'Invalid Function Call', 'Error thrown when less than 2 arguments is passed');
    assert.throws(function () { $Z.validate(1, 2, 3); }, 'Invalid Function Call', 'Error thrown when more than 2 arguments is passed');
    assert.throws(function () { $Z.validate(1, 2); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate([1], 2); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate(1, [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate([1], [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate($H.arguments(1), [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate($H.arguments(1,2), [2]); }, 'Invalid Function Call', 'Error thrown when length of arguments is not equal to length of types');
    assert.ok($Z.validate($H.arguments(1), ['number']), 'Number identified correctly');
    assert.ok($Z.validate($H.arguments('string'), ['string']), 'String identified correctly');
    assert.ok($Z.validate($H.arguments({}), ['object']), 'Object identified correctly');
    assert.ok($Z.validate($H.arguments([]), ['array']), 'Array identified correctly');
    assert.ok($Z.validate($H.arguments(1, {}), ['number', 'object']), 'Works for more than 1 argument');
});

$Q.module('Single Element Extractors', {
    setup: function() {
        window.classes = $H.classes;
        window.attributes = $H.attributes;
        window.elements = $H.elements;
    },
    teardown: function() {
        delete window.classes;
        delete window.attributes;
        delete window.elements;
    }
});

$Q.test('Classes', function (assert) {
    for (var i in classes)
        assert.deepEqual($Z.classes(i), classes[i], 'Classes in \'' + i + '\' are \'' + classes[i] + '\'');
});
$Q.test('Attributes', function (assert) {
    for (var i in attributes)
        assert.deepEqual($Z.attributes(i), attributes[i], 'Attributes in \'' + i + '\' are \'' + JSON.stringify(attributes[i]) + '\'');
});
$Q.test('Elements', function (assert) {
    for (var i in elements)
        assert.deepEqual($Z.element(i), elements[i], 'Elements in \'' + i + '\' retreived successfully as ' + JSON.stringify(elements[i]));
});<commit_msg>Added More Unit Tests<commit_after>/// <reference path="../lib/jquery-2.1.1.min.js" />
/// <reference path="../lib/qunit-git.js" />
/// <reference path="../project/zen-query.js" />
/// <reference path="../tests/helpers.js" />

$Q.module('Utilities', {
    setup: function() {
        window.types = $H.types;
        window.obj = $H.obj;
        window.arr = $H.arr;
    },
    teardown: function() {
        delete window.types;
        delete window.obj;
        delete window.arr;
    },
});

$Q.test('Object Type', function(assert) {
    for (var i in types)
        assert.ok($Z.objectType(types[i]) === i, i + ' identified correctly');
});
$Q.test('Is', function(assert) {
    for (var i in types)
        assert.ok($Z.is(i, types[i]) === true, 'typeof ' + JSON.stringify(types[i]) + ' identified correctly as ' + i);
});
$Q.test('Has', function(assert) {
    assert.ok($Z.has('key', obj) === true, 'Matches for Object');
    assert.ok($Z.has('key-two', obj) === true, 'Matches for Object');
    assert.ok($Z.has('key-three', obj) === false, 'Returns false for bad key of Object');
    assert.ok($Z.has('1', arr) === true, 'Matches for Array - String Index');
    assert.ok($Z.has('0', arr) === true, 'Matches for Array');
    assert.ok($Z.has(1, arr) === true, 'Matches for Array - Numeric Index');
    assert.ok($Z.has(0, arr) === true, 'Matches for Array');
    assert.ok($Z.has(2, arr) === false, 'Returns false for bad key of Array');
    assert.ok($Z.has('key', arr) === true, 'Matches for Array');
    assert.ok($Z.has('key-three', arr) === false, 'Returns false for bad key of Array');
});
$Q.test('Validate Arguments', function (assert) {
    assert.throws(function () { $Z.validate(); }, 'Invalid Function Call', 'Error thrown when no arguments are passed');
    assert.throws(function () { $Z.validate(1); }, 'Invalid Function Call', 'Error thrown when less than 2 arguments is passed');
    assert.throws(function () { $Z.validate(1, 2, 3); }, 'Invalid Function Call', 'Error thrown when more than 2 arguments is passed');
    assert.throws(function () { $Z.validate(1, 2); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate([1], 2); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate(1, [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate([1], [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate($H.arguments(1), [2]); }, 'Invalid Function Call', 'Error thrown when 2 arguments of invalid type are passed');
    assert.throws(function () { $Z.validate($H.arguments(1,2), [2]); }, 'Invalid Function Call', 'Error thrown when length of arguments is not equal to length of types');
    assert.ok($Z.validate($H.arguments(1), ['number']), 'Number identified correctly');
    assert.ok($Z.validate($H.arguments('string'), ['string']), 'String identified correctly');
    assert.ok($Z.validate($H.arguments({}), ['object']), 'Object identified correctly');
    assert.ok($Z.validate($H.arguments([]), ['array']), 'Array identified correctly');
    assert.ok($Z.validate($H.arguments(1, {}), ['number', 'object']), 'Works for more than 1 argument');
});
$Q.test('Trim', function(assert) {
    assert.expect(0);
});
$Q.test('Nullify', function (assert) {
    assert.expect(0);
});
$Q.test('Random', function (assert) {
    assert.expect(0);
});
$Q.test('Extend', function (assert) {
    assert.expect(0);
});

$Q.module('Single Element Extractors', {
    setup: function() {
        window.classes = $H.classes;
        window.attributes = $H.attributes;
        window.elements = $H.elements;
    },
    teardown: function() {
        delete window.classes;
        delete window.attributes;
        delete window.elements;
    }
});

$Q.test('Classes', function (assert) {
    for (var i in classes)
        assert.deepEqual($Z.classes(i), classes[i], 'Classes in \'' + i + '\' are \'' + classes[i] + '\'');
});
$Q.test('Attributes', function (assert) {
    for (var i in attributes)
        assert.deepEqual($Z.attributes(i), attributes[i], 'Attributes in \'' + i + '\' are \'' + JSON.stringify(attributes[i]) + '\'');
});
$Q.test('Elements', function (assert) {
    for (var i in elements)
        assert.deepEqual($Z.element(i), elements[i], 'Elements in \'' + i + '\' retreived successfully as ' + JSON.stringify(elements[i]));
});<|endoftext|>