<commit_before>var assert = require('assert');
var windows = require('../windows');

module.exports = inject;

var QUICK_BAR_COUNT = 9;
var QUICK_BAR_START = 36;

var armorSlots = {
  head: 5,
  torso: 6,
  legs: 7,
  feet: 8
};

function noop(err) {
  if(err) throw err;
}

function inject(bot) {
  var nextQuickBarSlot = 0;

  function tossStack(item, cb) {
    cb = cb || noop;
    assert.ok(item);
    bot.clickWindow(item.slot, 0, 0, function(err) {
      if(err) return cb(err);
      bot.clickWindow(-999, 0, 0, cb);
      bot.closeWindow(bot.currentWindow || bot.inventory);
    });
  }

  function toss(itemType, metadata, count, cb) {
    var window = bot.currentWindow || bot.inventory;
    var options = {
      window: window,
      itemType: itemType,
      metadata: metadata,
      count: count,
      sourceStart: window.inventorySlotStart,
      sourceEnd: window.inventorySlotStart + windows.INVENTORY_SLOT_COUNT,
      destStart: -999
    };
    bot.transfer(options, cb);
  }

  function unequip(destination, cb) {
    cb = cb || noop;
    if(destination === 'hand') {
      equipEmpty(cb);
    } else {
      disrobe(destination, cb);
    }
  }

  function setQuickBarSlot(slot) {
    assert.ok(slot >= 0);
    assert.ok(slot < 9);
    if(bot.quickBarSlot === slot) return;
    bot.quickBarSlot = slot;
    bot._client.write('held_item_slot', {
      slotId: slot
    });
    bot.updateHeldItem();
  }

  function equipEmpty(cb) {
    for(var i = 0; i < 9; ++i) {
      if(!bot.inventory.slots[QUICK_BAR_START + i]) {
        setQuickBarSlot(i);
        process.nextTick(cb);
        return;
      }
    }
    var slot = bot.inventory.firstEmptyInventorySlot();
    if(!slot) {
      bot.tossStack(bot.heldItem, cb);
      return;
    }
    var equipSlot = QUICK_BAR_START + bot.quickBarSlot;
    bot.clickWindow(equipSlot, 0, 0, function(err) {
      if(err) return cb(err);
      bot.clickWindow(slot, 0, 0, function(err) {
        if(err) return cb(err);
        if(bot.inventory.selectedItem) {
          bot.clickWindow(-999, 0, 0, cb);
        } else {
          cb();
        }
      });
    });
  }

  function disrobe(destination, cb) {
    assert.equal(bot.currentWindow, null);
    var destSlot = getDestSlot(destination);
    bot.putAway(destSlot, cb);
  }

  function equip(item, destination, cb) {
    cb = cb || noop;
    if(typeof item === 'number') {
      item = bot.inventory.findInventoryItem(item);
    }
    if(item == null || typeof item !== 'object') {
      return cb(new Error('Invalid item object in equip'));
    }
    var sourceSlot = item.slot;
    var destSlot = getDestSlot(destination);

    if(sourceSlot === destSlot) {
      // don't need to do anything
      process.nextTick(cb);
      return;
    }

    if(destSlot >= QUICK_BAR_START && sourceSlot >= QUICK_BAR_START) {
      // all we have to do is change the quick bar selection
      bot.setQuickBarSlot(sourceSlot - QUICK_BAR_START);
      process.nextTick(cb);
      return;
    }

    if(destination !== 'hand') {
      bot.moveSlotItem(sourceSlot, destSlot, cb);
      return;
    }

    // find an empty slot on the quick bar to put the source item in
    destSlot = bot.inventory.firstEmptySlotRange(QUICK_BAR_START, QUICK_BAR_START + QUICK_BAR_COUNT);
    if(destSlot == null) {
      // LRU cache for the quick bar items
      destSlot = QUICK_BAR_START + nextQuickBarSlot;
      nextQuickBarSlot = (nextQuickBarSlot + 1) % QUICK_BAR_COUNT;
    }
    setQuickBarSlot(destSlot - QUICK_BAR_START);
    bot.moveSlotItem(sourceSlot, destSlot, cb);
  }

  function getDestSlot(destination) {
    if(!destination || destination === 'hand') {
      return QUICK_BAR_START + bot.quickBarSlot;
    } else {
      var destSlot = armorSlots[destination];
      assert.ok(destSlot != null, "invalid destination: " + destination);
      return destSlot;
    }
  }

  bot.equip = equip;
  bot.unequip = unequip;
  bot.toss = toss;
  bot.tossStack = tossStack;
  bot.setQuickBarSlot = setQuickBarSlot;

  // constants
  bot.QUICK_BAR_START = QUICK_BAR_START;

}<commit_msg>the destination of unequip is not optional, produce an error if not given<commit_after>var assert = require('assert');
var windows = require('../windows');

module.exports = inject;

var QUICK_BAR_COUNT = 9;
var QUICK_BAR_START = 36;

var armorSlots = {
  head: 5,
  torso: 6,
  legs: 7,
  feet: 8
};

function noop(err) {
  if(err) throw err;
}

function inject(bot) {
  var nextQuickBarSlot = 0;

  function tossStack(item, cb) {
    cb = cb || noop;
    assert.ok(item);
    bot.clickWindow(item.slot, 0, 0, function(err) {
      if(err) return cb(err);
      bot.clickWindow(-999, 0, 0, cb);
      bot.closeWindow(bot.currentWindow || bot.inventory);
    });
  }

  function toss(itemType, metadata, count, cb) {
    var window = bot.currentWindow || bot.inventory;
    var options = {
      window: window,
      itemType: itemType,
      metadata: metadata,
      count: count,
      sourceStart: window.inventorySlotStart,
      sourceEnd: window.inventorySlotStart + windows.INVENTORY_SLOT_COUNT,
      destStart: -999
    };
    bot.transfer(options, cb);
  }

  function unequip(destination, cb) {
    cb = cb || noop;
    if(destination === 'hand') {
      equipEmpty(cb);
    } else {
      disrobe(destination, cb);
    }
  }

  function setQuickBarSlot(slot) {
    assert.ok(slot >= 0);
    assert.ok(slot < 9);
    if(bot.quickBarSlot === slot) return;
    bot.quickBarSlot = slot;
    bot._client.write('held_item_slot', {
      slotId: slot
    });
    bot.updateHeldItem();
  }

  function equipEmpty(cb) {
    for(var i = 0; i < 9; ++i) {
      if(!bot.inventory.slots[QUICK_BAR_START + i]) {
        setQuickBarSlot(i);
        process.nextTick(cb);
        return;
      }
    }
    var slot = bot.inventory.firstEmptyInventorySlot();
    if(!slot) {
      bot.tossStack(bot.heldItem, cb);
      return;
    }
    var equipSlot = QUICK_BAR_START + bot.quickBarSlot;
    bot.clickWindow(equipSlot, 0, 0, function(err) {
      if(err) return cb(err);
      bot.clickWindow(slot, 0, 0, function(err) {
        if(err) return cb(err);
        if(bot.inventory.selectedItem) {
          bot.clickWindow(-999, 0, 0, cb);
        } else {
          cb();
        }
      });
    });
  }

  function disrobe(destination, cb) {
    assert.equal(bot.currentWindow, null);
    var destSlot = getDestSlot(destination);
    bot.putAway(destSlot, cb);
  }

  function equip(item, destination, cb) {
    cb = cb || noop;
    if(typeof item === 'number') {
      item = bot.inventory.findInventoryItem(item);
    }
    if(item == null || typeof item !== 'object') {
      return cb(new Error('Invalid item object in equip'));
    }
    var sourceSlot = item.slot;
    var destSlot = getDestSlot(destination);

    if(sourceSlot === destSlot) {
      // don't need to do anything
      process.nextTick(cb);
      return;
    }

    if(destSlot >= QUICK_BAR_START && sourceSlot >= QUICK_BAR_START) {
      // all we have to do is change the quick bar selection
      bot.setQuickBarSlot(sourceSlot - QUICK_BAR_START);
      process.nextTick(cb);
      return;
    }

    if(destination !== 'hand') {
      bot.moveSlotItem(sourceSlot, destSlot, cb);
      return;
    }

    // find an empty slot on the quick bar to put the source item in
    destSlot = bot.inventory.firstEmptySlotRange(QUICK_BAR_START, QUICK_BAR_START + QUICK_BAR_COUNT);
    if(destSlot == null) {
      // LRU cache for the quick bar items
      destSlot = QUICK_BAR_START + nextQuickBarSlot;
      nextQuickBarSlot = (nextQuickBarSlot + 1) % QUICK_BAR_COUNT;
    }
    setQuickBarSlot(destSlot - QUICK_BAR_START);
    bot.moveSlotItem(sourceSlot, destSlot, cb);
  }

  function getDestSlot(destination) {
    if(destination === 'hand') {
      return QUICK_BAR_START + bot.quickBarSlot;
    } else {
      var destSlot = armorSlots[destination];
      assert.ok(destSlot != null, "invalid destination: " + destination);
      return destSlot;
    }
  }

  bot.equip = equip;
  bot.unequip = unequip;
  bot.toss = toss;
  bot.tossStack = tossStack;
  bot.setQuickBarSlot = setQuickBarSlot;

  // constants
  bot.QUICK_BAR_START = QUICK_BAR_START;

}<|endoftext|>


<commit_before>var CLIENT_ID = '227617601741-e4ed1r83v5cpheaakcn411gk1h5t0gam.apps.googleusercontent.com';
var SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];

function checkAuth() {
	gapi.auth.authorize({
		'client_id': CLIENT_ID,
		'scope': SCOPES.join(' '),
		'immediate': true
	}, handleAuthResult);
}

function handleAuthResult(authResult) {
	var authorizeDiv = document.getElementById('authorize-div');
	if (authResult && !authResult.error) {
		authorizeDiv.style.display = 'none';
		loadCalendarApi();
	} else {
		authorizeDiv.style.display = 'inline';
	}
}

function handleAuthClick(event) {
	gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false
	}, handleAuthResult);
	return false;
}

function loadCalendarApi() {
	gapi.client.load('calendar', 'v3', listUpcomingEvents);
}

function listUpcomingEvents() {
	$('#events').html('Loading Calendar');
	var request = gapi.client.calendar.events.list({
		'calendarId': 'primary',
		'timeMin': (new Date()).toISOString(),
		'showDeleted': false,
		'singleEvents': true,
		'maxResults': 9,
		'orderBy': 'startTime'
	});

	request.execute(function(resp) {
		var events = resp.items;
		$('#title').html('Upcoming events');

		if (events.length > 0) {
			for (i = 0; i < events.length; i++) {
				var event = events[i];
				var when = event.start.dateTime;
				if (!when) {
					when = event.start;
				}
				addEvent(event, when, !(((when+"").indexOf("T") > -1)));
			}
		} else {
			$('#title').html('No upcoming events found');
		}
	});
}

function checkTime(i) {
	if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
	return i;
}

function addEvent(calendarEvent, date, allday) {
	var content = calendarEvent.summary;

	var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
	var firstDate = new Date();
	var secondDate = new Date(date);
	if (!(secondDate instanceof Date) || secondDate == "Invalid Date") {
		var parts = date.date.split("-");
		secondDate = new Date(parts[0], parts[1] - 1, parts[2]);
	}
	var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime()) / (oneDay)));
	var contentDays = diffDays + " days to go";

	if (diffDays == 1) contentDays = diffDays + " day to go";
	if (allday) {
		if (firstDate.getDate() == secondDate.getDate() && firstDate.getMonth() == secondDate.getMonth()) {
			contentDays = "today";
		}
	}
	if (diffDays == 0) {
		if (allday) contentDays = "today";
		else contentDays = "today at " + checkTime(secondDate.getHours()) + ":" +  checkTime(secondDate.getMinutes());
	}

	$('#events').append('' + content + '' + contentDays + '');
}
<commit_msg>working fixing cal<commit_after>var CLIENT_ID = '227617601741-e4ed1r83v5cpheaakcn411gk1h5t0gam.apps.googleusercontent.com';
var SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];

