<commit_before>'use strict';

var Sandal = (function () {

    var Sandal, _getArgumentNames, _register, _hasCircularDependencies, _callResolvedCallbacks, _createObjectSync, _resolve;

	_register = function (container, name, item) {
		if (name === 'done' || container[name]) {
			throw new Error(name + ' is already registered');
		}
		container[name] = item;
	};

	_getArgumentNames = function (func) {
		var functionString, argumentList;
		functionString = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '');
		argumentList = functionString.slice(functionString.indexOf('(') + 1, functionString.indexOf(')')).match(/([^\s,]+)/g);
		if (argumentList === null) {
			argumentList = [];
		}
		return argumentList;
	};

	_hasCircularDependencies = function (dependencyNames, resolveChain) {
		var i, j;
		for (j = 0; j < dependencyNames.length; j++) {
			for (i = 0; i < resolveChain.length; i++) {
				if (resolveChain[i] === dependencyNames[j]) {
					return true;
				}
			}
		}
		return false;
	};

	_callResolvedCallbacks = function (err, item) {
		for (var i = 0; i < item.resolvedCallbacks.length; i++) {
            item.resolvedCallbacks[i](err);
		}
        item.resolvedCallbacks = [];
        item.isResolving = false;
	};

    _createObjectSync = function (item, dependencies) {
        if (item.ctor) {
            var obj = Object.create(item.ctor.prototype);
            item.ctor.prototype.constructor.apply(obj, dependencies);
            return obj;
        } else {
            return item.factory.apply(null, dependencies);
        }
    };

	_resolve = function (name, container, resolveChain, callback) {

		var i, obj, resolvingDone, isDone, item, dependencyNames, dependencyCount, dependencies, hasDoneCallback, resolvedDependenciesCount;

        resolveChain.push(name);

        item = container[name];

        if (!item) {
            callback(new Error('No implementation registered for ' + name));
            return;
        }

		resolvingDone = function (err, obj) {
            if (!isDone) {
                isDone = true;
                if (item.lifecycle === 'singleton') {
                    item.singleton = obj;
                    _callResolvedCallbacks(err, item);
                } else {
                    callback(err, obj);
                }
            }
        };

        if (item.lifecycle === 'singleton') {

            item.resolvedCallbacks = item.resolvedCallbacks || [];
            item.resolvedCallbacks.push(function (err) {
                callback(err, item.singleton);
            });

            if (item.isResolving) {
                return;
            }
            item.isResolving = true;

            if (item.hasOwnProperty('singleton')) {
				resolvingDone(null, item.singleton);
                return;
            }

        }

		if (!item.ctor && !item.factory) {
			resolvingDone(new Error('No valid implementation registered for ' + name));
			return;
		}

		dependencyNames = _getArgumentNames(item.ctor || item.factory);
		if (_hasCircularDependencies(dependencyNames, resolveChain)) {
			resolvingDone(new Error('There are circular dependencies in resolve chain: ' + resolveChain));
            return;
		}

		dependencyCount = dependencyNames.length;
		if (dependencyCount === 0) {
            try {
                obj = _createObjectSync(item, []);
				resolvingDone(null, obj);
            } catch (err) {
				resolvingDone(err);
            }
			return;
		}

		dependencies = [];
		hasDoneCallback = false;
		resolvedDependenciesCount = 0;
		for (i = 0; i < dependencyCount; i++) {

			(function (index) {

				var dependencyCallback = function (err, dependency) {

                    if (err) {
						resolvingDone(err);
						return;
					}
					dependencies[index] = dependency;
					resolvedDependenciesCount++;

					if (resolvedDependenciesCount === dependencyCount) {

                        try {
                            obj = _createObjectSync(item, dependencies);
                        } catch (err) {
							resolvingDone(err);
                        }

						if (!hasDoneCallback) {
							resolvingDone(null, obj);
						}
					}
				};

                if (dependencyNames[index] === 'done') {
                    hasDoneCallback = true;
					if (item.factory && hasDoneCallback) {
						dependencyCallback(null, resolvingDone);
					} else {
						dependencyCallback(null, function (err) {
							resolvingDone(err, obj);
						});
					}
                    return;
                }

				_resolve(dependencyNames[index], container, resolveChain.slice(0), dependencyCallback);

			})(i);

		}

	};

	Sandal = function () {
		this.clear();
	};

	Sandal.prototype.service = function (name, ctor, transient) {
		if (typeof ctor !== 'function') {
			throw new Error('Service must be a function');
		}
		_register(this.container, name, {
			ctor: ctor,
			lifecycle: transient ? 'transient' : 'singleton'
		});
		return this;
	};

	Sandal.prototype.factory = function (name, factory, transient) {
		if (typeof factory !== 'function') {
			throw new Error('Function required');
		}
		_register(this.container, name, {
			factory: factory,
			lifecycle: transient ? 'transient' : 'singleton'
		});
		return this;
	};

	Sandal.prototype.object = function (name, obj) {
		_register(this.container, name, {
			singleton: obj,
			lifecycle: 'singleton'
		});
		return this;
	};

	Sandal.prototype.resolve = function (arg1, arg2) {

		var that = this, callback, itemNames, itemCount, resolvedCount, resolved, i;

		if (typeof arg1 === 'string') {
            itemNames = [ arg1 ];
			callback = arg2;
		} else if (typeof arg1 === 'function') {
			callback = arg1;
		} else {
            itemNames = arg1;
			callback = arg2;
		}

		if (typeof callback !== 'function') {
			throw new Error('Callback function required');
		}

		if (!itemNames) {
            itemNames = _getArgumentNames(callback);
            itemNames = itemNames.splice(1);
		}

        itemCount = itemNames.length;
        if (itemCount === 0) {
            callback(null);
            return;
        }

		resolvedCount = 0;
		resolved = [];
		for (i = 0; i < itemCount; i++) {
			(function (index) {
				_resolve(itemNames[index], that.container, [], function (err, svc) {
					resolvedCount++;
					resolved[0] = resolved[0] || err;
					resolved[index + 1] = svc;
					if (resolvedCount === itemCount) {
						callback.apply({}, resolved);
					}
				});
			})(i);
		}
		return this;
	};

	Sandal.prototype.remove = function (names) {
		if (!names) {
			return this;
		}
		if (typeof names === 'string') {
			names = [ names ];
		}
		for (var i = 0; i < names.length; i++) {
			if (names[i] === 'sandal' || names[i] === 'done') {
				throw new Error('Removing ' + names[i] + ' is not allowed');
			}
			delete this.container[names[i]];
		}
		return this;
	};

	Sandal.prototype.clear = function () {
		this.container = {
			sandal: {
				singleton: this,
				lifecycle: 'singleton'
			}
		};
		return this;
	};

	return Sandal;

})();

if (module && module.exports) {
	module.exports = Sandal;
}<commit_msg>Improved registaration error messages<commit_after>'use strict';

var Sandal = (function () {

    var Sandal, _getArgumentNames, _register, _hasCircularDependencies, _callResolvedCallbacks, _createObjectSync, _resolve;

	_register = function (container, name, item) {
		if (name === 'done' || container[name]) {
			throw new Error(name + ' is already registered');
		}
		container[name] = item;
	};

	_getArgumentNames = function (func) {
		var functionString, argumentList;
		functionString = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '');
		argumentList = functionString.slice(functionString.indexOf('(') + 1, functionString.indexOf(')')).match(/([^\s,]+)/g);
		if (argumentList === null) {
			argumentList = [];
		}
		return argumentList;
	};

	_hasCircularDependencies = function (dependencyNames, resolveChain) {
		var i, j;
		for (j = 0; j < dependencyNames.length; j++) {
			for (i = 0; i < resolveChain.length; i++) {
				if (resolveChain[i] === dependencyNames[j]) {
					return true;
				}
			}
		}
		return false;
	};

	_callResolvedCallbacks = function (err, item) {
		for (var i = 0; i < item.resolvedCallbacks.length; i++) {
            item.resolvedCallbacks[i](err);
		}
        item.resolvedCallbacks = [];
        item.isResolving = false;
	};

    _createObjectSync = function (item, dependencies) {
        if (item.ctor) {
            var obj = Object.create(item.ctor.prototype);
            item.ctor.prototype.constructor.apply(obj, dependencies);
            return obj;
        } else {
            return item.factory.apply(null, dependencies);
        }
    };

	_resolve = function (name, container, resolveChain, callback) {

		var i, obj, resolvingDone, isDone, item, dependencyNames, dependencyCount, dependencies, hasDoneCallback, resolvedDependenciesCount;

        resolveChain.push(name);

        item = container[name];

        if (!item) {
            callback(new Error('No implementation registered for ' + name));
            return;
        }

		resolvingDone = function (err, obj) {
            if (!isDone) {
                isDone = true;
                if (item.lifecycle === 'singleton') {
                    item.singleton = obj;
                    _callResolvedCallbacks(err, item);
                } else {
                    callback(err, obj);
                }
            }
        };

        if (item.lifecycle === 'singleton') {

            item.resolvedCallbacks = item.resolvedCallbacks || [];
            item.resolvedCallbacks.push(function (err) {
                callback(err, item.singleton);
            });

            if (item.isResolving) {
                return;
            }
            item.isResolving = true;

            if (item.hasOwnProperty('singleton')) {
				resolvingDone(null, item.singleton);
                return;
            }

        }

		if (!item.ctor && !item.factory) {
			resolvingDone(new Error('No valid implementation registered for ' + name));
			return;
		}

		dependencyNames = _getArgumentNames(item.ctor || item.factory);
		if (_hasCircularDependencies(dependencyNames, resolveChain)) {
			resolvingDone(new Error('There are circular dependencies in resolve chain: ' + resolveChain));
            return;
		}

		dependencyCount = dependencyNames.length;
		if (dependencyCount === 0) {
            try {
                obj = _createObjectSync(item, []);
				resolvingDone(null, obj);
            } catch (err) {
				resolvingDone(err);
            }
			return;
		}

		dependencies = [];
		hasDoneCallback = false;
		resolvedDependenciesCount = 0;
		for (i = 0; i < dependencyCount; i++) {

			(function (index) {

				var dependencyCallback = function (err, dependency) {

                    if (err) {
						resolvingDone(err);
						return;
					}
					dependencies[index] = dependency;
					resolvedDependenciesCount++;

					if (resolvedDependenciesCount === dependencyCount) {

                        try {
                            obj = _createObjectSync(item, dependencies);
                        } catch (err) {
							resolvingDone(err);
                        }

						if (!hasDoneCallback) {
							resolvingDone(null, obj);
						}
					}
				};

                if (dependencyNames[index] === 'done') {
                    hasDoneCallback = true;
					if (item.factory && hasDoneCallback) {
						dependencyCallback(null, resolvingDone);
					} else {
						dependencyCallback(null, function (err) {
							resolvingDone(err, obj);
						});
					}
                    return;
                }

				_resolve(dependencyNames[index], container, resolveChain.slice(0), dependencyCallback);

			})(i);

		}

	};

	Sandal = function () {
		this.clear();
	};

	Sandal.prototype.service = function (name, ctor, transient) {
		if (typeof ctor !== 'function') {
			throw new Error('Service "' + name + '" must be a function');
		}
		_register(this.container, name, {
			ctor: ctor,
			lifecycle: transient ? 'transient' : 'singleton'
		});
		return this;
	};

	Sandal.prototype.factory = function (name, factory, transient) {
		if (typeof factory !== 'function') {
			throw new Error('Factory "' + name + '" must be a function');
		}
		_register(this.container, name, {
			factory: factory,
			lifecycle: transient ? 'transient' : 'singleton'
		});
		return this;
	};

	Sandal.prototype.object = function (name, obj) {
		_register(this.container, name, {
			singleton: obj,
			lifecycle: 'singleton'
		});
		return this;
	};

	Sandal.prototype.resolve = function (arg1, arg2) {

		var that = this, callback, itemNames, itemCount, resolvedCount, resolved, i;

		if (typeof arg1 === 'string') {
            itemNames = [ arg1 ];
			callback = arg2;
		} else if (typeof arg1 === 'function') {
			callback = arg1;
		} else {
            itemNames = arg1;
			callback = arg2;
		}

		if (typeof callback !== 'function') {
			throw new Error('Callback function required');
		}

		if (!itemNames) {
            itemNames = _getArgumentNames(callback);
            itemNames = itemNames.splice(1);
		}

        itemCount = itemNames.length;
        if (itemCount === 0) {
            callback(null);
            return;
        }

		resolvedCount = 0;
		resolved = [];
		for (i = 0; i < itemCount; i++) {
			(function (index) {
				_resolve(itemNames[index], that.container, [], function (err, svc) {
					resolvedCount++;
					resolved[0] = resolved[0] || err;
					resolved[index + 1] = svc;
					if (resolvedCount === itemCount) {
						callback.apply({}, resolved);
					}
				});
			})(i);
		}
		return this;
	};

	Sandal.prototype.remove = function (names) {
		if (!names) {
			return this;
		}
		if (typeof names === 'string') {
			names = [ names ];
		}
		for (var i = 0; i < names.length; i++) {
			if (names[i] === 'sandal' || names[i] === 'done') {
				throw new Error('Removing ' + names[i] + ' is not allowed');
			}
			delete this.container[names[i]];
		}
		return this;
	};

	Sandal.prototype.clear = function () {
		this.container = {
			sandal: {
				singleton: this,
				lifecycle: 'singleton'
			}
		};
		return this;
	};

	return Sandal;

})();