function checkAuth() {
	gapi.auth.authorize({
		'client_id': CLIENT_ID,
		'scope': SCOPES.join(' '),
		'immediate': true
	}, handleAuthResult);
}

function handleAuthResult(authResult) {
	var authorizeDiv = document.getElementById('authorize-div');
	if (authResult && !authResult.error) {
		authorizeDiv.style.display = 'none';
		loadCalendarApi();
	} else {
		authorizeDiv.style.display = 'inline';
	}
}

function handleAuthClick(event) {
	gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false
	}, handleAuthResult);
	return false;
}

function loadCalendarApi() {
	gapi.client.load('calendar', 'v3', listUpcomingEvents);
}

function listUpcomingEvents() {
	$('#events').html('Loading Calendar');
	var request = gapi.client.calendar.events.list({
		'calendarId': 'primary',
		'timeMin': (new Date()).toISOString(),
		'showDeleted': false,
		'singleEvents': true,
		'maxResults': 9,
		'orderBy': 'startTime'
	});

	request.execute(function(resp) {
		var events = resp.items;
		$('#title').html('Upcoming events');

		if (events.length > 0) {
			for (i = 0; i < events.length; i++) {
				var event = events[i];
				var when = event.start.dateTime;
				if (!when) {
					when = event.start;
				}
				addEvent(event, when, !(((when+"").indexOf("T") > -1)));
			}
		} else {
			$('#title').html('No upcoming events found');
		}
	});
}

function checkTime(i) {
	if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
	return i;
}

function addEvent(calendarEvent, date, allday) {
	var content = calendarEvent.summary;

	var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
	var firstDate = new Date();
	var secondDate = new Date(date);
	if (!(secondDate instanceof Date) || secondDate == "Invalid Date") {
		var parts = date.date.split("-");
		secondDate = new Date(parts[0], parts[1] - 1, parts[2]);
	}
	var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime()) / (oneDay)));
	var contentDays = diffDays + " days to go";

	if (diffDays == 1) contentDays = "tomorrow";
	if (allday) {
		if (firstDate.getDate() == secondDate.getDate() && firstDate.getMonth() == secondDate.getMonth()) {
			contentDays = "today";
		}
	}
	if (diffDays == 0) {
		if (allday) contentDays = "today";
		else contentDays = "today at " + checkTime(secondDate.getHours()) + ":" +  checkTime(secondDate.getMinutes());
	}

	$('#events').append('' + content + '' + contentDays + '');
}
<|endoftext|>


<commit_before>// Copyright 2012 Mark Cavage.  All rights reserved.

var Writable = require('stream').Writable;
var util = require('util');

var assert = require('assert-plus');
var crc = require('crc');
var microtime = require('microtime');
var WError = require('verror').WError;

var proto = require('./protocol');

///--- Errors

function ChecksumError(exp, actual, msg) {
        WError.call(this, {}, 'checksum error(%d): caclulated %d', exp, actual);

        this.context = {
                expected_crc: exp,
                actual_crc: actual,
                message: msg
        };
        this.name = this.constructor.name;
}
util.inherits(ChecksumError, WError);

function InvalidContentError(cause, msg) {
        WError.call(this, cause, 'invalid JSON encountered');

        this.context = {
                message: msg
        };
        this.name = this.constructor.name;
}
util.inherits(InvalidContentError, WError);

///--- Internal Functions

function parseBuffer(buf, msg) {
        assert.object(buf, 'buffer');
        assert.object(msg, 'message');

        if (buf.length < proto.HEADER_LEN)
                return (false);

        msg._offset = msg._offset || 0;
        if (msg._offset === 0) {
                msg.version = buf.readUInt8(msg._offset++, true);
                msg.type = buf.readUInt8(msg._offset++, true);
                msg.status = buf.readUInt8(msg._offset++, true);
                msg.msgid = buf.readUInt32BE(msg._offset, true);
                msg._offset += 4;
                msg.checksum = buf.readInt32BE(msg._offset, true);
                msg._offset += 4;
                msg.length = buf.readUInt32BE(msg._offset, true);
                msg._offset += 4;
        }

        var remain = msg._offset + msg.length;
        if (buf.length < remain)
                return (false);

        msg.data = buf.slice(msg._offset, remain).toString('utf8');
        msg._offset += msg.length;
        return (true);
}

///--- API

function MessageDecoder() {
        Writable.call(this);

        this._buf = null;
        this._msg = null;
}
util.inherits(MessageDecoder, Writable);

MessageDecoder.prototype._write = function _write(buf, encoding, cb) {
        var checksum;
        var msg;
        var self = this;

        if (this._buf) {
                // Wed Underrun data on a previous call
                var len = this._buf.length + buf.length;
                buf = Buffer.concat([this._buf, buf], len);
        }

        assert.ok(Buffer.isBuffer(buf));
        msg = this._msg || {};

        while (buf.length > 0) {
                if (!parseBuffer(buf, msg)) {
                        this._buf = buf;
                        this._msg = msg;
                        cb();
                        return;
                }

                checksum = crc.crc16(msg.data);
                if (msg.checksum !== checksum) {
                        var e = new ChecksumError(msg.checksum, checksum, msg);
                        self.emit('error', e);
                }

                try {
                        msg.data = JSON.parse(msg.data);
                } catch (e) {
                        self.emit('error', new InvalidContentError(e));
                }

                msg.start = microtime.now();
                this.emit('message', msg);

                buf = buf.slice(msg._offset);
                msg = {};
        }
        cb();
};

///--- Exports

module.exports = {

        MessageDecoder: MessageDecoder,

        createMessageDecoder: function createMessageDecoder() {
                return (new MessageDecoder());
        }

};
<commit_msg>reset placeholder vars<commit_after>// Copyright 2012 Mark Cavage.  All rights reserved.

var Writable = require('stream').Writable;
var util = require('util');

var assert = require('assert-plus');
var crc = require('crc');
var microtime = require('microtime');
var WError = require('verror').WError;

var proto = require('./protocol');

///--- Errors

function ChecksumError(exp, actual, msg) {
        WError.call(this, {}, 'checksum error(%d): caclulated %d', exp, actual);

        this.context = {
                expected_crc: exp,
                actual_crc: actual,
                message: msg
        };
        this.name = this.constructor.name;
}
util.inherits(ChecksumError, WError);

function InvalidContentError(cause, msg) {
        WError.call(this, cause, 'invalid JSON encountered');

        this.context = {
                message: msg
        };
        this.name = this.constructor.name;
}
util.inherits(InvalidContentError, WError);

///--- Internal Functions

function parseBuffer(buf, msg) {
        assert.object(buf, 'buffer');
        assert.object(msg, 'message');

        if (buf.length < proto.HEADER_LEN)
                return (false);

        msg._offset = msg._offset || 0;
        if (msg._offset === 0) {
                msg.version = buf.readUInt8(msg._offset++, true);
                msg.type = buf.readUInt8(msg._offset++, true);
                msg.status = buf.readUInt8(msg._offset++, true);
                msg.msgid = buf.readUInt32BE(msg._offset, true);
                msg._offset += 4;
                msg.checksum = buf.readInt32BE(msg._offset, true);
                msg._offset += 4;
                msg.length = buf.readUInt32BE(msg._offset, true);
                msg._offset += 4;
        }

        var remain = msg._offset + msg.length;
        if (buf.length < remain)
                return (false);

        msg.data = buf.slice(msg._offset, remain).toString('utf8');
        msg._offset += msg.length;
        return (true);
}

///--- API

function MessageDecoder() {
        Writable.call(this);

        this._buf = null;
        this._msg = null;
}
util.inherits(MessageDecoder, Writable);

MessageDecoder.prototype._write = function _write(buf, encoding, cb) {
        var checksum;
        var msg;
        var self = this;

        if (this._buf) {
                // Wed Underrun data on a previous call
                var len = this._buf.length + buf.length;
                buf = Buffer.concat([this._buf, buf], len);
        }

        assert.ok(Buffer.isBuffer(buf));
        msg = this._msg || {};

        while (buf.length > 0) {
                if (!parseBuffer(buf, msg)) {
                        this._buf = buf;
                        this._msg = msg;
                        cb();
                        return;
                }

                checksum = crc.crc16(msg.data);
                if (msg.checksum !== checksum) {
                        var e = new ChecksumError(msg.checksum, checksum, msg);
                        self.emit('error', e);
                }

                try {
                        msg.data = JSON.parse(msg.data);
                } catch (e) {
                        self.emit('error', new InvalidContentError(e));
                }

                msg.start = microtime.now();
                this.emit('message', msg);

                buf = buf.slice(msg._offset);
                msg = {};
        }

	this._buf = null;
	this._msg = null;
        cb();
};

///--- Exports

module.exports = {

        MessageDecoder: MessageDecoder,

        createMessageDecoder: function createMessageDecoder() {
                return (new MessageDecoder());
        }

};
<|endoftext|>


<commit_before>/**
 * Created by tsxuehu on 17/1/4.
 */
var config = {

    "bem": {
        "shortcuts": {"component": "b", "modifier": "m", "descendent": "e"},
        "separators": {"descendent": "__", "modifier": "--"}
    }/*,
    "autoprefixer": {"browsers": ["ie > 8", "last 2 versions"]},
    "rem": {"browsers": ["ie > 8", "last 2 versions"]}*/
};
// https://github.com/trysound/postcss-easy-import
var partialImport = require("postcss-easy-import")();

// 这不是bem，虽然名字叫bem，其实它是suit
// https://github.com/saladcss/saladcss-bem
var bem = require("saladcss-bem")(config.bem);

// https://github.com/jonathantneal/precss
var precss = require("precss")();

// https://github.com/postcss/autoprefixer
var autoprefixer = require("autoprefixer")();

module.exports = function (webpack) {
  // 顺序很重要
  return [
    partialImport,
    bem,
    precss,
    autoprefixer
  ];
};
<commit_msg>remove unused postcss plugins<commit_after>var config = {
    'bem': {
        'shortcuts': {'component': 'b', 'modifier': 'm', 'descendent': 'e'},
        'separators': {'descendent': '__', 'modifier': '--'}
    }
};
// https://github.com/trysound/postcss-easy-import
var partialImport = require("postcss-easy-import")();

// 这不是bem，虽然名字叫bem，其实它是suit
// https://github.com/saladcss/saladcss-bem
var bem = require("saladcss-bem")(config.bem);

// https://github.com/jonathantneal/precss
var precss = require("precss")();

// https://github.com/postcss/autoprefixer
var autoprefixer = require("autoprefixer")();

module.exports = function (webpack) {
  // 顺序很重要
  return [
    partialImport,
    bem,
    precss,
    autoprefixer
  ];
};
<|endoftext|>


<commit_before>import applyProps from './applyProps.js';
import { assembleMetadata, removeLinkStorages, storeOneResults } from './prepareForDelivery';
import prepareForDelivery from './prepareForDelivery';
import {getNodeNamespace} from './createGraph';
import {isFieldInProjection} from '../lib/fieldInProjection';

/**
 * This is always run client side to build the data graph out of client-side collections.
 *
 * @param node
 * @param parentObject
 * @param fetchOptions
 * @returns {*}
 */
function fetch(node, parentObject, fetchOptions = {}) {
    let {filters, options} = applyProps(node);
    // add subscription filter
    if (fetchOptions.scoped && fetchOptions.subscriptionHandle) {
        _.extend(filters, fetchOptions.subscriptionHandle.scopeQuery());
    }
    // add query path filter
    if (fetchOptions.scoped) {
        _.extend(filters, {[`_query_path_${getNodeNamespace(node)}`]: {$exists: true}});
    }

    let results = [];

    if (parentObject) {
        let accessor = node.linker.createLink(parentObject, node.collection);

        if (node.isVirtual) {
            options.fields = options.fields || {};
            if (!isFieldInProjection(options.fields, node.linkStorageField, true)) {
                _.extend(options.fields, {
                    [node.linkStorageField]: 1
                });
            }
        }

        results = accessor.find(filters, options).fetch();
    } else {
        results = node.collection.find(filters, options).fetch();
    }

    _.each(node.collectionNodes, collectionNode => {
        _.each(results, result => {
            const collectionNodeResults = fetch(collectionNode, result);
            result[collectionNode.linkName] = collectionNodeResults;
            //delete result[node.linker.linkStorageField];

            /**
             * Push into the results, because snapBackCaches() in prepareForDelivery does not work otherwise.
             * This is non-optimal, can we be sure that every item in results contains _id and add only if not in
             * the results?
             *
             * Other possible ways:
             * - do something like assemble() in storeHypernovaResults
             * - pass node.results to accessor above and find with sift
             */

            collectionNode.results.push(...collectionNodeResults);

            // this was not working because all references must be replaced in snapBackCaches, not only the ones that are
            // found first
            // const currentIds = _.pluck(collectionNode.results, '_id');
            // collectionNode.results.push(...collectionNodeResults.filter(res => !_.contains(currentIds, res._id)));
        })
    });

    return results;
}

export default (node, params, fetchOptions) => {
    node.results = fetch(node, null, fetchOptions);

    prepareForDelivery(node, params);

    return node.results;
}
<commit_msg>Fix recursiveFetch to respect fetchOptions.scope on recursion<commit_after>import applyProps from './applyProps.js';
import { assembleMetadata, removeLinkStorages, storeOneResults } from './prepareForDelivery';
import prepareForDelivery from './prepareForDelivery';
import {getNodeNamespace} from './createGraph';
import {isFieldInProjection} from '../lib/fieldInProjection';

/**
 * This is always run client side to build the data graph out of client-side collections.
 *
 * @param node
 * @param parentObject
 * @param fetchOptions
 * @returns {*}
 */
function fetch(node, parentObject, fetchOptions = {}) {
    let {filters, options} = applyProps(node);
    // add subscription filter
    if (fetchOptions.scoped && fetchOptions.subscriptionHandle) {
        _.extend(filters, fetchOptions.subscriptionHandle.scopeQuery());
    }
    // add query path filter
    if (fetchOptions.scoped) {
        _.extend(filters, {[`_query_path_${getNodeNamespace(node)}`]: {$exists: true}});
    }

    let results = [];

    if (parentObject) {
        let accessor = node.linker.createLink(parentObject, node.collection);

        if (node.isVirtual) {
            options.fields = options.fields || {};
            if (!isFieldInProjection(options.fields, node.linkStorageField, true)) {
                _.extend(options.fields, {
                    [node.linkStorageField]: 1
                });
            }
        }

        results = accessor.find(filters, options).fetch();
    } else {
        results = node.collection.find(filters, options).fetch();
    }

    _.each(node.collectionNodes, collectionNode => {
        _.each(results, result => {
            const collectionNodeResults = fetch(collectionNode, result, fetchOptions);
            result[collectionNode.linkName] = collectionNodeResults;
            //delete result[node.linker.linkStorageField];

            /**
             * Push into the results, because snapBackCaches() in prepareForDelivery does not work otherwise.
             * This is non-optimal, can we be sure that every item in results contains _id and add only if not in
             * the results?
             *
             * Other possible ways:
             * - do something like assemble() in storeHypernovaResults
             * - pass node.results to accessor above and find with sift
             */

            collectionNode.results.push(...collectionNodeResults);

            // this was not working because all references must be replaced in snapBackCaches, not only the ones that are
            // found first
            // const currentIds = _.pluck(collectionNode.results, '_id');
            // collectionNode.results.push(...collectionNodeResults.filter(res => !_.contains(currentIds, res._id)));
        })
    });

    return results;
}

export default (node, params, fetchOptions) => {
    node.results = fetch(node, null, fetchOptions);

    prepareForDelivery(node, params);

    return node.results;
}
<|endoftext|>


<commit_before>/*
Plugin Name: amCharts Animate Data
Description: Smoothly animates the `dataProvider`
Author: Paul Chapman, amCharts
Version: 1.0.0
Author URI: http://www.amcharts.com/

Copyright 2015 amCharts

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Please note that the above license covers only this plugin. It by all means does
not apply to any other amCharts products that are covered by different licenses.
*/

/* globals AmCharts */
/* jshint -W061 */

( function() {
	"use strict";

	function raf( self ) {
		requestAnimationFrame( function( now ) {
			self._onFrame( now );
		} );
	}

	function noop( now ) {}

	function Animation( duration, start, tick, end ) {
		this._finished = false;
		this._startTime = null;
		this._duration = duration;
		this._start = ( start == null ? noop : start );
		this._tick = ( tick == null ? noop : tick );
		this._end = ( end == null ? noop : end );
	}

	Animation.prototype.cancel = function() {
		this._finished = true;
		this._startTime = null;
		this._duration = null;
		this._start = null;
		this._tick = null;
		this._end = null;
	};

	Animation.prototype._onFrame = function( now ) {
		// This will only happen when the animation was cancelled
		if ( this._finished ) {
			return true;

		} else if ( this._startTime === null ) {
			this._startTime = now;
			this._start( 0 );
			return false;

		} else {
			var diff = now - this._startTime;

			if ( diff < this._duration ) {
				this._tick( diff / this._duration );
				return false;

			} else {
				this._end( 1 );
				// Cleanup all the properties
				this.cancel();
				return true;
			}
		}
	};

	function Animator() {
		this._animating = false;
		this._animations = [];
		this._onBeforeFrames = [];
		this._onAfterFrames = [];
	}

	Animator.prototype.animate = function( options ) {
		var animation = new Animation(
			options.duration,
			options.start,
			options.tick,
			options.end
		);

		this._animations.push( animation );

		if ( !this._animating ) {
			this._animating = true;

			raf( this );
		}

		return animation;
	};

	Animator.prototype.onBeforeFrame = function( f ) {
		this._onBeforeFrames.push( f );
	};

	Animator.prototype.onAfterFrame = function( f ) {
		this._onAfterFrames.push( f );
	};

	Animator.prototype._onFrame = function( now ) {
		var onBeforeFrames = this._onBeforeFrames;

		for ( var i = 0; i < onBeforeFrames.length; ++i ) {
			onBeforeFrames[ i ]( now );
		}

		var animations = this._animations;

		for ( var i = 0; i < animations.length; ++i ) {
			var animation = animations[ i ];

			// If the animation is finished...
			if ( animation._onFrame( now ) ) {
				// TODO this is a bit slow, but I don't know of a faster alternative
				animations.splice( i, 1 );
				--i;
			}
		}

		var onAfterFrames = this._onAfterFrames;

		for ( var i = 0; i < onAfterFrames.length; ++i ) {
			onAfterFrames[ i ]( now );
		}

		// All animations are finished
		if ( animations.length === 0 ) {
			this._animating = false;

		} else {
			raf( this );
		}
	};

	var _animator = new Animator();

	AmCharts.animate = function( options ) {
		return _animator.animate( options );
	};

	AmCharts.tween = function( time, from, to ) {
		return ( time * ( to - from ) ) + from;
	};

	function easeInOut3( t ) {
		var r = ( t < 0.5 ? t * 2 : ( 1 - t ) * 2 );
		r *= r * r * r;
		return ( t < 0.5 ? r / 2 : 1 - ( r / 2 ) );
	}

	function easeIn3( t ) {
		t *= t * t * t;
		return t;
	}

	function easeOut3( t ) {
		var r = ( 1 - t );
		r *= r * r * r;
		return ( 1 - r );
	}

	var needsValidation = [];

	function isNaN( x ) {
		return x !== x;
	}

	function each( array, fn ) {
		var length = array.length;

		for ( var i = 0; i < length; ++i ) {
			fn( array[ i ] );
		}
	}

	// Super fast and memory efficient map
	function map( array, fn ) {
		var length = array.length;
		var output = new Array( length );

		for ( var i = 0; i < length; ++i ) {
			output[ i ] = fn( array[ i ] );
		}

		return output;
	}

	function pushNew( array, x ) {
		for ( var i = 0; i < array.length; ++i ) {
			if ( array[ i ] === x ) {
				return;
			}
		}

		array.push( x );
	}

	// TODO check the performance of this
	_animator.onAfterFrame( function() {
		for ( var i = 0; i < needsValidation.length; ++i ) {
			needsValidation[ i ].validateData();
		}

		needsValidation.length = 0;
	} );

	// This ensures that a key is only added once
	function addKey( keys, seen, key ) {
		if ( !seen[ key ] ) {
			seen[ key ] = true;
			keys.push( key );
		}
	}

	function addKeys( keys, seen, object, a ) {
		each( a, function( key ) {
			var value = object[ key ];

			if ( value != null ) {
				addKey( keys, seen, value );
			}
		} );
	}

	function getKeysSliced( chart, keys, seen ) {
		addKeys( keys, seen, chart, [
			"alphaField",
			"valueField"
		] );
	}

	function getKeysFunnel( chart, keys, seen ) {
		getKeysSliced( chart, keys, seen );
	}

	function getKeysPie( chart, keys, seen ) {
		getKeysSliced( chart, keys, seen );

		addKeys( keys, seen, chart, [
			"labelRadiusField"
		] );
	}

	// TODO this is wrong
	function getKeysGantt( chart, keys, seen ) {
		// TODO is this correct ?
		getKeysCategoryAxis( chart.categoryAxis, keys, seen );
		// TODO is this correct ?
		getKeysGraphs( chart.graphs, keys, seen );

		addKeys( keys, seen, chart, [
			"columnWidthField",
			"durationField",
			"endField",
			"startField"
		] );
	}

	function getKeysGraphs( graphs, keys, seen ) {
		each( graphs, function( graph ) {
			addKeys( keys, seen, graph, [
				"alphaField",
				"bulletSizeField",
				"closeField",
				"dashLengthField",
				"errorField",
				"highField",
				"lowField",
				"openField",
				"valueField"
			] );
		} );
	}

	function getKeysCategoryAxis( categoryAxis, keys, seen ) {
		addKeys( keys, seen, categoryAxis, [
			"widthField"
		] );
	}

	// Returns an array of all of the animatable keys
	function getKeys( chart ) {
		var keys = [];

		var seen = {};

		if ( chart.type === "funnel" ) {
			getKeysFunnel( chart, keys, seen );

		} else if ( chart.type === "pie" ) {
			getKeysPie( chart, keys, seen );

		// TODO this is wrong
		} else if ( chart.type === "gantt" ) {
			getKeysGantt( chart, keys, seen );

		} else if ( chart.type === "serial" ) {
			getKeysCategoryAxis( chart.categoryAxis, keys, seen );
			getKeysGraphs( chart.graphs, keys, seen );

		} else if ( chart.type === "radar" ) {
			getKeysGraphs( chart.graphs, keys, seen );

		// TODO support for this
		} else if ( chart.type === "gauge" ) {

		}

		return keys;
	}

	// TODO what about gantt charts ?
	function getCategoryField( chart ) {
		if ( chart.type === "funnel" || chart.type === "pie" ) {
			return chart.titleField;

		} else if ( chart.type === "serial" || chart.type === "radar" ) {
			return chart.categoryField;

		// TODO support for this
		} else if ( chart.type === "gauge" ) {

		}
	}

	function getValue( value ) {
		if ( value == null ) {
			return null;

		} else {
			value = +value;

			// TODO test this
			// TODO what about Infinity, etc. ?
			if ( isNaN( value ) ) {
				return null;

			} else {
				return value;
			}
		}
	}

	function getValues( data, keys ) {
		return map( keys, function( key ) {
			return getValue( data[ key ] );
		} );
	}

	function getString( value ) {
		// TODO better algorithm for this ?
		return JSON.stringify( value );
	}

	function animateData( dataProvider, options ) {
		var chart = this;

		var easing = options.easing || easeOut3;

		var categoryField = getCategoryField( chart );
		var keys = getKeys( chart );

		var categories = {};
		var values = [];

		each( chart.dataProvider, function( data ) {
			// TODO handle data which doesn't have a category
			var category = getString( data[ categoryField ] );

			categories[ category ] = data;
		} );

		each( dataProvider, function( data ) {
			// TODO handle data which doesn't have a category
			var category = getString( data[ categoryField ] );

			// If the new data has the same category as the old data...
			if ( category in categories ) {
				var oldValues = getValues( categories[ category ], keys );
				var newValues = getValues( data, keys );

				// TODO maybe use a class rather than an object literal ?
				values.push( {
					oldValues: oldValues,
					newValues: newValues,
					data: data
				} );
			}
		} );

		chart.dataProvider = dataProvider;

		function tick( time ) {
			// Apply the easing to the time ratio
			time = easing( time );

			for ( var i = 0; i < values.length; ++i ) {
				var info = values[ i ];
				var oldValues = info.oldValues;
				var newValues = info.newValues;
				var data = info.data;

				for ( var j = 0; j < keys.length; ++j ) {
					var key = keys[ j ];
					var oldValue = oldValues[ j ];
					var newValue = newValues[ j ];

					if ( oldValue != null && newValue != null ) {
						data[ key ] = AmCharts.tween( time, oldValue, newValue );
					}
				}
			}

			// TODO check the performance of this
			pushNew( needsValidation, chart );
		}

		return AmCharts.animate( {
			duration: options.duration,
			tick: tick,
			end: function ( time ) {
				tick( time );

				if ( options.complete != null ) {
					options.complete();
				}
			}
		} );
	}

	AmCharts.addInitHandler( function( chart ) {
		chart.animateData = animateData;
	}, [ "funnel", "pie", "gantt", "serial", "radar", "gauge" ] );

} )();
<commit_msg>animateData: Removing support for gauge charts<commit_after>/*
Plugin Name: amCharts Animate Data
Description: Smoothly animates the `dataProvider`
Author: Paul Chapman, amCharts
Version: 1.0.0
Author URI: http://www.amcharts.com/

Copyright 2015 amCharts

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Please note that the above license covers only this plugin. It by all means does
not apply to any other amCharts products that are covered by different licenses.
*/