if (module && module.exports) {
	module.exports = Sandal;
}<|endoftext|>


<commit_before>var portsToColorByHosts = function (hosts, port, color) {
    // Changes the status of provided port to provided color by Array of hosts
    // for lair-blue, lair-orange, lair-red; Host status is updated to COLOR also
    //
    // Created by: Matt Burch
    // Usage: portsToColorByHosts(["192.168.1.1","192.168.1.2"],80,'lair-blue');
    // Supported Colors: console.log(STATUS_MAP)
    //
    // Requires client-side updates: true
    var HOSTTargets = hosts;
    var PORT = port;
    var COLOR = color;
    var PROJECT_ID = Session.get('projectId');
    var MODIFIED_BY = Meteor.user().emails[0].address;
    var COUNT = 0;
    var STATUS = {
        'lair-red': 4,
        'lair-orange': 3,
        'lair-blue': 2,
        'lair-green': 0,
        'lair-grey': 0
    };

    if (STATUS_MAP.indexOf(COLOR) === -1) {
        console.log("Lair Supported colors: " + STATUS_MAP);
        throw {
            name: "Wrong Color",
            message: "Provided COLOR: \"" + COLOR + "\" is not Lair compliant"
        };
    }
    HOSTTargets.forEach(function (target) {
        host = Hosts.findOne({
            project_id: PROJECT_ID,
            'string_addr': target
        });
        hostPort = Ports.find({
            'host_id': host._id,
            'port': PORT
        }).fetch();
        if (typeof hostPort == 'undefined') {
            return;
        } else {
            hostPort.forEach(function (port) {
                console.log("Updating: " + target + ":" + port.port + "/" + port.protocol);
                Meteor.call("setPortStatus", PROJECT_ID, port._id, COLOR);
                if (STATUS[COLOR] > STATUS[host.status]) {
                    console.log("Updating: " + target + " status \"" + COLOR + "\"");
                    Meteor.call("setHostStatus", PROJECT_ID, host._id, COLOR);
                }
                COUNT++;
            });
        }
    });
    console.log(COUNT + " port(s) updated");
};<commit_msg>fix comparison and minor cleanup<commit_after>var portsToColorByHosts = function (hosts, port, color) {
    // Changes the status of provided port to provided color by Array of hosts
    // for lair-blue, lair-orange, lair-red; Host status is updated to COLOR also
    //
    // Created by: Matt Burch
    // Usage: portsToColorByHosts(['192.168.1.1','192.168.1.2'],80,'lair-blue');
    // Supported Colors: console.log(STATUS_MAP)
    //
    // Requires client-side updates: true
    var HOSTTargets = hosts;
    var PORT = port;
    var COLOR = color;
    var PROJECT_ID = Session.get('projectId');
    var MODIFIED_BY = Meteor.user().emails[0].address;
    var COUNT = 0;
    var STATUS = {
        'lair-red': 4,
        'lair-orange': 3,
        'lair-blue': 2,
        'lair-green': 0,
        'lair-grey': 0
    };

    if (STATUS_MAP.indexOf(COLOR) === -1) {
        console.log('Lair Supported colors: ' + STATUS_MAP);
        throw {
            name: 'Wrong Color',
            message: 'Provided COLOR: \"' + COLOR + '\" is not Lair compliant'
        };
    }
    HOSTTargets.forEach(function (target) {
        var host = Hosts.findOne({
            project_id: PROJECT_ID,
            'string_addr': target
        });
        var hostPort = Ports.find({
            'host_id': host._id,
            'port': PORT
        }).fetch();
        if (hostPort.length < 1) {
            return;
        }

        hostPort.forEach(function (port) {
            console.log('Updating: ' + target + ':' + port.port + '/' + port.protocol);
            Meteor.call('setPortStatus', PROJECT_ID, port._id, COLOR);
            if (STATUS[COLOR] > STATUS[host.status]) {
                console.log('Updating: ' + target + ' status \"' + COLOR + '\"');
                Meteor.call('setHostStatus', PROJECT_ID, host._id, COLOR);
            }
            COUNT++;
        });
    });
    console.log(COUNT + ' port(s) updated');
};<|endoftext|>


<commit_before>/**
 * Backbone localStorage Adapter
 * Version 1.1.7
 *
 * https://github.com/jeromegn/Backbone.localStorage
 */
(function (root, factory) {
   if (typeof exports === 'object' && typeof require === 'function') {
     module.exports = factory(require("backbone"));
   } else if (typeof define === "function" && define.amd) {
      // AMD. Register as an anonymous module.
      define(["backbone"], function(Backbone) {
        // Use global variables if the locals are undefined.
        return factory(Backbone || root.Backbone);
      });
   } else {
      // RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
      factory(Backbone);
   }
}(this, function(Backbone) {
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.

// Hold reference to Underscore.js and Backbone.js in the closure in order
// to make things work even if they are removed from the global namespace

// Generate four random hex digits.
function S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};

// Generate a pseudo-GUID by concatenating random hexadecimal.
function guid() {
   return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};

function contains(array, item) {
  var i = array.length;
  while (i--) if (array[i] === obj) return true;
  return false;
}

function extend(obj, props) {
  for (var key in props) obj[key] = props[key]
  return obj;
}

// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead
Backbone.LocalStorage = window.Store = function(name) {
  if( !this.localStorage ) {
    throw "Backbone.localStorage: Environment does not support localStorage."
  }
  this.name = name;
  var store = this.localStorage().getItem(this.name);
  this.records = (store && store.split(",")) || [];
};

extend(Backbone.LocalStorage.prototype, {

  // Save the current state of the **Store** to *localStorage*.
  save: function() {
    this.localStorage().setItem(this.name, this.records.join(","));
  },

  // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
  // have an id of it's own.
  create: function(model) {
    if (!model.id) {
      model.id = guid();
      model.set(model.idAttribute, model.id);
    }
    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
    this.records.push(model.id.toString());
    this.save();
    return this.find(model);
  },

  // Update a model by replacing its copy in `this.data`.
  update: function(model) {
    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
    var modelId = model.id.toString();
    if (!contains(this.records, modelId)) {
      this.records.push(modelId);
      this.save();
    }
    return this.find(model);
  },

  // Retrieve a model from `this.data` by id.
  find: function(model) {
    return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
  },

  // Return the array of all models currently in storage.
  findAll: function() {
    var result = [];
    for (var i = 0, id, data; i < this.records.length; i++) {
      id = this.records[i];
      data = this.jsonData(this.localStorage().getItem(this.name+"-"+id));
      if (data != null) result.push(data);
    }
    return result;
  },

  // Delete a model from `this.data`, returning it.
  destroy: function(model) {
    if (model.isNew())
      return false
    this.localStorage().removeItem(this.name+"-"+model.id);
    var modelId = model.id.toString();
    for (var i = 0, id; i < this.records.length; i++) {
      if (this.records[i] === modelId) {
        this.records.splice(i, 1);
      }
    }
    this.save();
    return model;
  },

  localStorage: function() {
    return localStorage;
  },

  // fix for "illegal access" error on Android when JSON.parse is passed null
  jsonData: function (data) {
      return data && JSON.parse(data);
  },

  // Clear localStorage for specific collection.
  _clear: function() {
    var local = this.localStorage(),
      itemRe = new RegExp("^" + this.name + "-");

    // Remove id-tracking item (e.g., "foo").
    local.removeItem(this.name);

    // Match all data items (e.g., "foo-ID") and remove.
    for (var k in local) {
      if (itemRe.test(k)) {
        local.removeItem(k);
      }
    }

    this.records.length = 0;
  },

  // Size of localStorage.
  _storageSize: function() {
    return this.localStorage().length;
  }

});

// localSync delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
  var store = model.localStorage || model.collection.localStorage;

  var resp, errorMessage, syncDfd = Backbone.$.Deferred && Backbone.$.Deferred(); //If $ is having Deferred - use it.

  try {

    switch (method) {
      case "read":
        resp = model.id != undefined ? store.find(model) : store.findAll();
        break;
      case "create":
        resp = store.create(model);
        break;
      case "update":
        resp = store.update(model);
        break;
      case "delete":
        resp = store.destroy(model);
        break;
    }

  } catch(error) {
    if (error.code === 22 && store._storageSize() === 0)
      errorMessage = "Private browsing is unsupported";
    else
      errorMessage = error.message;
  }

  if (resp) {
    if (options && options.success) {
      if (Backbone.VERSION === "0.9.10") {
        options.success(model, resp, options);
      } else {
        options.success(resp);
      }
    }
    if (syncDfd) {
      syncDfd.resolve(resp);
    }

  } else {
    errorMessage = errorMessage ? errorMessage
                                : "Record Not Found";

    if (options && options.error)
      if (Backbone.VERSION === "0.9.10") {
        options.error(model, errorMessage, options);
      } else {
        options.error(errorMessage);
      }

    if (syncDfd)
      syncDfd.reject(errorMessage);
  }

  // add compatibility with $.ajax
  // always execute callback for success and error
  if (options && options.complete) options.complete(resp);

  return syncDfd && syncDfd.promise();
};

Backbone.ajaxSync = Backbone.sync;

Backbone.getSyncMethod = function(model) {
  if(model.localStorage || (model.collection && model.collection.localStorage)) {
    return Backbone.localSync;
  }

  return Backbone.ajaxSync;
};

// Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone.sync = function(method, model, options) {
  return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
};