/* globals AmCharts */
/* jshint -W061 */

( function() {
	"use strict";

	function raf( self ) {
		requestAnimationFrame( function( now ) {
			self._onFrame( now );
		} );
	}

	function noop( now ) {}

	function Animation( duration, start, tick, end ) {
		this._finished = false;
		this._startTime = null;
		this._duration = duration;
		this._start = ( start == null ? noop : start );
		this._tick = ( tick == null ? noop : tick );
		this._end = ( end == null ? noop : end );
	}

	Animation.prototype.cancel = function() {
		this._finished = true;
		this._startTime = null;
		this._duration = null;
		this._start = null;
		this._tick = null;
		this._end = null;
	};

	Animation.prototype._onFrame = function( now ) {
		// This will only happen when the animation was cancelled
		if ( this._finished ) {
			return true;

		} else if ( this._startTime === null ) {
			this._startTime = now;
			this._start( 0 );
			return false;

		} else {
			var diff = now - this._startTime;

			if ( diff < this._duration ) {
				this._tick( diff / this._duration );
				return false;

			} else {
				this._end( 1 );
				// Cleanup all the properties
				this.cancel();
				return true;
			}
		}
	};

	function Animator() {
		this._animating = false;
		this._animations = [];
		this._onBeforeFrames = [];
		this._onAfterFrames = [];
	}

	Animator.prototype.animate = function( options ) {
		var animation = new Animation(
			options.duration,
			options.start,
			options.tick,
			options.end
		);

		this._animations.push( animation );

		if ( !this._animating ) {
			this._animating = true;

			raf( this );
		}

		return animation;
	};

	Animator.prototype.onBeforeFrame = function( f ) {
		this._onBeforeFrames.push( f );
	};

	Animator.prototype.onAfterFrame = function( f ) {
		this._onAfterFrames.push( f );
	};

	Animator.prototype._onFrame = function( now ) {
		var onBeforeFrames = this._onBeforeFrames;

		for ( var i = 0; i < onBeforeFrames.length; ++i ) {
			onBeforeFrames[ i ]( now );
		}

		var animations = this._animations;

		for ( var i = 0; i < animations.length; ++i ) {
			var animation = animations[ i ];

			// If the animation is finished...
			if ( animation._onFrame( now ) ) {
				// TODO this is a bit slow, but I don't know of a faster alternative
				animations.splice( i, 1 );
				--i;
			}
		}

		var onAfterFrames = this._onAfterFrames;

		for ( var i = 0; i < onAfterFrames.length; ++i ) {
			onAfterFrames[ i ]( now );
		}

		// All animations are finished
		if ( animations.length === 0 ) {
			this._animating = false;

		} else {
			raf( this );
		}
	};

	var _animator = new Animator();

	AmCharts.animate = function( options ) {
		return _animator.animate( options );
	};

	AmCharts.tween = function( time, from, to ) {
		return ( time * ( to - from ) ) + from;
	};

	function easeInOut3( t ) {
		var r = ( t < 0.5 ? t * 2 : ( 1 - t ) * 2 );
		r *= r * r * r;
		return ( t < 0.5 ? r / 2 : 1 - ( r / 2 ) );
	}

	function easeIn3( t ) {
		t *= t * t * t;
		return t;
	}

	function easeOut3( t ) {
		var r = ( 1 - t );
		r *= r * r * r;
		return ( 1 - r );
	}

	var needsValidation = [];

	function isNaN( x ) {
		return x !== x;
	}

	function each( array, fn ) {
		var length = array.length;

		for ( var i = 0; i < length; ++i ) {
			fn( array[ i ] );
		}
	}

	// Super fast and memory efficient map
	function map( array, fn ) {
		var length = array.length;
		var output = new Array( length );

		for ( var i = 0; i < length; ++i ) {
			output[ i ] = fn( array[ i ] );
		}

		return output;
	}

	function pushNew( array, x ) {
		for ( var i = 0; i < array.length; ++i ) {
			if ( array[ i ] === x ) {
				return;
			}
		}

		array.push( x );
	}

	// TODO check the performance of this
	_animator.onAfterFrame( function() {
		for ( var i = 0; i < needsValidation.length; ++i ) {
			needsValidation[ i ].validateData();
		}

		needsValidation.length = 0;
	} );

	// This ensures that a key is only added once
	function addKey( keys, seen, key ) {
		if ( !seen[ key ] ) {
			seen[ key ] = true;
			keys.push( key );
		}
	}

	function addKeys( keys, seen, object, a ) {
		each( a, function( key ) {
			var value = object[ key ];

			if ( value != null ) {
				addKey( keys, seen, value );
			}
		} );
	}

	function getKeysSliced( chart, keys, seen ) {
		addKeys( keys, seen, chart, [
			"alphaField",
			"valueField"
		] );
	}

	function getKeysFunnel( chart, keys, seen ) {
		getKeysSliced( chart, keys, seen );
	}

	function getKeysPie( chart, keys, seen ) {
		getKeysSliced( chart, keys, seen );

		addKeys( keys, seen, chart, [
			"labelRadiusField"
		] );
	}

	// TODO this is wrong
	function getKeysGantt( chart, keys, seen ) {
		// TODO is this correct ?
		getKeysCategoryAxis( chart.categoryAxis, keys, seen );
		// TODO is this correct ?
		getKeysGraphs( chart.graphs, keys, seen );

		addKeys( keys, seen, chart, [
			"columnWidthField",
			"durationField",
			"endField",
			"startField"
		] );
	}

	function getKeysGraphs( graphs, keys, seen ) {
		each( graphs, function( graph ) {
			addKeys( keys, seen, graph, [
				"alphaField",
				"bulletSizeField",
				"closeField",
				"dashLengthField",
				"errorField",
				"highField",
				"lowField",
				"openField",
				"valueField"
			] );
		} );
	}

	function getKeysCategoryAxis( categoryAxis, keys, seen ) {
		addKeys( keys, seen, categoryAxis, [
			"widthField"
		] );
	}

	// Returns an array of all of the animatable keys
	function getKeys( chart ) {
		var keys = [];

		var seen = {};

		if ( chart.type === "funnel" ) {
			getKeysFunnel( chart, keys, seen );

		} else if ( chart.type === "pie" ) {
			getKeysPie( chart, keys, seen );

		// TODO this is wrong
		} else if ( chart.type === "gantt" ) {
			getKeysGantt( chart, keys, seen );

		} else if ( chart.type === "serial" ) {
			getKeysCategoryAxis( chart.categoryAxis, keys, seen );
			getKeysGraphs( chart.graphs, keys, seen );

		} else if ( chart.type === "radar" ) {
			getKeysGraphs( chart.graphs, keys, seen );
		}

		return keys;
	}

	// TODO what about gantt charts ?
	function getCategoryField( chart ) {
		if ( chart.type === "funnel" || chart.type === "pie" ) {
			return chart.titleField;

		} else if ( chart.type === "serial" || chart.type === "radar" ) {
			return chart.categoryField;
		}
	}

	function getValue( value ) {
		if ( value == null ) {
			return null;

		} else {
			value = +value;

			// TODO test this
			// TODO what about Infinity, etc. ?
			if ( isNaN( value ) ) {
				return null;

			} else {
				return value;
			}
		}
	}

	function getValues( data, keys ) {
		return map( keys, function( key ) {
			return getValue( data[ key ] );
		} );
	}

	function getString( value ) {
		// TODO better algorithm for this ?
		return JSON.stringify( value );
	}

	function animateData( dataProvider, options ) {
		var chart = this;

		var easing = options.easing || easeOut3;

		var categoryField = getCategoryField( chart );
		var keys = getKeys( chart );

		var categories = {};
		var values = [];

		each( chart.dataProvider, function( data ) {
			// TODO handle data which doesn't have a category
			var category = getString( data[ categoryField ] );

			categories[ category ] = data;
		} );

		each( dataProvider, function( data ) {
			// TODO handle data which doesn't have a category
			var category = getString( data[ categoryField ] );

			// If the new data has the same category as the old data...
			if ( category in categories ) {
				var oldValues = getValues( categories[ category ], keys );
				var newValues = getValues( data, keys );

				// TODO maybe use a class rather than an object literal ?
				values.push( {
					oldValues: oldValues,
					newValues: newValues,
					data: data
				} );
			}
		} );

		chart.dataProvider = dataProvider;

		function tick( time ) {
			// Apply the easing to the time ratio
			time = easing( time );

			for ( var i = 0; i < values.length; ++i ) {
				var info = values[ i ];
				var oldValues = info.oldValues;
				var newValues = info.newValues;
				var data = info.data;

				for ( var j = 0; j < keys.length; ++j ) {
					var key = keys[ j ];
					var oldValue = oldValues[ j ];
					var newValue = newValues[ j ];

					if ( oldValue != null && newValue != null ) {
						data[ key ] = AmCharts.tween( time, oldValue, newValue );
					}
				}
			}

			// TODO check the performance of this
			pushNew( needsValidation, chart );
		}

		return AmCharts.animate( {
			duration: options.duration,
			tick: tick,
			end: function ( time ) {
				tick( time );

				if ( options.complete != null ) {
					options.complete();
				}
			}
		} );
	}

	AmCharts.addInitHandler( function( chart ) {
		chart.animateData = animateData;
	}, [ "funnel", "pie", "gantt", "serial", "radar" ] );

} )();
<|endoftext|>