return Backbone.LocalStorage;
}));
<commit_msg>Fix jQuery dependency when Backbone.$ is null.<commit_after>/**
 * Backbone localStorage Adapter
 * Version 1.1.7
 *
 * https://github.com/jeromegn/Backbone.localStorage
 */
(function (root, factory) {
   if (typeof exports === 'object' && typeof require === 'function') {
     module.exports = factory(require("backbone"));
   } else if (typeof define === "function" && define.amd) {
      // AMD. Register as an anonymous module.
      define(["backbone"], function(Backbone) {
        // Use global variables if the locals are undefined.
        return factory(Backbone || root.Backbone);
      });
   } else {
      // RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
      factory(Backbone);
   }
}(this, function(Backbone) {
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.

// Hold reference to Underscore.js and Backbone.js in the closure in order
// to make things work even if they are removed from the global namespace

// Generate four random hex digits.
function S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};

// Generate a pseudo-GUID by concatenating random hexadecimal.
function guid() {
   return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};

function contains(array, item) {
  var i = array.length;
  while (i--) if (array[i] === obj) return true;
  return false;
}

function extend(obj, props) {
  for (var key in props) obj[key] = props[key]
  return obj;
}

// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead
Backbone.LocalStorage = window.Store = function(name) {
  if( !this.localStorage ) {
    throw "Backbone.localStorage: Environment does not support localStorage."
  }
  this.name = name;
  var store = this.localStorage().getItem(this.name);
  this.records = (store && store.split(",")) || [];
};

extend(Backbone.LocalStorage.prototype, {

  // Save the current state of the **Store** to *localStorage*.
  save: function() {
    this.localStorage().setItem(this.name, this.records.join(","));
  },

  // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
  // have an id of it's own.
  create: function(model) {
    if (!model.id) {
      model.id = guid();
      model.set(model.idAttribute, model.id);
    }
    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
    this.records.push(model.id.toString());
    this.save();
    return this.find(model);
  },

  // Update a model by replacing its copy in `this.data`.
  update: function(model) {
    this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
    var modelId = model.id.toString();
    if (!contains(this.records, modelId)) {
      this.records.push(modelId);
      this.save();
    }
    return this.find(model);
  },

  // Retrieve a model from `this.data` by id.
  find: function(model) {
    return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
  },

  // Return the array of all models currently in storage.
  findAll: function() {
    var result = [];
    for (var i = 0, id, data; i < this.records.length; i++) {
      id = this.records[i];
      data = this.jsonData(this.localStorage().getItem(this.name+"-"+id));
      if (data != null) result.push(data);
    }
    return result;
  },

  // Delete a model from `this.data`, returning it.
  destroy: function(model) {
    if (model.isNew())
      return false
    this.localStorage().removeItem(this.name+"-"+model.id);
    var modelId = model.id.toString();
    for (var i = 0, id; i < this.records.length; i++) {
      if (this.records[i] === modelId) {
        this.records.splice(i, 1);
      }
    }
    this.save();
    return model;
  },

  localStorage: function() {
    return localStorage;
  },

  // fix for "illegal access" error on Android when JSON.parse is passed null
  jsonData: function (data) {
      return data && JSON.parse(data);
  },

  // Clear localStorage for specific collection.
  _clear: function() {
    var local = this.localStorage(),
      itemRe = new RegExp("^" + this.name + "-");

    // Remove id-tracking item (e.g., "foo").
    local.removeItem(this.name);

    // Match all data items (e.g., "foo-ID") and remove.
    for (var k in local) {
      if (itemRe.test(k)) {
        local.removeItem(k);
      }
    }

    this.records.length = 0;
  },

  // Size of localStorage.
  _storageSize: function() {
    return this.localStorage().length;
  }

});

// localSync delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
  var store = model.localStorage || model.collection.localStorage;

  var resp, errorMessage;
  //If $ is having Deferred - use it.
  var syncDfd = Backbone.$ ?
    (Backbone.$.Deferred && Backbone.$.Deferred()) :
    (Backbone.Deferred && Backbone.Deferred());

  try {

    switch (method) {
      case "read":
        resp = model.id != undefined ? store.find(model) : store.findAll();
        break;
      case "create":
        resp = store.create(model);
        break;
      case "update":
        resp = store.update(model);
        break;
      case "delete":
        resp = store.destroy(model);
        break;
    }

  } catch(error) {
    if (error.code === 22 && store._storageSize() === 0)
      errorMessage = "Private browsing is unsupported";
    else
      errorMessage = error.message;
  }

  if (resp) {
    if (options && options.success) {
      if (Backbone.VERSION === "0.9.10") {
        options.success(model, resp, options);
      } else {
        options.success(resp);
      }
    }
    if (syncDfd) {
      syncDfd.resolve(resp);
    }

  } else {
    errorMessage = errorMessage ? errorMessage
                                : "Record Not Found";

    if (options && options.error)
      if (Backbone.VERSION === "0.9.10") {
        options.error(model, errorMessage, options);
      } else {
        options.error(errorMessage);
      }

    if (syncDfd)
      syncDfd.reject(errorMessage);
  }

  // add compatibility with $.ajax
  // always execute callback for success and error
  if (options && options.complete) options.complete(resp);

  return syncDfd && syncDfd.promise();
};

Backbone.ajaxSync = Backbone.sync;

Backbone.getSyncMethod = function(model) {
  if(model.localStorage || (model.collection && model.collection.localStorage)) {
    return Backbone.localSync;
  }

  return Backbone.ajaxSync;
};

// Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone.sync = function(method, model, options) {
  return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
};

return Backbone.LocalStorage;
}));
<|endoftext|>


<commit_before>//    Backbone XMPP PubSub Storage v0.1

//    (c) 2012 Yiorgis Gozadinos, Riot AS.
//    Backbone.xmpp is distributed under the MIT license.
//    http://github.com/ggozad/Backbone.xmpp

// A simple module to replace **Backbone.sync** with *XMPP PubSub*-based
// persistence.