<commit_before>/*

 ___  _   _   ___  ____ _____ ___   ___   ___   _   _
/ __|/ \_/ \ / _ \| |\_\_  __|  /  / _ \ / _ \ / \_/ \
\__ \ /| |\ | | | |  \   | | / /__| |_| | |_| | /| |\ |
|___/_||_||_|_| |_|_|\_\ |_|/_____|\___/ \___/|_||_||_|

 Version: 0.1.2
  Author: Alliance Port, LLC
 Website: http://alliance.port.rocks/
    Docs: http://alliance.port.rocks/jquery-ap-smartzoom/
    Repo: http://github.com/allianceport/jquery-ap-smartzoom/
  Issues: http://github.com/allianceport/jquery-ap-smartzoom/issues
 */

window.ap = window.ap || {};

window.ap.smartzoom = (function( _w ) {

    var $     = _w.jQuery || _w.Zepto || _w.jquip
      , myApp = _w.ap;

    var models      = {}
      , views       = {}
      , controllers = {};

    models = {
        fontSize: 62.5
      , width:    320
    };

    views.getCurrent = function() {
        return models.screen;
    };

    controllers.viewPort = function() {
        var windowWidth  = $( window ).width()
          , windowHeight = $( window ).height()
          , currentZoom  = ( windowWidth / models.width ) * 100
          , orientation  = false;
        if ( windowWidth > windowHeight ) {
            orientation = 'portrait';
            views.body.removeClass( 'ui-landscape' ).addClass( 'ui-portrait' );
        }
        else {
            orientation = 'landscape';
            views.body.removeClass( 'ui-portrait' ).addClass( 'ui-landscape' );
        }
        if ( currentZoom < 200 ) {
            document.documentElement.style.zoom = currentZoom + '%';
            if ( myApp.isMobile.iOS() ) {
                document.documentElement.style.webkitTextSizeAdjust = '100%';
                document.body.style.fontSize = ( models.fontSize * currentZoom / 100 ) + "%";
            }
        }
        return {
            width:       windowWidth  || 320
          , height:      windowHeight || 480
          , zoom:        currentZoom  || 100
          , orientation: orientation  || 'portrait'
        };
    };

    controllers.resize = function() {
        var resizeTimerID = false;
        return function() {
            if ( ! resizeTimerID ) {
                resizeTimerID = setTimeout(function() {
                    models.screen = controllers.viewPort();
                    clearTimeout( resizeTimerID );
                    resizeTimerID = false;
                }, 450 );
            }
        };
    }();

    return {
        getCurrent: function() {
            return models.screen;
        }
      , initialize: function( options ) {
            models.width = options && options.width ? options.width : 320;
            models.fontSize = options && options.fontSize ? options.fontSize : 62.5;
            views.body = $( 'body' );
            models.screen    = controllers.viewPort();
            // Deprecated: window.scrollTo( 0, 1 );
            $( _w ).bind( 'resize', controllers.resize );
            return models.screen;
        }
      , terminate:  function() {
            $( _w ).unbind( 'resize', controllers.resize );
            document.documentElement.style.zoom = '100%';
            if ( myApp.isMobile.iOS() ) {
                document.documentElement.style.webkitTextSizeAdjust = 'auto';
                document.body.style.fontSize = models.fontSize + "%";
            }
            return models.screen;
      }
    };

})( window );
<commit_msg>Bumping Version<commit_after>/*

 ___  _   _   ___  ____ _____ ___   ___   ___   _   _
/ __|/ \_/ \ / _ \| |\_\_  __|  /  / _ \ / _ \ / \_/ \
\__ \ /| |\ | | | |  \   | | / /__| |_| | |_| | /| |\ |
|___/_||_||_|_| |_|_|\_\ |_|/_____|\___/ \___/|_||_||_|

 Version: 0.2.0
  Author: Alliance Port, LLC
 Website: http://alliance.port.rocks/
    Docs: http://alliance.port.rocks/jquery-ap-smartzoom/
    Repo: http://github.com/allianceport/jquery-ap-smartzoom/
  Issues: http://github.com/allianceport/jquery-ap-smartzoom/issues
 */

window.ap = window.ap || {};

window.ap.smartzoom = (function( _w ) {

    var $     = _w.jQuery || _w.Zepto || _w.jquip
      , myApp = _w.ap;

    var models      = {}
      , views       = {}
      , controllers = {};

    models = {
        fontSize: 62.5
      , width:    320
    };

    views.getCurrent = function() {
        return models.screen;
    };

    controllers.viewPort = function() {
        var windowWidth  = $( window ).width()
          , windowHeight = $( window ).height()
          , currentZoom  = ( windowWidth / models.width ) * 100
          , orientation  = false;
        if ( windowWidth > windowHeight ) {
            orientation = 'portrait';
            views.body.removeClass( 'ui-landscape' ).addClass( 'ui-portrait' );
        }
        else {
            orientation = 'landscape';
            views.body.removeClass( 'ui-portrait' ).addClass( 'ui-landscape' );
        }
        if ( currentZoom < 200 ) {
            document.documentElement.style.zoom = currentZoom + '%';
            if ( myApp.isMobile.iOS() ) {
                document.documentElement.style.webkitTextSizeAdjust = '100%';
                document.body.style.fontSize = ( models.fontSize * currentZoom / 100 ) + "%";
            }
        }
        return {
            width:       windowWidth  || 320
          , height:      windowHeight || 480
          , zoom:        currentZoom  || 100
          , orientation: orientation  || 'portrait'
        };
    };

    controllers.resize = function() {
        var resizeTimerID = false;
        return function() {
            if ( ! resizeTimerID ) {
                resizeTimerID = setTimeout(function() {
                    models.screen = controllers.viewPort();
                    clearTimeout( resizeTimerID );
                    resizeTimerID = false;
                }, 450 );
            }
        };
    }();

    return {
        getCurrent: function() {
            return models.screen;
        }
      , initialize: function( options ) {
            models.width = options && options.width ? options.width : 320;
            models.fontSize = options && options.fontSize ? options.fontSize : 62.5;
            views.body = $( 'body' );
            models.screen    = controllers.viewPort();
            // Deprecated: window.scrollTo( 0, 1 );
            $( _w ).bind( 'resize', controllers.resize );
            return models.screen;
        }
      , terminate:  function() {
            $( _w ).unbind( 'resize', controllers.resize );
            document.documentElement.style.zoom = '100%';
            if ( myApp.isMobile.iOS() ) {
                document.documentElement.style.webkitTextSizeAdjust = 'auto';
                document.body.style.fontSize = models.fontSize + "%";
            }
            return models.screen;
      }
    };

})( window );
<|endoftext|>


<commit_before>/*!
 * EventTracker - is a jQuery plugin wrapper for Google Analytics custom event tracker
 * https://github.com/globocom/jquery-eventtracker
 * version: 0.2.0
 */

(function($){

  $.fn.trackEvents = function(params) {
    var tracker = $.fn.trackEvents;

    $.fn.trackEvents.params = $.extend({
      delay: 250,
      cssClassForDefaultEvent: "defaultEnable"
    }, params);

    params = $.fn.trackEvents.params;

    if (!window._gaq) {
      $.fn.trackEvents.disabled = true;
      return;
    }

    return this.each (function() {
      var element = $(this);

      var options = tracker.popDataOptions(element);
      var events = tracker.getDataEvents(element);

      _.each(events, function(event) {
        if (element.get(0).tagName == "A") {
          element.click(tracker.link.generateStrategy(element, event, options));

        } else if (element.get(0).tagName == "FORM") {
          element.submit(tracker.form.generateStrategy(element, event, options));
        }
      });
    });
  }

  // Form Strategy

  $.fn.trackEvents.form = {};

  $.fn.trackEvents.form.generateStrategy = function(element, event, options) {
    return $.fn.trackEvents.generateStrategy({
      element: element,
      event: event,
      options: options,
      action: "submit",
      callback: function() { $.fn.trackEvents.form.callback(element); }
    });
  }

  $.fn.trackEvents.form.callback = function(element) {
    $.fn.trackEvents.callback(element, "submit", $.fn.trackEvents.form);
  }

  // Link Strategy

  $.fn.trackEvents.link = {};

  $.fn.trackEvents.link.generateStrategy = function(element, event, options) {
    return $.fn.trackEvents.generateStrategy({
      element: element,
      event: event,
      options: options,
      action: "click",
      callback: function() { $.fn.trackEvents.link.callback(element); }
    });
  }

  $.fn.trackEvents.link.callback = function(element) {
    $.fn.trackEvents.callback(element, "click", $.fn.trackEvents.link);
  }

  $.fn.trackEvents.link.defaultAction = function() {
    if ($.fn.trackEvents.hasDefaultEvent($(this))) {
      var href = $(this).attr("href");
      $.fn.trackEvents.locationHref(href);
    }
  }

  $.fn.trackEvents.link.defaultAction.action = "defaultAction";

  $.fn.trackEvents.link.hasDefaultAction = function(element) {
    return $.fn.trackEvents.hasDefaultAction(element, "click");
  }

  // Common code
  $.fn.trackEvents.generateStrategy = function(opts) {
    var tracker = $.fn.trackEvents;
    var params = tracker.params;

    var strategy = function(e) {
      var event = opts.event;

      var eventAttr = $.fn.trackEvents.keyToTagAttr(opts.event.key);
      event.content = $(this).attr(eventAttr);

      tracker.notifyAnalytics(event);

      if (!opts.options.javaScriptOnly) {
        e.preventDefault();
        e.stopImmediatePropagation();

        opts.element.addClass(params.cssClassForDefaultEvent);
        opts.element.off(opts.action, strategy);

        setTimeout(opts.callback, params.delay);
      }
    }

    return strategy;
  }

  $.fn.trackEvents.callback = function(element, action, namespace) {
    var tracker = $.fn.trackEvents;

    if (namespace.defaultAction && !namespace.hasDefaultAction(element)) {
      element[action](namespace.defaultAction);
    }

    element.trigger(action);
  }

  $.fn.trackEvents.hasDefaultAction = function(element, action) {
    var events = element.data("events");
    if (events) {
      return _.any(events[action], function(obj) {
        return obj.handler.action == "defaultAction";
      });
    }
    return false;
  }

  $.fn.trackEvents.locationHref = function(href) {
    document.location.href = href;
  }

  $.fn.trackEvents.hasDefaultEvent = function(element) {
    var params = $.fn.trackEvents.params;
    return element.hasClass(params.cssClassForDefaultEvent);
  }

  $.fn.trackEvents.notifyAnalytics = function(event) {
    var category = event.category.toString();
    var action = event.action.toString();
    var content = (event.content === undefined) ? "" : event.content.toString();

    if (window._gaq) {
      window._gaq.push(['_trackEvent', category, action, content]);
    }
  }

  $.fn.trackEvents.getDataEvents = function(element) {
    var data = element.data();
    var tracker = $.fn.trackEvents;
    var events = _.filter(_.keys(data), function(key) { return !!key.match(/^event/); });

    return _.map(events, function(eventName) {
      var elements = eventName.split(/[aA]ction/);
      var category = tracker.whitespace(elements[0].replace(/^event/, ''));
      var action = tracker.whitespace(elements[1]);
      return {
        key: eventName,
        category: category,
        action: action,
        content: data[eventName]
      };
    });
  }

  $.fn.trackEvents.popDataOptions = function(element) {
    var data = element.data();

    var tracker = $.fn.trackEvents;
    var optionNames = {javaScriptOnly: "eventJavascriptOnly"};

    return _.tap({}, function(obj) {
      _.each(_.keys(optionNames), function(optName) {
        var optAttr = optionNames[optName];
        var optValue = data[optAttr];

        obj[optName] = optValue ? optValue : null;

        element.removeData(optAttr);
      });
    });
  };

  $.fn.trackEvents.whitespace = function(string) {
    return string.replace(/([A-Z])/g, " $1").replace(/^\s+/, '').replace(/\s+$/, '');
  },

  $.fn.trackEvents.keyToTagAttr = function(string) {
    return "data-" + string.replace(/([A-Z])/g, "-$1").toLowerCase();
  }

})(jQuery);
<commit_msg>adding version<commit_after>/*!
 * EventTracker - is a jQuery plugin wrapper for Google Analytics custom event tracker
 * https://github.com/globocom/jquery-eventtracker
 * version: v0.2.0
 */

(function($){

  $.fn.trackEvents = function(params) {
    var tracker = $.fn.trackEvents;

    $.fn.trackEvents.params = $.extend({
      delay: 250,
      cssClassForDefaultEvent: "defaultEnable"
    }, params);

    params = $.fn.trackEvents.params;

    if (!window._gaq) {
      $.fn.trackEvents.disabled = true;
      return;
    }

    return this.each (function() {
      var element = $(this);

      var options = tracker.popDataOptions(element);
      var events = tracker.getDataEvents(element);

      _.each(events, function(event) {
        if (element.get(0).tagName == "A") {
          element.click(tracker.link.generateStrategy(element, event, options));

        } else if (element.get(0).tagName == "FORM") {
          element.submit(tracker.form.generateStrategy(element, event, options));
        }
      });
    });
  }

  // Form Strategy

  $.fn.trackEvents.form = {};

  $.fn.trackEvents.form.generateStrategy = function(element, event, options) {
    return $.fn.trackEvents.generateStrategy({
      element: element,
      event: event,
      options: options,
      action: "submit",
      callback: function() { $.fn.trackEvents.form.callback(element); }
    });
  }

  $.fn.trackEvents.form.callback = function(element) {
    $.fn.trackEvents.callback(element, "submit", $.fn.trackEvents.form);
  }

  // Link Strategy

  $.fn.trackEvents.link = {};

  $.fn.trackEvents.link.generateStrategy = function(element, event, options) {
    return $.fn.trackEvents.generateStrategy({
      element: element,
      event: event,
      options: options,
      action: "click",
      callback: function() { $.fn.trackEvents.link.callback(element); }
    });
  }

  $.fn.trackEvents.link.callback = function(element) {
    $.fn.trackEvents.callback(element, "click", $.fn.trackEvents.link);
  }

  $.fn.trackEvents.link.defaultAction = function() {
    if ($.fn.trackEvents.hasDefaultEvent($(this))) {
      var href = $(this).attr("href");
      $.fn.trackEvents.locationHref(href);
    }
  }

  $.fn.trackEvents.link.defaultAction.action = "defaultAction";

  $.fn.trackEvents.link.hasDefaultAction = function(element) {
    return $.fn.trackEvents.hasDefaultAction(element, "click");
  }

  // Common code
  $.fn.trackEvents.generateStrategy = function(opts) {
    var tracker = $.fn.trackEvents;
    var params = tracker.params;

    var strategy = function(e) {
      var event = opts.event;

      var eventAttr = $.fn.trackEvents.keyToTagAttr(opts.event.key);
      event.content = $(this).attr(eventAttr);

      tracker.notifyAnalytics(event);

      if (!opts.options.javaScriptOnly) {
        e.preventDefault();
        e.stopImmediatePropagation();

        opts.element.addClass(params.cssClassForDefaultEvent);
        opts.element.off(opts.action, strategy);

        setTimeout(opts.callback, params.delay);
      }
    }

    return strategy;
  }

  $.fn.trackEvents.callback = function(element, action, namespace) {
    var tracker = $.fn.trackEvents;

    if (namespace.defaultAction && !namespace.hasDefaultAction(element)) {
      element[action](namespace.defaultAction);
    }

    element.trigger(action);
  }

  $.fn.trackEvents.hasDefaultAction = function(element, action) {
    var events = element.data("events");
    if (events) {
      return _.any(events[action], function(obj) {
        return obj.handler.action == "defaultAction";
      });
    }
    return false;
  }

  $.fn.trackEvents.locationHref = function(href) {
    document.location.href = href;
  }

  $.fn.trackEvents.hasDefaultEvent = function(element) {
    var params = $.fn.trackEvents.params;
    return element.hasClass(params.cssClassForDefaultEvent);
  }

  $.fn.trackEvents.notifyAnalytics = function(event) {
    var category = event.category.toString();
    var action = event.action.toString();
    var content = (event.content === undefined) ? "" : event.content.toString();

    if (window._gaq) {
      window._gaq.push(['_trackEvent', category, action, content]);
    }
  }

  $.fn.trackEvents.getDataEvents = function(element) {
    var data = element.data();
    var tracker = $.fn.trackEvents;
    var events = _.filter(_.keys(data), function(key) { return !!key.match(/^event/); });

    return _.map(events, function(eventName) {
      var elements = eventName.split(/[aA]ction/);
      var category = tracker.whitespace(elements[0].replace(/^event/, ''));
      var action = tracker.whitespace(elements[1]);
      return {
        key: eventName,
        category: category,
        action: action,
        content: data[eventName]
      };
    });
  }

  $.fn.trackEvents.popDataOptions = function(element) {
    var data = element.data();

    var tracker = $.fn.trackEvents;
    var optionNames = {javaScriptOnly: "eventJavascriptOnly"};

    return _.tap({}, function(obj) {
      _.each(_.keys(optionNames), function(optName) {
        var optAttr = optionNames[optName];
        var optValue = data[optAttr];

        obj[optName] = optValue ? optValue : null;

        element.removeData(optAttr);
      });
    });
  };

  $.fn.trackEvents.whitespace = function(string) {
    return string.replace(/([A-Z])/g, " $1").replace(/^\s+/, '').replace(/\s+$/, '');
  },

  $.fn.trackEvents.keyToTagAttr = function(string) {
    return "data-" + string.replace(/([A-Z])/g, "-$1").toLowerCase();
  }

})(jQuery);
<|endoftext|>


<commit_before>jQuery.fn.selectorPath = function() {
    var path = [],
        $current = this;

    while(true) {
        // if it's not defined stop
        if(!$current.length) {
            break;
        }

        // if it's the body add it to the path and stop
        if($current.is('body')) {
            path.push('body');
            break;
        }
        // if the id is defined stop the path
        var id = $current.attr('id');
        if(id) {
            path.push('#' + id);
            break;
        }

        var nodeName = $current[0].nodeName.toLowerCase(),
            index = $current.index(nodeName);

        path.push(nodeName + ':eq(' + index + ')');

        $current = $current.parent();
    }

    return path.reverse().join(' > ');
};

jQuery.fn.selectorPaths = function() {
    var output = [];

    this.each(function() {
        output.push($(this).selectorPath());
    });

    return output;
};<commit_msg>indexing is now based on the element type<commit_after>jQuery.fn.selectorPath = function() {
    var path = [],
        $current = this;

    while(true) {
        // if it's not defined stop
        if(!$current.length) {
            break;
        }

        // if it's the body add it to the path and stop
        if($current.is('body')) {
            path.push('body');
            break;
        }
        // if the id is defined stop the path
        var id = $current.attr('id');
        if(id) {
            path.push('#' + id);
            break;
        }

        var $parent = $current.parent(),
            nodeName = $current[0].nodeName.toLowerCase(),
            index = $parent.children(nodeName).index($current);

        path.push(nodeName + ':eq(' + index + ')');

        $current = $parent;
    }

    return path.reverse().join(' > ');
};

jQuery.fn.selectorPaths = function() {
    var output = [];

    this.each(function() {
        output.push($(this).selectorPath());
    });

    return output;
};<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Shows a button that changes the simulation to full screen.  This feature is not available on iPad.
 *
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  var Node = require( 'SCENERY/nodes/Node' );
  var FontAwesomeNode = require( 'SUN/FontAwesomeNode' );
  var inherit = require( 'PHET_CORE/inherit' );

  function requestFullScreen( element ) {

    // Supports most browsers and their versions.
    var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;

    if ( requestMethod ) { // Native full screen.
      requestMethod.call( element );
    }
    else if ( typeof window.ActiveXObject !== "undefined" ) { // Older IE.
      var wscript = new ActiveXObject( "WScript.Shell" );
      if ( wscript !== null ) {
        wscript.SendKeys( "{F11}" );
      }
    }
  }

  var fullScreener = function() {
    requestFullScreen( document.body );
  };

  function FullScreenButton( options ) {
    Node.call( this, { cursor: 'pointer' } );
    this.addChild( new FontAwesomeNode( 'fullscreen', { fill: '#fff', scale: 0.8 } ) );
    this.mutate( _.extend( { cursor: 'pointer' }, options ) );//TODO: pointer not going through here

    this.addInputListener( {
      down: function() {
        $( 'body' ).one( 'mouseup', fullScreener );
      }
    } );

    this.mouseArea = this.bounds;
    this.touchArea = this.bounds;
  }

  return inherit( Node, FullScreenButton );
} );<commit_msg>Removed FullScreenButton.js, see #261<commit_after><|endoftext|>


<commit_before>'use strict';

var $ = require('jquery');

function NavMainComponent(html) {
    this.$html = html;
};

NavMainComponent.prototype.init = function() {

    var component = this;

    component.$navMain = this.$html.find('.nav-main');
    component.$navPrimary = this.$html.find('.nav-primary');
    component.$navSecondary = this.$html.find('.nav-secondary');
    component.$primaryNavLinks = component.$navPrimary.find('.nav-link');
    component.$secondaryNavLinks = component.$navSecondary.find('.nav-link');
    component.$closeLink = component.$navMain.find('[data-nav-action=close]');

    component.closeHandler = function() {
        component.closeNavs();
    };

    // Primary Nav Items Height Adjustment
    $('.nav-primary .nav-item .nav-link').each(function(){
        console.log($(this));
        if ($('.nav-primary .nav-item .nav-link span').height() >= 30) {
            $('.nav-primary .nav-item .nav-link').css({'height': '100%', 'padding-bottom': '16px'});
        }
    });

    component.$primaryNavLinks.on('click', function(e) {

        var $self = $(this),
            href = $self.attr('href');

        // If href is a fragment, don't add it to the URL because it breaks the
        // back button
        if (href.substring(0,1) === '#') {
            e.preventDefault();
        }

        component.switchPrimaryNav(href);
        component.switchSecondaryNav(href);

        component.$html.find('.content-main').on('click', component.closeHandler);
    });

    component.$secondaryNavLinks.on('click', function() {
        component.changeActiveSecondaryNavLink($(this).attr('href'));
    });

    component.$closeLink.on('click', function(e) {
        e.preventDefault();
        component.closeNavs();
    });
};

NavMainComponent.prototype.switchPrimaryNav = function(target) {

    var component = this;

    component.$html.find('.nav-primary .nav-link').removeClass('is-active');

    if (component.$html.find('[data-nav="' + target + '"]').length >= 1) {
        component.$navMain.addClass('is-open');
    } else {
        component.closeNavs();
    }

    component.$html.find('.nav-primary .is-active').removeClass('is-active');
    component.$html.find('[href="' + target + '"]').addClass('is-active');
};