(function ($, _, Backbone, Strophe) {

    // A PubSub node acting as storage.
    // Create it with the `id` the node has on the XMPP server,
    // and a Strophe `connection`.
    var PubSubNodeStorage = function(id, connection) {
        this.id = id;
        this.connection = connection;
    };

    // Attach methods to **PubSubNodeStorage**.
    _.extend(PubSubNodeStorage.prototype, {

        // **create** publishes to the node the model in JSON format.
        //Resolves by setting and returning the `id` of the item.
        create: function(model) {
            var d = $.Deferred(),
                entry = $build('entry').t(JSON.stringify(model.toJSON())).tree(),
                p = this.connection.PubSub.publish(this.id, entry);
            p.done(function (id) {
                model.id = id;
                d.resolve(model);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **update** a model by re-publishing it on the node.
        update: function(model) {
            var d = $.Deferred(),
                entry = $build('entry').t(JSON.stringify(model.toJSON())).tree(),
                p = this.connection.PubSub.publish(this.id, entry, model.id);
            p.done(function (id) {
                d.resolve(model);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **getItem** retrieves a model from the node by `id`.
        // Resolves by returning the attributes that are different and their values.
        getItem: function(model) {
            var d = $.Deferred(),
                p = this.connection.PubSub.items(this.id, {item_ids: [model.id]});
            p.done(function (item) {
                var updated = {},
                    attrs = JSON.parse($('entry', item).text());
                _.each(attrs, function (value, key) {
                    if (model.get(key) !== value) updated[key] = value;
                });
                d.resolve(updated);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **getItems** resolves by returning the array of all models currently published on the node.
        getItems: function() {
            var d = $.Deferred(),
                p = this.connection.PubSub.items(this.id);
            p.done(function (items) {
                var id, attrs;
                d.resolve(_.map(items, function (item) {
                    attrs = JSON.parse($('entry', item).text());
                    attrs.id = $(item).attr('id');
                    return attrs;
                }));
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **destroy** deletes the item correcsponding to the `model` from the node.
        // Resolves by returning the `model`.
        destroy: function(model) {
            var d = $.Deferred(),
                p = this.connection.PubSub.deleteItem(this.id, model.id);
            p.done(function () { d.resolve(model); });
            p.fail(d.reject);
            return d.promise();
        }

    });

    // **xmppAsync** is the replacement for **sync**. It delegates sync operations
    // to the model or collection's `node` property, which should be an instance
    // of **PubSubNodeStorage**.
    Backbone.xmppSync = function(method, model, options) {

        var p,
            node = model.node || (model.collection && model.collection.node);

        // If there is no node, fail directly, somebody did not read the docs.
        if (!node) return $.Deferred().reject().promise();

        switch (method) {
            case "read":    p = typeof model.id !== 'undefined' ? node.getItem(model) : node.getItems(); break;
            case "create":  p = node.create(model); break;
            case "update":  p = node.update(model); break;
            case "delete":  p = node.destroy(model); break;
        }

        // Fallback for old-style callbacks.
        options = options || {};
        if (options.success) p.done(options.success);
        if (options.error) p.fail(options.error);

        return p;
    };

    this.PubSubNodeStorage = PubSubNodeStorage;

})(this.jQuery, this._, this.Backbone, this.Strophe);
<commit_msg>Allow the PubSubNodeStorage to be specified by the node attribute or the node() function<commit_after>//    Backbone XMPP PubSub Storage v0.1

//    (c) 2012 Yiorgis Gozadinos, Riot AS.
//    Backbone.xmpp is distributed under the MIT license.
//    http://github.com/ggozad/Backbone.xmpp

// A simple module to replace **Backbone.sync** with *XMPP PubSub*-based
// persistence.

(function ($, _, Backbone, Strophe) {

    // A PubSub node acting as storage.
    // Create it with the `id` the node has on the XMPP server,
    // and a Strophe `connection`.
    var PubSubNodeStorage = function(id, connection) {
        this.id = id;
        this.connection = connection;
    };

    // Attach methods to **PubSubNodeStorage**.
    _.extend(PubSubNodeStorage.prototype, {

        // **create** publishes to the node the model in JSON format.
        //Resolves by setting and returning the `id` of the item.
        create: function(model) {
            var d = $.Deferred(),
                entry = $build('entry').t(JSON.stringify(model.toJSON())).tree(),
                p = this.connection.PubSub.publish(this.id, entry);
            p.done(function (id) {
                model.id = id;
                d.resolve(model);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **update** a model by re-publishing it on the node.
        update: function(model) {
            var d = $.Deferred(),
                entry = $build('entry').t(JSON.stringify(model.toJSON())).tree(),
                p = this.connection.PubSub.publish(this.id, entry, model.id);
            p.done(function (id) {
                d.resolve(model);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **getItem** retrieves a model from the node by `id`.
        // Resolves by returning the attributes that are different and their values.
        getItem: function(model) {
            var d = $.Deferred(),
                p = this.connection.PubSub.items(this.id, {item_ids: [model.id]});
            p.done(function (item) {
                var updated = {},
                    attrs = JSON.parse($('entry', item).text());
                _.each(attrs, function (value, key) {
                    if (model.get(key) !== value) updated[key] = value;
                });
                d.resolve(updated);
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **getItems** resolves by returning the array of all models currently published on the node.
        getItems: function() {
            var d = $.Deferred(),
                p = this.connection.PubSub.items(this.id);
            p.done(function (items) {
                var id, attrs;
                d.resolve(_.map(items, function (item) {
                    attrs = JSON.parse($('entry', item).text());
                    attrs.id = $(item).attr('id');
                    return attrs;
                }));
            });
            p.fail(d.reject);
            return d.promise();
        },

        // **destroy** deletes the item correcsponding to the `model` from the node.
        // Resolves by returning the `model`.
        destroy: function(model) {
            var d = $.Deferred(),
                p = this.connection.PubSub.deleteItem(this.id, model.id);
            p.done(function () { d.resolve(model); });
            p.fail(d.reject);
            return d.promise();
        }

    });

    // **xmppAsync** is the replacement for **sync**. It delegates sync operations
    // to the model or collection's `node` property, which should be an instance
    // of **PubSubNodeStorage**.
    Backbone.xmppSync = function(method, model, options) {

        var p,
            node = (model.node || model.node())||
                   (model.collection && (model.collection.node || model.connection.node()));

        // If there is no node, fail directly, somebody did not read the docs.
        if (!node) return $.Deferred().reject().promise();

        switch (method) {
            case "read":    p = typeof model.id !== 'undefined' ? node.getItem(model) : node.getItems(); break;
            case "create":  p = node.create(model); break;
            case "update":  p = node.update(model); break;
            case "delete":  p = node.destroy(model); break;
        }

        // Fallback for old-style callbacks.
        options = options || {};
        if (options.success) p.done(options.success);
        if (options.error) p.fail(options.error);

        return p;
    };

    this.PubSubNodeStorage = PubSubNodeStorage;

})(this.jQuery, this._, this.Backbone, this.Strophe);
<|endoftext|>


<commit_before>'use strict';

// todo: sanitize this along with its auths

var AWS = require('aws-sdk');

var config = require('../config/config');
var settings = require('./settings');

AWS.config.region = config.region;

const s3 = new AWS.S3();
const amazonIAM = new AWS.IAM();

function setupBuckets() {
  settings.set('bucketName', config.bucketName);
  return Promise.resolve()
  .then(createBucket)
  .then(attachCORSToBucket)
  .then(createWriteBucketPolicy)
  .then(attachWriteBucketPolicyToAuthRole)
  ;
}

function createBucket() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property
    Bucket: config.bucketName,
    CreateBucketConfiguration: {
      LocationConstraint: config.region,
    },
  };
  return s3.createBucket(params).promise()
  .then(data => {
    console.log("createBucket -> %j", data);
    return data;
  });
}

function attachCORSToBucket() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketCors-property
    Bucket: config.bucketName,
    CORSConfiguration: {
      CORSRules: [{
        AllowedMethods: ['GET', 'PUT', 'POST'],
        AllowedOrigins: ['*'],
        AllowedHeaders: ['*'],
        ExposeHeaders: ['ETag', 'x-amz-meta-custom-header'],
        MaxAgeSeconds: 3000
      }]
    }
  };
  return s3.putBucketCors(params).promise()
  .then(data => {
    console.log("putBucketCors -> %j", data);
    return data;
  });
}

function createWriteBucketPolicy() {
  var policy = {
    Version: "2012-10-17",
    Statement: [{
      Effect: "Allow",
      Action: [
        "s3:GetObject",
        "s3:PutObject",
        "s3:putObjectACL"
      ],
      Resource: [
        "arn:aws:s3:::" + settings.get('bucketName') + "/" + config.uploadFileName,
      ]
    }]
  };
  var policyJson = JSON.stringify(policy, null, 2);
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/IAM.html#createPolicy-property
    PolicyName: config.authBucketPolicyName,
    Description: 'Write to bucket',
    PolicyDocument: policyJson,
  };
  return amazonIAM.createPolicy(params).promise()
  .then(data => {
    console.log("createPolicy -> %j", data);
    console.log("createPolicy -> arn:", data.Policy.Arn);
    settings.set('bucketAuthPolicyArn', data.Policy.Arn);
    return data;
  });
}

function attachWriteBucketPolicyToAuthRole() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/IAM.html#attachRolePolicy-property
    RoleName: config.authRoleName,
    PolicyArn: settings.get('bucketAuthPolicyArn'),
  };
  return amazonIAM.attachRolePolicy(params).promise()
  .then(data => {
    console.log("attachRolePolicy -> %j", data);
    return data;
  });
}

module.exports = setupBuckets;
<commit_msg>buckets: include DELETE in CORS permissions<commit_after>'use strict';

// todo: sanitize this along with its auths

var AWS = require('aws-sdk');

var config = require('../config/config');
var settings = require('./settings');

AWS.config.region = config.region;

const s3 = new AWS.S3();
const amazonIAM = new AWS.IAM();

function setupBuckets() {
  settings.set('bucketName', config.bucketName);
  return Promise.resolve()
  .then(createBucket)
  .then(attachCORSToBucket)
  .then(createWriteBucketPolicy)
  .then(attachWriteBucketPolicyToAuthRole)
  ;
}

function createBucket() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property
    Bucket: config.bucketName,
    CreateBucketConfiguration: {
      LocationConstraint: config.region,
    },
  };
  return s3.createBucket(params).promise()
  .then(data => {
    console.log("createBucket -> %j", data);
    return data;
  });
}

function attachCORSToBucket() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketCors-property
    Bucket: config.bucketName,
    CORSConfiguration: {
      CORSRules: [{
        AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
        AllowedOrigins: ['*'],
        AllowedHeaders: ['*'],
        ExposeHeaders: ['ETag', 'x-amz-meta-custom-header'],
        MaxAgeSeconds: 3000
      }]
    }
  };
  return s3.putBucketCors(params).promise()
  .then(data => {
    console.log("putBucketCors -> %j", data);
    return data;
  });
}

function createWriteBucketPolicy() {
  var policy = {
    Version: "2012-10-17",
    Statement: [{
      Effect: "Allow",
      Action: [
        "s3:GetObject",
        "s3:PutObject",
        "s3:putObjectACL"
      ],
      Resource: [
        "arn:aws:s3:::" + settings.get('bucketName') + "/" + config.uploadFileName,
      ]
    }]
  };
  var policyJson = JSON.stringify(policy, null, 2);
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/IAM.html#createPolicy-property
    PolicyName: config.authBucketPolicyName,
    Description: 'Write to bucket',
    PolicyDocument: policyJson,
  };
  return amazonIAM.createPolicy(params).promise()
  .then(data => {
    console.log("createPolicy -> %j", data);
    console.log("createPolicy -> arn:", data.Policy.Arn);
    settings.set('bucketAuthPolicyArn', data.Policy.Arn);
    return data;
  });
}

function attachWriteBucketPolicyToAuthRole() {
  const params = {
    // see http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/IAM.html#attachRolePolicy-property
    RoleName: config.authRoleName,
    PolicyArn: settings.get('bucketAuthPolicyArn'),
  };
  return amazonIAM.attachRolePolicy(params).promise()
  .then(data => {
    console.log("attachRolePolicy -> %j", data);
    return data;
  });
}

module.exports = setupBuckets;
<|endoftext|>


<commit_before>/**
 * Created by hensleym on 7/13/15.
 *
 * Thanks to http://zeroviscosity.com/d3-js-step-by-step/step-2-a-basic-donut-chart
 * for the tutorial on making donut charts.
 */
(function(){
    'use strict';

    angular
        .module('chartTopperDemo')
        .service('donutChart', donutChart);

        function donutChart() {

            return{
                build: build
            };

            function build(data, element) {

                //Fit width to parent
                var width = $(element).parent().width(),
                    height = 300,
                    radius = Math.min(width, height) / 2;

                //Create default d3 color scale - will rotate in with d3.ordinal.colors
                var color = d3.scale.category20();

                //Create a pie generator
                var pie = d3.layout.pie();

                //Create the arc inner/outer radius
                var arc = d3.svg.arc()
                    .innerRadius(radius / 2)
                    //How much does this fill the container
                    .outerRadius(radius - 5);

                var outerElement = d3.select(element).append("svg")
                    //Add width
                    .attr("width", width)
                    //add height
                    .attr("height", height);

                outerElement.append("text")
                    .text("Test Text");

                    //add pieces to arc
                var svg = outerElement.append("g")
                        //Center the element
                        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

                svg.append("text")
                   .attr("dy", ".35em")
                   .attr("text-anchor", "middle")
                   .text("Test Text");

                //assemble.
                var path = svg.selectAll("path")
                    .data(pie(data))
                    .enter()
                    .append("path")
                    .attr("stroke", "white")
                    .attr("stroke-width", 0.5)
                    .attr("fill", function(d, i) { return color(i); })
                    .attr("d", arc)

            }
        }
})();<commit_msg>Figured out how to put in the inline text<commit_after>/**
 * Created by hensleym on 7/13/15.
 *
 * Thanks to http://zeroviscosity.com/d3-js-step-by-step/step-2-a-basic-donut-chart
 * for the tutorial on making donut charts.
 */
(function(){
    'use strict';

    angular
        .module('chartTopperDemo')
        .service('donutChart', donutChart);

        function donutChart() {

            return{
                build: build
            };

            function build(data, element) {

                //Fit width to parent
                var width = $(element).parent().width(),
                    height = 300,
                    radius = Math.min(width, height) / 2;

                //Create default d3 color scale - will rotate in with d3.ordinal.colors
                var color = d3.scale.category20();

                //Create a pie generator
                var pie = d3.layout.pie();

                //Create the arc inner/outer radius
                var arc = d3.svg.arc()
                    .innerRadius(radius / 2)
                    //How much does this fill the container
                    .outerRadius(radius - 5);

                var outerElement = d3.select(element).append("svg")
                    //Add width
                    .attr("width", width)
                    //add height
                    .attr("height", height);

                    //add pieces to arc
                var svg = outerElement.append("g")
                        //Center the element
                        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

                //assemble.
                var path = svg.selectAll("path")
                    .data(pie(data))
                    .enter()
                    .append("path")
                    .attr("stroke", "white")
                    .attr("stroke-width", 0.5)
                    .attr("fill", function(d, i) { return color(i); })
                    .attr("d", arc);

                svg.selectAll("text")
                    .data(pie(data))
                    .enter()
                    .append("text")
                    .attr("transform", function(d) {return "translate(" + arc.centroid(d) + ")"; })
                    .attr("text-anchor", "middle")
                    .text(function(d){
                        return d.value;
                    });

                svg.append("text")
                    .attr("dy", ".35em")
                    .attr("text-anchor", "middle")
                    .text("Test Text");

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


<commit_before>// Usage is "phantomjs-survey_snapshot.js <output_file> <width> <height> <wait_time>"

var system = require('system'),
    args = system.args;

if (args.length === 1) {
    console.error('You must at least specify an argument with the URL to open.');
    exit();
}

var page = require('webpage').create(),
    url = args[1],
    destination = 'snapshot.png',
    width = 1024,
    height = 768,
    wait = 10000,
    headerHeight = 85;

if (args.length >= 3) {
    destination = args[2];
    if (args.length >= 4) {
        width = parseInt(args[3]);
        if (args.length >= 5) {
            height = parseInt(args[4]);
            if (args.length >= 6) {
                wait = parseInt(args[5]);
            }
        }
    }
}

// We add extra pixels for the header
height += headerHeight;

// viewportSize being the actual size of the headless browser
page.viewportSize = {
    width: width,
    height: height
};
// the clipRect is the portion of the page you are taking a screenshot of
// We remove the navbar from view
page.clipRect = {
    top: headerHeight,
    left: 0,
    width: width,
    height: height - headerHeight
};
page.open(url, function(status) {
  if(status === "success") {
    page.evaluate(function() {
        // Remove the cookie warning
        var cookie = document.getElementsByClassName('cc_banner-wrapper');
        for (var i=0; i < cookie.length; i++) {
           cookie[i].style.display="none";
        }
        // Remove the login message
        var alert = document.getElementsByClassName('alert');
        for (var j=0; j < alert.length; j++) {
           alert[j].style.display="none";
        }
    });
    window.setTimeout(function () {
        page.evaluate(function() {
            // Disable clustering
            emapic.modules.clustering.toggleClustering($('#clustering-control-activate'));
            // Remove the controls
            var control = document.getElementsByClassName('leaflet-control-container');
            for (var i=0; i < control.length; i++) {
               control[i].style.display="none";
            }
        });
        page.render(destination);
        phantom.exit();
    }, wait);
  }
});
<commit_msg>Remove popovers with css in phantomjs<commit_after>// Usage is "phantomjs-survey_snapshot.js <output_file> <width> <height> <wait_time>"

var system = require('system'),
    args = system.args;

if (args.length === 1) {
    console.error('You must at least specify an argument with the URL to open.');
    exit();
}

var page = require('webpage').create(),
    url = args[1],
    destination = 'snapshot.png',
    width = 1024,
    height = 768,
    wait = 10000,
    headerHeight = 85;

if (args.length >= 3) {
    destination = args[2];
    if (args.length >= 4) {
        width = parseInt(args[3]);
        if (args.length >= 5) {
            height = parseInt(args[4]);
            if (args.length >= 6) {
                wait = parseInt(args[5]);
            }
        }
    }
}

// We add extra pixels for the header
height += headerHeight;

// viewportSize being the actual size of the headless browser
page.viewportSize = {
    width: width,
    height: height
};
// the clipRect is the portion of the page you are taking a screenshot of
// We remove the navbar from view
page.clipRect = {
    top: headerHeight,
    left: 0,
    width: width,
    height: height - headerHeight
};
page.open(url, function(status) {
  if(status === "success") {
    page.evaluate(function() {
        // Remove the cookie warning
        $('<style>.cc_banner-wrapper { display: none; }</style>').appendTo('head');
        // Remove the login message
        $('<style>.alert { display: none; }</style>').appendTo('head');
    });
    window.setTimeout(function () {
        page.evaluate(function() {
            // Disable clustering
            emapic.modules.clustering.toggleClustering($('#clustering-control-activate'));
            // Remove the controls
            var control = document.getElementsByClassName('leaflet-control-container');
            for (var i=0; i < control.length; i++) {
               control[i].style.display="none";
            }
        });
        page.render(destination);
        phantom.exit();
    }, wait);
  }
});
<|endoftext|>


<commit_before>"use strict";
var Exclusions = {
  testers: null,
  getRe: function(pattern) {
    var func = this.testers[pattern], re;
    if (func) { return func; }
    if (pattern[0] === '^' && (re = Utils.makeRegexp(pattern, "", false))) {
      func = re.test.bind(re);
    } else {
      func = this._startsWith.bind(pattern.substring(1));
    }
    return this.testers[pattern] = func;
  },
  _startsWith: function(url) {
    return url.startsWith(this);
  },
  _listening: false,
  rules: [],
  setRules: function(rules) {
    var onURLChange;
    if (rules.length === 0) {
      this.rules = [];
      this.getPattern = function() { return null; };
      if (this._listening && (onURLChange = this.getOnURLChange())) {
        chrome.webNavigation.onHistoryStateUpdated.removeListener(onURLChange);
        chrome.webNavigation.onReferenceFragmentUpdated.removeListener(onURLChange);
      }
      this._listening = false;
      return;
    }
    this.testers || (this.testers = Object.create(null));
    this.rules = this.format(rules);
    this.testers = null;
    if (!this._listening && (onURLChange = this.getOnURLChange())) {
      chrome.webNavigation.onHistoryStateUpdated.addListener(onURLChange);
      chrome.webNavigation.onReferenceFragmentUpdated.addListener(onURLChange);
    }
    this._listening = true;
    this.getPattern = this._getPattern;
  },
  getPattern: null,
  _getPattern: function(url) {
    var rules = this.rules, _i, _len, matchedKeys = "", str;
    for (_i = 0, _len = rules.length; _i < _len; _i++) {
      if (rules[_i][0](url)) {
        str = rules[_i][1];
        if (!str) { return ""; }
        matchedKeys += str;
      }
    }
    return matchedKeys || null;
  },
  getOnURLChange: function() {
    return chrome.webNavigation && (this.onURLChange || g_requestHandlers.checkIfEnabled);
  },
  onURLChange: Settings.CONST.ChromeVersion < 41 && function(details) {
    var ref = Settings.indexPorts(details.tabId), i, msg = { name: "checkIfEnabled" };
    // force the tab's ports to reconnect and refresh their pass keys
    for (i = ref && ref.length; 0 < --i; ) {
      ref[i].postMessage(msg);
    }
  },
  format: function(rules) {
    var _i = rules.length, rule, out = new Array(_i);
    while (0 <= --_i) {
      rule = rules[_i];
      out[_i] = [this.getRe(rule.pattern), rule.passKeys];
    }
    return out;
  },
  getTemp: function(url, rules) {
    var old = this.rules;
    this.rules = this.format(rules);
    url = this._getPattern(url);
    this.rules = old;
    return url;
  },
  RefreshStatus: function(old_is_empty) {
    var ref = Settings.indexPorts(), tabId, frames
      , i, always_enabled, pass, status = "enabled", status0, port;
    always_enabled = Exclusions.rules.length > 0 ? null : {
      name: "reset",
      passKeys: null
    };
    if (old_is_empty) {
      always_enabled || Settings.broadcast({
        name: "checkIfEnabled"
      });
      return;
    }
    for (tabId in ref) {
      frames = ref[tabId];
      status0 = frames[0].sender.status;
      for (i = frames.length; 0 < --i; ) {
        port = frames[i];
        if (always_enabled) {
          if (port.sender.status === "enabled") {
            continue;
          }
        } else {
          pass = Exclusions.getPattern(port.sender.url);
          status = pass === null ? "enabled" : pass ? "partial" : "disabled";
          if (!pass && port.sender.status === status) {
            continue;
          }
        }
        port.postMessage(always_enabled || { name: "reset", passKeys: pass });
        port.sender.status = status;
      }
      if (status0 !== (status = frames[0].sender.status)) {
        g_requestHandlers.SetIcon(tabId | 0, status);
      }
    }
  }
};

Settings.updateHooks.exclusionRules = function(rules) {
  var is_empty = Exclusions.rules.length <= 0;
  Exclusions.setRules(rules);
  g_requestHandlers.esc();
  setTimeout(Exclusions.RefreshStatus, 17, is_empty);
};

Exclusions.setRules(Settings.get("exclusionRules"));
Settings.Init();
<commit_msg>fix a null pointer crash<commit_after>"use strict";
var Exclusions = {
  testers: null,
  getRe: function(pattern) {
    var func = this.testers[pattern], re;
    if (func) { return func; }
    if (pattern[0] === '^' && (re = Utils.makeRegexp(pattern, "", false))) {
      func = re.test.bind(re);
    } else {
      func = this._startsWith.bind(pattern.substring(1));
    }
    return this.testers[pattern] = func;
  },
  _startsWith: function(url) {
    return url.startsWith(this);
  },
  _listening: false,
  rules: [],
  setRules: function(rules) {
    var onURLChange;
    if (rules.length === 0) {
      this.rules = [];
      this.getPattern = function() { return null; };
      if (this._listening && (onURLChange = this.getOnURLChange())) {
        chrome.webNavigation.onHistoryStateUpdated.removeListener(onURLChange);
        chrome.webNavigation.onReferenceFragmentUpdated.removeListener(onURLChange);
      }
      this._listening = false;
      return;
    }
    this.testers || (this.testers = Object.create(null));
    this.rules = this.format(rules);
    this.testers = null;
    if (!this._listening && (onURLChange = this.getOnURLChange())) {
      chrome.webNavigation.onHistoryStateUpdated.addListener(onURLChange);
      chrome.webNavigation.onReferenceFragmentUpdated.addListener(onURLChange);
    }
    this._listening = true;
    this.getPattern = this._getPattern;
  },
  getPattern: null,
  _getPattern: function(url) {
    var rules = this.rules, _i, _len, matchedKeys = "", str;
    for (_i = 0, _len = rules.length; _i < _len; _i++) {
      if (rules[_i][0](url)) {
        str = rules[_i][1];
        if (!str) { return ""; }
        matchedKeys += str;
      }
    }
    return matchedKeys || null;
  },
  getOnURLChange: function() {
    return chrome.webNavigation && (this.onURLChange || g_requestHandlers.checkIfEnabled);
  },
  onURLChange: Settings.CONST.ChromeVersion < 41 && function(details) {
    var ref = Settings.indexPorts(details.tabId), i, msg = { name: "checkIfEnabled" };
    // force the tab's ports to reconnect and refresh their pass keys
    for (i = ref && ref.length; 0 < --i; ) {
      ref[i].postMessage(msg);
    }
  },
  format: function(rules) {
    var _i = rules.length, rule, out = new Array(_i);
    while (0 <= --_i) {
      rule = rules[_i];
      out[_i] = [this.getRe(rule.pattern), rule.passKeys];
    }
    return out;
  },
  getTemp: function(url, rules) {
    var old = this.rules;
    this.rules = this.format(rules);
    url = this._getPattern(url);
    this.rules = old;
    return url;
  },
  RefreshStatus: function(old_is_empty) {
    var ref = Settings.indexPorts(), tabId, frames
      , needIcon = Settings.get("showActionIcon")
      , i, always_enabled, pass, status = "enabled", status0, port;
    always_enabled = Exclusions.rules.length > 0 ? null : {
      name: "reset",
      passKeys: null
    };
    if (old_is_empty) {
      always_enabled || Settings.broadcast({
        name: "checkIfEnabled"
      });
      return;
    }
    for (tabId in ref) {
      frames = ref[tabId];
      status0 = frames[0].sender.status;
      for (i = frames.length; 0 < --i; ) {
        port = frames[i];
        if (always_enabled) {
          if (port.sender.status === "enabled") {
            continue;
          }
        } else {
          pass = Exclusions.getPattern(port.sender.url);
          status = pass === null ? "enabled" : pass ? "partial" : "disabled";
          if (!pass && port.sender.status === status) {
            continue;
          }
        }
        port.postMessage(always_enabled || { name: "reset", passKeys: pass });
        port.sender.status = status;
      }
      if (needIcon && status0 !== (status = frames[0].sender.status)) {
        g_requestHandlers.SetIcon(tabId | 0, status);
      }
    }
  }
};

Settings.updateHooks.exclusionRules = function(rules) {
  var is_empty = Exclusions.rules.length <= 0;
  Exclusions.setRules(rules);
  g_requestHandlers.esc();
  setTimeout(Exclusions.RefreshStatus, 17, is_empty);
};

Exclusions.setRules(Settings.get("exclusionRules"));
Settings.Init();
<|endoftext|>


<commit_before>/**
 * Standalone extraction of Backbone.Events, no external dependency required.
 * Degrades nicely when Backone/underscore are already available in the current
 * global context.
 *
 * Note that docs suggest to use underscore's `_.extend()` method to add Events
 * support to some given object. A `mixin()` method has been added to the Events
 * prototype to avoid using underscore for that sole purpose:
 *
 *     var myEventEmitter = BackboneEvents.mixin({});
 *
 * Or for a function constructor:
 *
 *     function MyConstructor(){}
 *     MyConstructor.prototype.foo = function(){}
 *     BackboneEvents.mixin(MyConstructor.prototype);
 *
 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
 * (c) 2013 Nicolas Perriault
 */
/* global exports:true, define, module */
(function() {
  var root = this,
      breaker = {},
      nativeForEach = Array.prototype.forEach,
      hasOwnProperty = Object.prototype.hasOwnProperty,
      slice = Array.prototype.slice,
      idCounter = 0;

  // Returns a partial implementation matching the minimal API subset required
  // by Backbone.Events
  function miniscore() {
    return {
      keys: Object.keys || function (obj) {
        if (typeof obj !== "object" && typeof obj !== "function" || obj === null) {
          throw new TypeError("keys() called on a non-object");
        }
        var key, keys = [];
        for (key in obj) {
          if (obj.hasOwnProperty(key)) {
            keys[keys.length] = key;
          }
        }
        return keys;
      },

      uniqueId: function(prefix) {
        var id = ++idCounter + '';
        return prefix ? prefix + id : id;
      },

      has: function(obj, key) {
        return hasOwnProperty.call(obj, key);
      },

      each: function(obj, iterator, context) {
        if (obj == null) return;
        if (nativeForEach && obj.forEach === nativeForEach) {
          obj.forEach(iterator, context);
        } else if (obj.length === +obj.length) {
          for (var i = 0, l = obj.length; i < l; i++) {
            if (iterator.call(context, obj[i], i, obj) === breaker) return;
          }
        } else {
          for (var key in obj) {
            if (this.has(obj, key)) {
              if (iterator.call(context, obj[key], key, obj) === breaker) return;
            }
          }
        }
      },

      once: function(func) {
        var ran = false, memo;
        return function() {
          if (ran) return memo;
          ran = true;
          memo = func.apply(this, arguments);
          func = null;
          return memo;
        };
      }
    };
  }

  var _ = miniscore(), Events;

  // Backbone.Events
  // ---------------

  // A module that can be mixed in to *any object* in order to provide it with
  // custom events. You may bind with `on` or remove with `off` callback
  // functions to an event; `trigger`-ing an event fires all callbacks in
  // succession.
  //
  //     var object = {};
  //     _.extend(object, Backbone.Events);
  //     object.on('expand', function(){ alert('expanded'); });
  //     object.trigger('expand');
  //
  Events = {

    // Bind an event to a `callback` function. Passing `"all"` will bind
    // the callback to all events fired.
    on: function(name, callback, context) {
      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
      this._events || (this._events = {});
      var events = this._events[name] || (this._events[name] = []);
      events.push({callback: callback, context: context, ctx: context || this});
      return this;
    },

    // Bind an event to only be triggered a single time. After the first time
    // the callback is invoked, it will be removed.
    once: function(name, callback, context) {
      if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
      var self = this;
      var once = _.once(function() {
        self.off(name, once);
        callback.apply(this, arguments);
      });
      once._callback = callback;
      return this.on(name, once, context);
    },

    // Remove one or many callbacks. If `context` is null, removes all
    // callbacks with that function. If `callback` is null, removes all
    // callbacks for the event. If `name` is null, removes all bound
    // callbacks for all events.
    off: function(name, callback, context) {
      var retain, ev, events, names, i, l, j, k;
      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
      if (!name && !callback && !context) {
        this._events = {};
        return this;
      }

      names = name ? [name] : _.keys(this._events);
      for (i = 0, l = names.length; i < l; i++) {
        name = names[i];
        if (events = this._events[name]) {
          this._events[name] = retain = [];
          if (callback || context) {
            for (j = 0, k = events.length; j < k; j++) {
              ev = events[j];
              if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
                  (context && context !== ev.context)) {
                retain.push(ev);
              }
            }
          }
          if (!retain.length) delete this._events[name];
        }
      }

      return this;
    },

    // Trigger one or many events, firing all bound callbacks. Callbacks are
    // passed the same arguments as `trigger` is, apart from the event name
    // (unless you're listening on `"all"`, which will cause your callback to
    // receive the true name of the event as the first argument).
    trigger: function(name) {
      if (!this._events) return this;
      var args = slice.call(arguments, 1);
      if (!eventsApi(this, 'trigger', name, args)) return this;
      var events = this._events[name];
      var allEvents = this._events.all;
      if (events) triggerEvents(events, args);
      if (allEvents) triggerEvents(allEvents, arguments);
      return this;
    },

    // Tell this object to stop listening to either specific events ... or
    // to every object it's currently listening to.
    stopListening: function(obj, name, callback) {
      var listeners = this._listeners;
      if (!listeners) return this;
      var deleteListener = !name && !callback;
      if (typeof name === 'object') callback = this;
      if (obj) (listeners = {})[obj._listenerId] = obj;
      for (var id in listeners) {
        listeners[id].off(name, callback, this);
        if (deleteListener) delete this._listeners[id];
      }
      return this;
    }

  };

  // Regular expression used to split event strings.
  var eventSplitter = /\s+/;

  // Implement fancy features of the Events API such as multiple event
  // names `"change blur"` and jQuery-style event maps `{change: action}`
  // in terms of the existing API.
  var eventsApi = function(obj, action, name, rest) {
    if (!name) return true;

    // Handle event maps.
    if (typeof name === 'object') {
      for (var key in name) {
        obj[action].apply(obj, [key, name[key]].concat(rest));
      }
      return false;
    }

    // Handle space separated event names.
    if (eventSplitter.test(name)) {
      var names = name.split(eventSplitter);
      for (var i = 0, l = names.length; i < l; i++) {
        obj[action].apply(obj, [names[i]].concat(rest));
      }
      return false;
    }

    return true;
  };

  // A difficult-to-believe, but optimized internal dispatch function for
  // triggering events. Tries to keep the usual cases speedy (most internal
  // Backbone events have 3 arguments).
  var triggerEvents = function(events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    switch (args.length) {
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
    }
  };

  var listenMethods = {listenTo: 'on', listenToOnce: 'once'};

  // Inversion-of-control versions of `on` and `once`. Tell *this* object to
  // listen to an event in another object ... keeping track of what it's
  // listening to.
  _.each(listenMethods, function(implementation, method) {
    Events[method] = function(obj, name, callback) {
      var listeners = this._listeners || (this._listeners = {});
      var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
      listeners[id] = obj;
      if (typeof name === 'object') callback = this;
      obj[implementation](name, callback, this);
      return this;
    };
  });

  // Aliases for backwards compatibility.
  Events.bind   = Events.on;
  Events.unbind = Events.off;

  // Mixin utility
  Events.mixin = function(proto) {
    var exports = ['on', 'once', 'off', 'trigger', 'stopListening', 'listenTo',
                   'listenToOnce', 'bind', 'unbind'];
    _.each(exports, function(name) {
      proto[name] = this[name];
    }, this);
    return proto;
  };

  // Export Events as BackboneEvents depending on current context
  if (typeof define === "function") {
    define(function() {
      return Events;
    });
  } else if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = Events;
    }
    exports.BackboneEvents = Events;
  } else {
    root.BackboneEvents = Events;
  }
})(this);
<commit_msg>check if module.exports exists first to fix issue with Browserify and requirejs<commit_after>/**
 * Standalone extraction of Backbone.Events, no external dependency required.
 * Degrades nicely when Backone/underscore are already available in the current
 * global context.
 *
 * Note that docs suggest to use underscore's `_.extend()` method to add Events
 * support to some given object. A `mixin()` method has been added to the Events
 * prototype to avoid using underscore for that sole purpose:
 *
 *     var myEventEmitter = BackboneEvents.mixin({});
 *
 * Or for a function constructor:
 *
 *     function MyConstructor(){}
 *     MyConstructor.prototype.foo = function(){}
 *     BackboneEvents.mixin(MyConstructor.prototype);
 *
 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
 * (c) 2013 Nicolas Perriault
 */
/* global exports:true, define, module */
(function() {
  var root = this,
      breaker = {},
      nativeForEach = Array.prototype.forEach,
      hasOwnProperty = Object.prototype.hasOwnProperty,
      slice = Array.prototype.slice,
      idCounter = 0;

  // Returns a partial implementation matching the minimal API subset required
  // by Backbone.Events
  function miniscore() {
    return {
      keys: Object.keys || function (obj) {
        if (typeof obj !== "object" && typeof obj !== "function" || obj === null) {
          throw new TypeError("keys() called on a non-object");
        }
        var key, keys = [];
        for (key in obj) {
          if (obj.hasOwnProperty(key)) {
            keys[keys.length] = key;
          }
        }
        return keys;
      },

      uniqueId: function(prefix) {
        var id = ++idCounter + '';
        return prefix ? prefix + id : id;
      },

      has: function(obj, key) {
        return hasOwnProperty.call(obj, key);
      },

      each: function(obj, iterator, context) {
        if (obj == null) return;
        if (nativeForEach && obj.forEach === nativeForEach) {
          obj.forEach(iterator, context);
        } else if (obj.length === +obj.length) {
          for (var i = 0, l = obj.length; i < l; i++) {
            if (iterator.call(context, obj[i], i, obj) === breaker) return;
          }
        } else {
          for (var key in obj) {
            if (this.has(obj, key)) {
              if (iterator.call(context, obj[key], key, obj) === breaker) return;
            }
          }
        }
      },

      once: function(func) {
        var ran = false, memo;
        return function() {
          if (ran) return memo;
          ran = true;
          memo = func.apply(this, arguments);
          func = null;
          return memo;
        };
      }
    };
  }

  var _ = miniscore(), Events;

  // Backbone.Events
  // ---------------

  // A module that can be mixed in to *any object* in order to provide it with
  // custom events. You may bind with `on` or remove with `off` callback
  // functions to an event; `trigger`-ing an event fires all callbacks in
  // succession.
  //
  //     var object = {};
  //     _.extend(object, Backbone.Events);
  //     object.on('expand', function(){ alert('expanded'); });
  //     object.trigger('expand');
  //
  Events = {

    // Bind an event to a `callback` function. Passing `"all"` will bind
    // the callback to all events fired.
    on: function(name, callback, context) {
      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
      this._events || (this._events = {});
      var events = this._events[name] || (this._events[name] = []);
      events.push({callback: callback, context: context, ctx: context || this});
      return this;
    },

    // Bind an event to only be triggered a single time. After the first time
    // the callback is invoked, it will be removed.
    once: function(name, callback, context) {
      if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
      var self = this;
      var once = _.once(function() {
        self.off(name, once);
        callback.apply(this, arguments);
      });
      once._callback = callback;
      return this.on(name, once, context);
    },

    // Remove one or many callbacks. If `context` is null, removes all
    // callbacks with that function. If `callback` is null, removes all
    // callbacks for the event. If `name` is null, removes all bound
    // callbacks for all events.
    off: function(name, callback, context) {
      var retain, ev, events, names, i, l, j, k;
      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
      if (!name && !callback && !context) {
        this._events = {};
        return this;
      }

      names = name ? [name] : _.keys(this._events);
      for (i = 0, l = names.length; i < l; i++) {
        name = names[i];
        if (events = this._events[name]) {
          this._events[name] = retain = [];
          if (callback || context) {
            for (j = 0, k = events.length; j < k; j++) {
              ev = events[j];
              if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
                  (context && context !== ev.context)) {
                retain.push(ev);
              }
            }
          }
          if (!retain.length) delete this._events[name];
        }
      }

      return this;
    },

    // Trigger one or many events, firing all bound callbacks. Callbacks are
    // passed the same arguments as `trigger` is, apart from the event name
    // (unless you're listening on `"all"`, which will cause your callback to
    // receive the true name of the event as the first argument).
    trigger: function(name) {
      if (!this._events) return this;
      var args = slice.call(arguments, 1);
      if (!eventsApi(this, 'trigger', name, args)) return this;
      var events = this._events[name];
      var allEvents = this._events.all;
      if (events) triggerEvents(events, args);
      if (allEvents) triggerEvents(allEvents, arguments);
      return this;
    },

    // Tell this object to stop listening to either specific events ... or
    // to every object it's currently listening to.
    stopListening: function(obj, name, callback) {
      var listeners = this._listeners;
      if (!listeners) return this;
      var deleteListener = !name && !callback;
      if (typeof name === 'object') callback = this;
      if (obj) (listeners = {})[obj._listenerId] = obj;
      for (var id in listeners) {
        listeners[id].off(name, callback, this);
        if (deleteListener) delete this._listeners[id];
      }
      return this;
    }

  };

  // Regular expression used to split event strings.
  var eventSplitter = /\s+/;

  // Implement fancy features of the Events API such as multiple event
  // names `"change blur"` and jQuery-style event maps `{change: action}`
  // in terms of the existing API.
  var eventsApi = function(obj, action, name, rest) {
    if (!name) return true;

    // Handle event maps.
    if (typeof name === 'object') {
      for (var key in name) {
        obj[action].apply(obj, [key, name[key]].concat(rest));
      }
      return false;
    }

    // Handle space separated event names.
    if (eventSplitter.test(name)) {
      var names = name.split(eventSplitter);
      for (var i = 0, l = names.length; i < l; i++) {
        obj[action].apply(obj, [names[i]].concat(rest));
      }
      return false;
    }

    return true;
  };

  // A difficult-to-believe, but optimized internal dispatch function for
  // triggering events. Tries to keep the usual cases speedy (most internal
  // Backbone events have 3 arguments).
  var triggerEvents = function(events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    switch (args.length) {
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
    }
  };

  var listenMethods = {listenTo: 'on', listenToOnce: 'once'};

  // Inversion-of-control versions of `on` and `once`. Tell *this* object to
  // listen to an event in another object ... keeping track of what it's
  // listening to.
  _.each(listenMethods, function(implementation, method) {
    Events[method] = function(obj, name, callback) {
      var listeners = this._listeners || (this._listeners = {});
      var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
      listeners[id] = obj;
      if (typeof name === 'object') callback = this;
      obj[implementation](name, callback, this);
      return this;
    };
  });

  // Aliases for backwards compatibility.
  Events.bind   = Events.on;
  Events.unbind = Events.off;

  // Mixin utility
  Events.mixin = function(proto) {
    var exports = ['on', 'once', 'off', 'trigger', 'stopListening', 'listenTo',
                   'listenToOnce', 'bind', 'unbind'];
    _.each(exports, function(name) {
      proto[name] = this[name];
    }, this);
    return proto;
  };

  // Export Events as BackboneEvents depending on current context
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = Events;
    }
    exports.BackboneEvents = Events;
  }else if (typeof define === "function") {
    define(function() {
      return Events;
    });
  } else {
    root.BackboneEvents = Events;
  }
})(this);
<|endoftext|>


<commit_before>define(function (require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');

	var SegmentPotentialView = function(options) {

		// Default values
		options = _.extend({

		}, options);

		if (options.segment)
			this.segment = options.segment;
		else
			throw 'SegmentPotentialView requires a Barrier model.';

		if (options.heatmapView)
			this.heatmapView = options.heatmapView;
		else
			throw 'SegmentPotentialView requires a HeatmapView to render.';
	};

	var segment,
	    xSpacing,
	    ySpacing,
	    halfYSpacing,
	    halfXSpacing,
	    height,
	    scaledNormal,
	    sX,
	    sY,
	    eX,
	    eY,
	    firstX,
	    firstY,
	    i,
	    j;

	_.extend(SegmentPotentialView.prototype, {

		render: function() {
			this.graphics = new PIXI.Graphics();
			this.graphics.alpha = 0;

			this.update(0, 0);

			this.heatmapView.stage.addChild(this.graphics);
		},

		remove: function() {
			this.heatmapView.stage.removeChild(this.graphics);
		},

		update: function(time, delta) {
			segment = this.segment;

			if (!segment.enabled)
				return;

				this.graphics.clear();

			if (this.graphics.alpha < 1)
				this.graphics.alpha += delta * 0.005;

			this.graphics.beginFill(0xFFFFFF, 0.5);
			this.graphics.lineStyle(2, 0xFFFFFF, 0.9);

			height = this.heatmapView.waveSimulation.lattice.height;

			xSpacing = this.heatmapView.xSpacing;
			ySpacing = this.heatmapView.ySpacing;
			halfYSpacing = ySpacing / 2.0;
			halfXSpacing = xSpacing / 2.0;

			/*
			 * I'm using the normal vector and thickness to paint lines
			 *   around the four corners of the rectangle that surrounds
			 *   at the appropriate thickness.
			 * Each offset vector is the sum of two vectors that are
			 *   derrived from the scaled normal vector.
			 */

			scaledNormal = segment.getNormalUnitVector();
			scaledNormal.x *= (segment.thickness / 2.0) * xSpacing;
			scaledNormal.y *= (segment.thickness / 2.0) * ySpacing * -1;
			i = scaledNormal.x;
			j = scaledNormal.y;

			sX = segment.start.x * xSpacing - halfXSpacing;
			sY = (height - segment.start.y) * ySpacing - halfYSpacing;
			eX = segment.end.x * xSpacing - halfXSpacing;
			eY = (height - segment.end.y) * ySpacing - halfYSpacing;

			firstX = sX - i - j;
			firstY = sY + i - j;

			this.graphics.moveTo(firstX, firstY);
			this.graphics.lineTo(sX - j + i, sY + i + j);
			this.graphics.lineTo(eX + j + i, eY - i + j);
			this.graphics.lineTo(eX + j - i, eY - i - j);
			this.graphics.lineTo(firstX, firstY);
		}

	});

	return SegmentPotentialView;
});
<commit_msg>Segment potential knob rendering<commit_after>define(function (require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');

	var SegmentPotentialView = function(options) {

		// Default values
		options = _.extend({

		}, options);

		if (options.segment)
			this.segment = options.segment;
		else
			throw 'SegmentPotentialView requires a Barrier model.';

		if (options.heatmapView)
			this.heatmapView = options.heatmapView;
		else
			throw 'SegmentPotentialView requires a HeatmapView to render.';
	};

	var segment,
	    xSpacing,
	    ySpacing,
	    halfYSpacing,
	    halfXSpacing,
	    height,
	    scaledNormal,
	    sX,
	    sY,
	    eX,
	    eY,
	    firstX,
	    firstY,
	    i,
	    j;

	_.extend(SegmentPotentialView.prototype, {

		render: function() {
			this.graphics = new PIXI.Graphics();
			this.graphics.alpha = 0;

			this.update(0, 0);

			this.heatmapView.stage.addChild(this.graphics);
		},

		remove: function() {
			this.heatmapView.stage.removeChild(this.graphics);
		},

		update: function(time, delta) {
			segment = this.segment;

			if (!segment.enabled)
				return;

				this.graphics.clear();

			if (this.graphics.alpha < 1)
				this.graphics.alpha += delta * 0.005;

			this.graphics.beginFill(0xFFFFFF, 0.5);
			this.graphics.lineStyle(2, 0xFFFFFF, 0.9);

			height = this.heatmapView.waveSimulation.lattice.height;

			xSpacing = this.heatmapView.xSpacing;
			ySpacing = this.heatmapView.ySpacing;
			halfYSpacing = ySpacing / 2.0;
			halfXSpacing = xSpacing / 2.0;

			/*
			 * I'm using the normal vector and thickness to paint lines
			 *   around the four corners of the rectangle that surrounds
			 *   at the appropriate thickness.
			 * Each offset vector is the sum of two vectors that are
			 *   derrived from the scaled normal vector.
			 */

			scaledNormal = segment.getNormalUnitVector();
			scaledNormal.x *= (segment.thickness / 2.0) * xSpacing;
			scaledNormal.y *= (segment.thickness / 2.0) * ySpacing * -1;
			i = scaledNormal.x;
			j = scaledNormal.y;

			sX = segment.start.x * xSpacing - halfXSpacing;
			sY = (height - segment.start.y) * ySpacing - halfYSpacing;
			eX = segment.end.x * xSpacing - halfXSpacing;
			eY = (height - segment.end.y) * ySpacing - halfYSpacing;

			firstX = sX + i + j;
			firstY = sY - i + j;

			this.graphics.moveTo(firstX, firstY);
			this.graphics.lineTo(sX + j - i, sY - i - j);
			this.graphics.lineTo(eX - j - i, eY + i - j);
			this.graphics.lineTo(eX - j + i, eY + i + j);
			this.graphics.lineTo(firstX, firstY);

			this.graphics.endFill();
			this.graphics.beginFill(0x21366B, 1);
			this.graphics.lineStyle(1, 0x21366B, 0.5);

			this.graphics.drawCircle(sX, sY, (segment.thickness / 2.0) * xSpacing - 1);
			this.graphics.drawCircle(eX, eY, (segment.thickness / 2.0) * xSpacing - 1);

			this.graphics.endFill();
		}

	});

	return SegmentPotentialView;
});
<|endoftext|>


<commit_before> // Helper scope
 if (!Helpers) {
  Helpers = {};
 }

if (typeof Handlebars !== 'undefined') {

    Handlebars.registerHelper('getLength', function (a) {
      return a && a.length;
    });

    Handlebars.registerHelper('isSelected', function (a, b) {
      return (a === b)?' selected': '';
    });

    Handlebars.registerHelper('isChecked', function (a, b) {
      return (a === b)?' checked': '';
    });

    Handlebars.registerHelper('cutString', function (str, len) {
      return (str.length > len)?str.substr(0, Math.max(len-3, 0))+'...':str;
    });

    Handlebars.registerHelper('$eq', function (a, b) {
      return (a === b); //Only text, numbers, boolean - not array & objects
    });

    Handlebars.registerHelper('$neq', function (a, b) {
      return (a !== b); //Only text, numbers, boolean - not array & objects
    });

    Handlebars.registerHelper('$in', function (a, b, c, d) {
      return ( a === b || a === c || a === d);
    });

    Handlebars.registerHelper('$nin', function (a, b, c, d) {
      return ( a !== b || a !== c || a !== d);
    });

    Handlebars.registerHelper('$exists', function (a) {
      return ( a !== undefined);
    });

    Handlebars.registerHelper('$lt', function (a, b) {
      return (a < b);
    });

    Handlebars.registerHelper('$gt', function (a, b) {
      return (a > b);
    });

    Handlebars.registerHelper('$lte', function (a, b) {
      return (a < b);
    });

    Handlebars.registerHelper('$gte', function (a, b) {
      return (a > b);
    });

    Handlebars.registerHelper('$and', function (a, b) {
      return (a && b);
    });

    Handlebars.registerHelper('$or', function (a, b) {
      return (a || b);
    });

    Handlebars.registerHelper('$not', function (a) {
      return (!a);
    });

    Handlebars.registerHelper('getText', function (text) { // Deprecating
      return Helpers.getText(text);
    });

    // Handlebars.registerHelper('userRole', function ( /* arguments */) {
    //   var role = Session.get('currentRole');
    //   return _.any(arguments, function(value) { return (value == role); });
    // });

    // expects an array: languageText['say.hello.to.me']['en'] = 'Say hello to me:)';
    // ex.:
    // getText('Say.Hello.To.Me') == 'say hello to me:)'; // lowercase
    // getText('SAY.HELLO.TO.ME') == 'SAY HELLO TO ME:)'; // uppercase
    // getText('Say.hello.to.me') == 'Say hello to me:)'; // uppercase first letter, rest lowercase
    // getText('Say.Hello.To.Me') == 'Say Hello To Me:)'; // camelCase

    var _languageDeps = new Deps.Dependency();
    var currentLanguage = 'en';

    // language = 'en'
    Helpers.setLanguage = function(language) {
      if (language && language !== currentLanguage) {
        currentLanguage = language;
        _languageDeps.changed();
      }
    };

    Helpers.language = function() {
      _languageDeps.depend();
      return currentLanguage;
    };

    Helpers.getText = function(text) {
      // handleCase will mimic text Case making src same case as text
      function handleCase(text, src) {
        // Return lowercase
        if (text == text.toLowerCase())
          return src.toLowerCase();
        // Return uppercase
        if (text == text.toUpperCase())
          return src.toUpperCase();
        // Return uppercase first letter, rest lowercase
        if (text.substr(1) == text.substr(1).toLowerCase() )
          return src.substr(0, 1).toUpperCase()+src.substr(1).toLowerCase();
        // Return CamelCase
        return src.replace(/( [a-z])/g, function($1){
          return $1.toUpperCase();
        });
      }
      var txt = text.toLowerCase();
      // TODO: Tidy the return line - kinda messy
      return handleCase(text, (languageText && languageText[txt])?( (languageText[txt][Helpers.language()])?languageText[txt][Helpers.language()]: languageText[txt].en):'['+text+']' );
    };

    /*
        Then $uper helper - Credit goes to @belisarius222 aka Ted Blackman for sparking an idear for a solution
    */
    Helpers.superScope = {};

    Helpers.addScope = function(name, obj) {
      console.log('Helper scope added ' + name);
      // TODO: Get rid of underscore
      Helpers.superScope[name] = _.bind(function() { return this; }, obj);
    };

    Helpers.removeScope = function(name) {
      delete Helpers.superScope[name];
    };

    Helpers.addScope('Session', Session);
    Helpers.addScope('Meteor', Meteor);

    Handlebars.registerHelper('$', function() {
      return Helpers.superScope;
    });
}
<commit_msg>Remove console.log<commit_after> // Helper scope
 if (!Helpers) {
  Helpers = {};
 }

if (typeof Handlebars !== 'undefined') {

    Handlebars.registerHelper('getLength', function (a) {
      return a && a.length;
    });

    Handlebars.registerHelper('isSelected', function (a, b) {
      return (a === b)?' selected': '';
    });

    Handlebars.registerHelper('isChecked', function (a, b) {
      return (a === b)?' checked': '';
    });

    Handlebars.registerHelper('cutString', function (str, len) {
      return (str.length > len)?str.substr(0, Math.max(len-3, 0))+'...':str;
    });

    Handlebars.registerHelper('$eq', function (a, b) {
      return (a === b); //Only text, numbers, boolean - not array & objects
    });

    Handlebars.registerHelper('$neq', function (a, b) {
      return (a !== b); //Only text, numbers, boolean - not array & objects
    });

    Handlebars.registerHelper('$in', function (a, b, c, d) {
      return ( a === b || a === c || a === d);
    });

    Handlebars.registerHelper('$nin', function (a, b, c, d) {
      return ( a !== b || a !== c || a !== d);
    });

    Handlebars.registerHelper('$exists', function (a) {
      return ( a !== undefined);
    });

    Handlebars.registerHelper('$lt', function (a, b) {
      return (a < b);
    });

    Handlebars.registerHelper('$gt', function (a, b) {
      return (a > b);
    });

    Handlebars.registerHelper('$lte', function (a, b) {
      return (a < b);
    });

    Handlebars.registerHelper('$gte', function (a, b) {
      return (a > b);
    });

    Handlebars.registerHelper('$and', function (a, b) {
      return (a && b);
    });

    Handlebars.registerHelper('$or', function (a, b) {
      return (a || b);
    });

    Handlebars.registerHelper('$not', function (a) {
      return (!a);
    });

    Handlebars.registerHelper('getText', function (text) { // Deprecating
      return Helpers.getText(text);
    });

    // Handlebars.registerHelper('userRole', function ( /* arguments */) {
    //   var role = Session.get('currentRole');
    //   return _.any(arguments, function(value) { return (value == role); });
    // });

    // expects an array: languageText['say.hello.to.me']['en'] = 'Say hello to me:)';
    // ex.:
    // getText('Say.Hello.To.Me') == 'say hello to me:)'; // lowercase
    // getText('SAY.HELLO.TO.ME') == 'SAY HELLO TO ME:)'; // uppercase
    // getText('Say.hello.to.me') == 'Say hello to me:)'; // uppercase first letter, rest lowercase
    // getText('Say.Hello.To.Me') == 'Say Hello To Me:)'; // camelCase

    var _languageDeps = new Deps.Dependency();
    var currentLanguage = 'en';

    // language = 'en'
    Helpers.setLanguage = function(language) {
      if (language && language !== currentLanguage) {
        currentLanguage = language;
        _languageDeps.changed();
      }
    };

    Helpers.language = function() {
      _languageDeps.depend();
      return currentLanguage;
    };

    Helpers.getText = function(text) {
      // handleCase will mimic text Case making src same case as text
      function handleCase(text, src) {
        // Return lowercase
        if (text == text.toLowerCase())
          return src.toLowerCase();
        // Return uppercase
        if (text == text.toUpperCase())
          return src.toUpperCase();
        // Return uppercase first letter, rest lowercase
        if (text.substr(1) == text.substr(1).toLowerCase() )
          return src.substr(0, 1).toUpperCase()+src.substr(1).toLowerCase();
        // Return CamelCase
        return src.replace(/( [a-z])/g, function($1){
          return $1.toUpperCase();
        });
      }
      var txt = text.toLowerCase();
      // TODO: Tidy the return line - kinda messy
      return handleCase(text, (languageText && languageText[txt])?( (languageText[txt][Helpers.language()])?languageText[txt][Helpers.language()]: languageText[txt].en):'['+text+']' );
    };

    /*
        Then $uper helper - Credit goes to @belisarius222 aka Ted Blackman for sparking an idear for a solution
    */
    Helpers.superScope = {};

    Helpers.addScope = function(name, obj) {
      // TODO: Get rid of underscore
      Helpers.superScope[name] = _.bind(function() { return this; }, obj);
    };

    Helpers.removeScope = function(name) {
      delete Helpers.superScope[name];
    };

    Helpers.addScope('Session', Session);
    Helpers.addScope('Meteor', Meteor);

    Handlebars.registerHelper('$', function() {
      return Helpers.superScope;
    });
}
<|endoftext|>