NavMainComponent.prototype.switchSecondaryNav = function(target) {

    var component = this;

    component.closeSubNavs();

    component.$html.find('.nav-list.is-active').removeClass('is-active');
    component.$html.find('[data-nav="' + target + '"]')
        .addClass('is-active');
};

NavMainComponent.prototype.changeActiveSecondaryNavLink = function(target) {

    var component = this;

    component.$html.find('.nav-secondary .nav-item.is-active').removeClass('is-active');
    component.$html.find('[href="' + target + '"]').addClass('is-active');
};

NavMainComponent.prototype.closeNavs = function() {

    var component = this;

    component.$navMain.removeClass('is-open');

    component.$html.find('.content-main').unbind('click', component.closeHandler);
};

NavMainComponent.prototype.closeSubNavs = function() {

    var component = this;

    component.$html.find('.nav-secondary .nav-container').removeClass('is-active');
};

module.exports = NavMainComponent;
<commit_msg>Remove JS Code<commit_after>'use strict';

var $ = require('jquery');

function NavMainComponent(html) {
    this.$html = html;
};

NavMainComponent.prototype.init = function() {

    var component = this;

    component.$navMain = this.$html.find('.nav-main');
    component.$navPrimary = this.$html.find('.nav-primary');
    component.$navSecondary = this.$html.find('.nav-secondary');
    component.$primaryNavLinks = component.$navPrimary.find('.nav-link');
    component.$secondaryNavLinks = component.$navSecondary.find('.nav-link');
    component.$closeLink = component.$navMain.find('[data-nav-action=close]');

    component.closeHandler = function() {
        component.closeNavs();
    };

    component.$primaryNavLinks.on('click', function(e) {

        var $self = $(this),
            href = $self.attr('href');

        // If href is a fragment, don't add it to the URL because it breaks the
        // back button
        if (href.substring(0,1) === '#') {
            e.preventDefault();
        }

        component.switchPrimaryNav(href);
        component.switchSecondaryNav(href);

        component.$html.find('.content-main').on('click', component.closeHandler);
    });

    component.$secondaryNavLinks.on('click', function() {
        component.changeActiveSecondaryNavLink($(this).attr('href'));
    });

    component.$closeLink.on('click', function(e) {
        e.preventDefault();
        component.closeNavs();
    });
};

NavMainComponent.prototype.switchPrimaryNav = function(target) {

    var component = this;

    component.$html.find('.nav-primary .nav-link').removeClass('is-active');

    if (component.$html.find('[data-nav="' + target + '"]').length >= 1) {
        component.$navMain.addClass('is-open');
    } else {
        component.closeNavs();
    }

    component.$html.find('.nav-primary .is-active').removeClass('is-active');
    component.$html.find('[href="' + target + '"]').addClass('is-active');
};

NavMainComponent.prototype.switchSecondaryNav = function(target) {

    var component = this;

    component.closeSubNavs();

    component.$html.find('.nav-list.is-active').removeClass('is-active');
    component.$html.find('[data-nav="' + target + '"]')
        .addClass('is-active');
};

NavMainComponent.prototype.changeActiveSecondaryNavLink = function(target) {

    var component = this;

    component.$html.find('.nav-secondary .nav-item.is-active').removeClass('is-active');
    component.$html.find('[href="' + target + '"]').addClass('is-active');
};

NavMainComponent.prototype.closeNavs = function() {

    var component = this;

    component.$navMain.removeClass('is-open');

    component.$html.find('.content-main').unbind('click', component.closeHandler);
};

NavMainComponent.prototype.closeSubNavs = function() {

    var component = this;

    component.$html.find('.nav-secondary .nav-container').removeClass('is-active');
};

module.exports = NavMainComponent;
<|endoftext|>


<commit_before>//Translated from savior.rb using babyruby2js
'use strict';

var main = require('../../main');

var Grid = require('../../Grid');
var Heuristic = require('./Heuristic');
var inherits = require('util').inherits;

var sOK = main.sOK, sDEBUG = main.sDEBUG, ALWAYS = main.ALWAYS;

/** @class Saviors rescue ally groups in atari */
function Savior(player) {
    Heuristic.call(this, player);

    this.hunter = player.getHeuristic('Hunter');
}
inherits(Savior, Heuristic);
module.exports = Savior;

Savior.prototype.evalBoard = function (stateYx, scoreYx) {
    var myScoreYx = this.scoreGrid.yx;
    for (var j = 1; j <= this.gsize; j++) {
        for (var i = 1; i <= this.gsize; i++) {
            var state = stateYx[j][i];
            if (state < sOK) continue;
            if (state === sDEBUG && this.name === this.player.debugHeuristic)
                main.debug = true; // set your breakpoint on this line if needed

            var stone = this.goban.stoneAt(i, j);
            var threat = this._evalEscape(i, j, stone);
            if (threat === 0) continue;
            if (main.debug) main.log.debug('=> Savior thinks we can save a threat of ' + threat + ' in ' + stone);
            var score = myScoreYx[j][i] = threat;
            scoreYx[j][i] += score;
        }
    }
};

// i,j / stone is the stone we are proposing to play to help one of nearby groups to escape
Savior.prototype._evalEscape = function (i, j, stone) {
    // look around stone for 2 things: threatened allies & strong allies
    var savedThreat = 0, groups = [], livesAdded = 0;
    var hunterThreat = null; // we only get once the eval from hunter in i,j
    for (var g, g_array = stone.uniqueAllies(this.color), g_ndx = 0; g=g_array[g_ndx], g_ndx < g_array.length; g_ndx++) {
        if (g.lives === 1) {
            groups.push(g);
            savedThreat += this.groupThreat(g, true);
        } else if (g.lives === 2) {
            if (hunterThreat === 0) continue;
            groups.push(g);
            if (hunterThreat !== null) continue;
            // Not really intuitive: we check if enemy could chase us starting in i,j
            if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' asking hunter to look at ' +
                stone + ' pre-atari on ' + g);
            hunterThreat = this.hunter.catchThreat(i, j, this.enemyColor);
            savedThreat += hunterThreat;
        } else if (g.isDead < ALWAYS) {
            livesAdded += g.lives - 1;
        }
    }
    if (savedThreat === 0) return 0; // no threat

    livesAdded += stone.numEmpties();
    if (livesAdded > 2) return savedThreat; // we can save the threat
    if (livesAdded === 2) {
        // do not count empties that were already a life of threatened groups
        var empties = stone.empties();
        for (var t = groups.length - 1; t >= 0; t--) {
            g = groups[t];
            for (var n = empties.length - 1; n >= 0; n--) {
                if (empties[n].isNextTo(g)) livesAdded--;
            }
        }
    }
    if (livesAdded === 2) {
        // we get 2 lives from the new stone - first check special case of border
        if (groups.length === 1 && stone.isBorder()) {
            if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' checks an escape along border in ' + Grid.xy2move(i, j));
            var savior = this.canEscapeAlongBorder(groups[0], i, j);
            if (savior !== undefined) return savior ? savedThreat : 0;
        }
        // get our hunter to evaluate if we can escape
        if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' asking hunter to look at ' + Grid.xy2move(i, j) + ': threat=' + savedThreat + ', lives_added=' + livesAdded);
        this.goban.tryAt(i, j, this.color);
        var isCaught = this.hunter.isEscapingAtariCaught(stone);
        this.goban.untry();
        if (!isCaught) {
            return savedThreat;
        }
    }
    if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' giving up on threat of ' + savedThreat + ' in ' + Grid.xy2move(i, j));
    return 0; // nothing we can do to help
};
<commit_msg>Fixed some double counting in Savior<commit_after>//Translated from savior.rb using babyruby2js
'use strict';

var main = require('../../main');

var Grid = require('../../Grid');
var Heuristic = require('./Heuristic');
var inherits = require('util').inherits;

var sOK = main.sOK, sDEBUG = main.sDEBUG, ALWAYS = main.ALWAYS;

/** @class Saviors rescue ally groups in atari */
function Savior(player) {
    Heuristic.call(this, player);

    this.hunter = player.getHeuristic('Hunter');
}
inherits(Savior, Heuristic);
module.exports = Savior;

Savior.prototype.evalBoard = function (stateYx, scoreYx) {
    var myScoreYx = this.scoreGrid.yx;
    for (var j = 1; j <= this.gsize; j++) {
        for (var i = 1; i <= this.gsize; i++) {
            var state = stateYx[j][i];
            if (state < sOK) continue;
            if (state === sDEBUG && this.name === this.player.debugHeuristic)
                main.debug = true; // set your breakpoint on this line if needed

            var stone = this.goban.stoneAt(i, j);
            var threat = this._evalEscape(i, j, stone);
            if (threat === 0) continue;
            if (main.debug) main.log.debug('=> Savior thinks we can save a threat of ' + threat + ' in ' + stone);
            var score = myScoreYx[j][i] = threat;
            scoreYx[j][i] += score;
        }
    }
};

// i,j / stone is the stone we are proposing to play to help one of nearby groups to escape
Savior.prototype._evalEscape = function (i, j, stone) {
    // look around stone for 2 things: threatened allies & strong allies
    var savedThreat = 0, groups = [], livesAdded = 0;
    var hunterThreat = null; // we only get once the eval from hunter in i,j
    for (var g, g_array = stone.uniqueAllies(this.color), g_ndx = 0; g=g_array[g_ndx], g_ndx < g_array.length; g_ndx++) {
        if (g.lives === 1) {
            if (hunterThreat === 0) continue;
            groups.push(g);
            if (hunterThreat !== null) continue;
            savedThreat += this.groupThreat(g, true);
        } else if (g.lives === 2) {
            if (hunterThreat === 0) continue;
            groups.push(g);
            if (hunterThreat !== null) continue;
            // Not really intuitive: we check if enemy could chase us starting in i,j
            if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' asking hunter to look at ' +
                stone + ' pre-atari on ' + g);
            hunterThreat = this.hunter.catchThreat(i, j, this.enemyColor);
            if (hunterThreat) savedThreat = hunterThreat; // hunter computes total threat in i,j
        } else if (g.isDead < ALWAYS) {
            livesAdded += g.lives - 1;
        }
    }
    if (savedThreat === 0) return 0; // no threat

    livesAdded += stone.numEmpties();
    if (livesAdded > 2) return savedThreat; // we can save the threat
    if (livesAdded === 2) {
        // do not count empties that were already a life of threatened groups
        var empties = stone.empties();
        for (var t = groups.length - 1; t >= 0; t--) {
            g = groups[t];
            for (var n = empties.length - 1; n >= 0; n--) {
                if (empties[n].isNextTo(g)) livesAdded--;
            }
        }
    }
    if (livesAdded === 2) {
        // we get 2 lives from the new stone - first check special case of border
        if (groups.length === 1 && stone.isBorder()) {
            if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' checks an escape along border in ' + Grid.xy2move(i, j));
            var savior = this.canEscapeAlongBorder(groups[0], i, j);
            if (savior !== undefined) return savior ? savedThreat : 0;
        }
        // get our hunter to evaluate if we can escape
        if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' asking hunter to look at ' + Grid.xy2move(i, j) + ': threat=' + savedThreat + ', lives_added=' + livesAdded);
        this.goban.tryAt(i, j, this.color);
        var isCaught = this.hunter.isEscapingAtariCaught(stone);
        this.goban.untry();
        if (!isCaught) {
            return savedThreat;
        }
    }
    if (main.debug) main.log.debug('Savior ' + Grid.colorName(this.color) + ' giving up on threat of ' + savedThreat + ' in ' + Grid.xy2move(i, j));
    return 0; // nothing we can do to help
};
<|endoftext|>


<commit_before>//Module is a Singelton
define(function(require) {

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var Store = require('localstorage');
  var Doc = require('models/doc');
  var settings = require('models/settings');
  var rsSync = require('utils/backbone.remoteStorage-documents');

  var Docs = Backbone.Collection.extend({

    model: Doc,

    sync: rsSync,

    initialize: function(models) {
      this.loading = $.Deferred();

      this
        .on('change:content', this.ensureOrder)
        .on('change:lastEdited', this.saveWhenIdle)
        .on('change:title', this.updateUrl);
    },

    addNew: function() {
      this.add({
        id: _.uniqueId(),
        lastEdited: new Date().getTime()
      });
    },

    // Sort by 'lastEdited'
    comparator: function(first, second) {
      return first.get('lastEdited') > second.get('lastEdited') ? -1 : 1 ;
    },

    saveTimeout: undefined,
    saveWhenIdle: function(doc) {
      clearTimeout(this.saveTimeout);
      this.saveTimeout = setTimeout(_.bind(doc.save, doc), 1000);
    },

    updateUrl: function(doc) {
      var url = encodeURI(doc.get('title').toLowerCase().replace(/\s| /g, '-'));
      if (url.length < 1) {
        doc.set('url', '');
        return;
      }
      var len = this.filter(function(doc) {
        return new RegExp('^' + escapeRegExp(url) + '(-[0-9]|$)').test(doc.get('url'));
      }).length;
      url = len < 1 ? url : url + '-' + len;
      doc.set('url', url);
    },

    ensureOrder: function() {
      if (settings.get('openDocId') !== this.first().id) this.sort();
    },

    deleteEmpty: function() {
      var previousDoc = this.get(settings.previous('openDocId'));
      if (previousDoc && previousDoc.isEmpty()) {
        previousDoc.destroy();
      }
    },

    prepare: function(query) {
      return this
        .filter(function(doc) {
          var search = new RegExp(query, 'i');
          return !doc.isEmpty() && search.test( doc.get('title') );
        }).map(function(doc) {
          var res = doc.toJSON();
          res.opacity = doc.getOpacity();
          return res;
        });
    }

  });

  function escapeRegExp(str) {
    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
  }

  var docs = new Docs();

  return docs;

});
<commit_msg>use a nice escapeRegExp function<commit_after>//Module is a Singelton
define(function(require) {

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var Store = require('localstorage');
  var Doc = require('models/doc');
  var settings = require('models/settings');
  var rsSync = require('utils/backbone.remoteStorage-documents');

  var Docs = Backbone.Collection.extend({

    model: Doc,

    sync: rsSync,

    initialize: function(models) {
      this.loading = $.Deferred();

      this
        .on('change:content', this.ensureOrder)
        .on('change:lastEdited', this.saveWhenIdle)
        .on('change:title', this.updateUrl);
    },

    addNew: function() {
      this.add({
        id: _.uniqueId(),
        lastEdited: new Date().getTime()
      });
    },

    // Sort by 'lastEdited'
    comparator: function(first, second) {
      return first.get('lastEdited') > second.get('lastEdited') ? -1 : 1 ;
    },

    saveTimeout: undefined,
    saveWhenIdle: function(doc) {
      clearTimeout(this.saveTimeout);
      this.saveTimeout = setTimeout(_.bind(doc.save, doc), 1000);
    },

    updateUrl: function(doc) {
      var url = encodeURI(doc.get('title').toLowerCase().replace(/\s| /g, '-'));
      if (url.length < 1) {
        doc.set('url', '');
        return;
      }
      var len = this.filter(function(doc) {
        return new RegExp('^' + escapeRegExp(url) + '(-[0-9]|$)').test(doc.get('url'));
      }).length;
      url = len < 1 ? url : url + '-' + len;
      doc.set('url', url);
    },

    ensureOrder: function() {
      if (settings.get('openDocId') !== this.first().id) this.sort();
    },

    deleteEmpty: function() {
      var previousDoc = this.get(settings.previous('openDocId'));
      if (previousDoc && previousDoc.isEmpty()) {
        previousDoc.destroy();
      }
    },

    prepare: function(query) {
      return this
        .filter(function(doc) {
          var search = new RegExp(query, 'i');
          return !doc.isEmpty() && search.test( doc.get('title') );
        }).map(function(doc) {
          var res = doc.toJSON();
          res.opacity = doc.getOpacity();
          return res;
        });
    }

  });

  // see link for more info:
  // http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711
  function escapeRegExp(str) {
    return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

  }

  var docs = new Docs();

  return docs;

});
<|endoftext|>


<commit_before>'use strict';

var helpers = require('../helpers');

var getLastWhitespace = function (node) {
  if (node === false) {
    return null;
  }

  if (typeof node !== 'object') {
    return false;
  }
  if (node.is('space')) {
    return node;
  }

  return getLastWhitespace(node.last());
};

module.exports = {
  'name': 'space-before-brace',
  'defaults': {
    'include': true
  },
  'detect': function (ast, parser) {
    var result = [];
    if (ast.syntax === 'scss') {
      ast.traverseByTypes(['block', 'atrulers', 'declaration'], function (block, i, parent) {
        var previous = false,
            whitespace,
            warn = {};

        if ((block.is('block') || block.is('atrulers')) && !parent.is('value')) {
          previous = parent.get(i - 1);
        }
        else if (block.is('declaration')) {
          if (block.contains('value')) {
            for (var j = 0; j < block.content.length; j++) {
              if (block.content[j].is('value') && block.content[j].content[0].is('block')) {
                previous = block.content[j - 1];
                warn.line = block.content[j].content[0].start.line;
                warn.col = block.content[j].content[0].start.column;
              }
            }
          }
        }
        whitespace = getLastWhitespace(previous);
        if (whitespace === false) {
          if (parser.options.include) {
            if (!warn.hasOwnProperty('line')) {
              warn.line = block.start.line;
              warn.col = block.start.column;
            }
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': warn.line,
              'column': warn.col - 1,
              'message': 'Whitespace required before {',
              'severity': parser.severity
            });
          }
        }
        else {
          if (!parser.options.include && whitespace !== null) {
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': whitespace.start.line,
              'column': whitespace.start.column,
              'message': 'Whitespace not allowed before {',
              'severity': parser.severity
            });
          }
        }
      });
    }
    return result;
  }
};
<commit_msg>:bug: Fix space-before-brace to work with gonzales 3.2<commit_after>'use strict';

var helpers = require('../helpers');

var getLastWhitespace = function (node) {
  if (node === false) {
    return null;
  }

  if (!node) {
    return false;
  }
  if (node.is('space')) {
    return node;
  }

  return getLastWhitespace(node.last());
};

module.exports = {
  'name': 'space-before-brace',
  'defaults': {
    'include': true
  },
  'detect': function (ast, parser) {
    var result = [];
    if (ast.syntax === 'scss') {
      ast.traverseByTypes(['block', 'atrulers', 'declaration'], function (block, i, parent) {
        var previous = false,
            whitespace,
            warn = {};

        if ((block.is('block') || block.is('atrulers')) && !parent.is('value')) {
          previous = parent.get(i - 1);
        }
        else if (block.is('declaration')) {
          if (block.contains('value')) {
            for (var j = 0; j < block.content.length; j++) {
              if (block.content[j].is('value') && block.content[j].content[0].is('block')) {
                previous = block.content[j - 1];
                warn.line = block.content[j].content[0].start.line;
                warn.col = block.content[j].content[0].start.column;
              }
            }
          }
        }
        whitespace = getLastWhitespace(previous);
        if (whitespace === false) {
          if (parser.options.include) {
            if (!warn.hasOwnProperty('line')) {
              warn.line = block.start.line;
              warn.col = block.start.column;
            }
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': warn.line,
              'column': warn.col - 1,
              'message': 'Whitespace required before {',
              'severity': parser.severity
            });
          }
        }
        else {
          if (!parser.options.include && whitespace !== null) {
            result = helpers.addUnique(result, {
              'ruleId': parser.rule.name,
              'line': whitespace.start.line,
              'column': whitespace.start.column,
              'message': 'Whitespace not allowed before {',
              'severity': parser.severity
            });
          }
        }
      });
    }
    return result;
  }
};
<|endoftext|>


<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * Returns a combination of status information for the repository's git status
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

const execute = require( '../dual/execute' );
const getBranch = require( './getBranch' );
const gitRevParse = require( './gitRevParse' );
const assert = require( 'assert' );

/**
 * Returns a combination of status information for the repository's git status
 * @public
 *
 * @param {string} repo - The repository name
 * @returns {Promise.<{symbolicRef:string, branch:string, sha:string, status:string, [trackingBranch:string}, [ahead:number], [behind:number]}>}
 */
module.exports = async function( repo ) {
  assert( typeof repo === 'string' );

  const result = {};

  result.symbolicRef = await execute( 'git', [ 'symbolic-ref', '-q', 'HEAD' ], `../${repo}` );
  result.branch = await getBranch( repo ); // might be empty string
  result.sha = await gitRevParse( repo, 'HEAD' );
  result.status = await execute( 'git', [ 'status', '--porcelain' ], `../${repo}` );

  if ( result.branch ) {
    // Safe method to get ahead/behind counts, see http://stackoverflow.com/questions/2969214/git-programmatically-know-by-how-much-the-branch-is-ahead-behind-a-remote-branc

    // get the tracking-branch name
    result.trackingBranch = await execute( 'git', [ 'for-each-ref', '--format=\'%(upstream:short)\'', result.symbolicRef ], `../${repo}` );

    // e.g. behind-count + '\t' + ahead-count
    const counts = await execute( 'git', [ 'rev-list', '--left-right', '--count', `${result.trackingBranch}...HEAD` ], `../${repo}` );

    result.behind = parseInt( counts.split( '\t' )[ 0 ], 10 );
    result.ahead = parseInt( counts.split( '\t' )[ 1 ], 10 );
  }

  return result;
};
<commit_msg>gitStatus properly checking upstream remote, see https://github.com/phetsims/phettest/issues/1<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * Returns a combination of status information for the repository's git status
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

const execute = require( '../dual/execute' );
const getBranch = require( './getBranch' );
const gitRevParse = require( './gitRevParse' );
const assert = require( 'assert' );

/**
 * Returns a combination of status information for the repository's git status
 * @public
 *
 * @param {string} repo - The repository name
 * @returns {Promise.<{symbolicRef:string, branch:string, sha:string, status:string, [trackingBranch:string}, [ahead:number], [behind:number]}>}
 */
module.exports = async function( repo ) {
  assert( typeof repo === 'string' );

  const result = {};

  result.symbolicRef = await execute( 'git', [ 'symbolic-ref', '-q', 'HEAD' ], `../${repo}` );
  result.branch = await getBranch( repo ); // might be empty string
  result.sha = await gitRevParse( repo, 'HEAD' );
  result.status = await execute( 'git', [ 'status', '--porcelain' ], `../${repo}` );

  if ( result.branch ) {
    // Safe method to get ahead/behind counts, see http://stackoverflow.com/questions/2969214/git-programmatically-know-by-how-much-the-branch-is-ahead-behind-a-remote-branc

    // get the tracking-branch name
    result.trackingBranch = await execute( 'git', [ 'for-each-ref', '--format=\'%(upstream:short)\'', result.symbolicRef ], `../${repo}` );

    // e.g. behind-count + '\t' + ahead-count
    const counts = await execute( 'git', [ 'rev-list', '--left-right', '--count', `${result.trackingBranch}@{u}...HEAD` ], `../${repo}` );

    result.behind = parseInt( counts.split( '\t' )[ 0 ], 10 );
    result.ahead = parseInt( counts.split( '\t' )[ 1 ], 10 );
  }

  return result;
};
<|endoftext|>