<commit_before>import Ember from 'ember';
import DS from 'ember-data';
import decorateAdapter from './base-store/decorate-adapter';
import decorateSerializer from './base-store/decorate-serializer';
import decorateAPICall from './base-store/decorate-api-call';

/**
 * This should be used as store:main
 *
 * @class BaseStore
 * @extends DS.Store
 */
export default DS.Store.extend({
  onlineStore: null,
  offlineStore: null,
  offlineGlobals: Ember.inject.service('offline-globals'),

  /**
   * Global instance of Syncer that contains methods to sync model.
   *
   * @property syncer
   * @type Syncer
   * @readOnly
   */
  syncer: null,

  init() {
    this._super(...arguments);
    let owner = Ember.getOwner(this);
    if (Ember.isNone(this.get('onlineStore'))) {
      let onlineStore = DS.Store.create(owner.ownerInjection());
      this.set('onlineStore', onlineStore);
    }

    let syncer = owner.lookup('syncer:main');
    this.set('syncer', syncer);

    let offlineStore = owner.lookup('store:local');
    this.set('offlineStore', offlineStore);
  },

  /**
    This method returns a fresh collection from the server, regardless of if there is already records
    in the store or not.
    @method findAll
    @param {String} modelName
    @param {Object} options
    @return {Promise} promise
  */
  findAll: function (modelName, options) {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('all', 'findAll', arguments, 1) : offlineStore.findAll.apply(offlineStore, arguments);
  },

  /**
   * This method returns a record for a given type and id combination.
   * NOTE: this will trigger syncUp twice, this is OK. And since this is
   *  a public method, we probably want to preserve this.
    @method findRecord
    @param {String} modelName
    @param {String|Integer} id
    @param {Object} options
    @return {Promise} promise
   */
  findRecord: function(modelName, id, options) {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('single', 'findRecord', arguments, 2) : offlineStore.findRecord.apply(offlineStore, arguments);
  },

  /**
    This method is called by the record's `reload` method.
    This method calls the adapter's `find` method, which returns a promise. When
    **that** promise resolves, `reloadRecord` will resolve the promise returned
    by the record's `reload`.
    @method reloadRecord
    @private
    @param {DS.Model} internalModel
    @return {Promise} promise
  */
  reloadRecord: function (internalModel) {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('single', 'reloadRecord', arguments, -1) : offlineStore.reloadRecord.apply(offlineStore, arguments);
  },

  /**
    Query for records that meet certain criteria. Resolves with DS.RecordArray.
    @method query
    @param {String} modelName
    @param {Object} query
    @return {Promise} promise
  */
  query: function (modelName, query) {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('multiple', 'query', arguments, -1) : offlineStore.query.apply(offlineStore, arguments);
  },

  /**
    Query for record that meet certain criteria. Resolves with single record.
    @method query
    @param {String} modelName
    @param {Object} query
    @return {Promise} promise
  */
  queryRecord: function (modelName, query) {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('single', 'queryRecord', arguments, -1) : offlineStore.queryRecord.apply(offlineStore, arguments);
  },

  adapterFor: function(type) {
    let onlineStore = this.get('onlineStore');
    let offlineStore = this.get('offlineStore');
    let adapter = onlineStore.adapterFor(type);
    if (this.get('offlineGlobals').get('isOfflineEnabled')) {
      return this._isOnline() ? decorateAdapter.call(this, adapter) : offlineStore.adapterFor(type);
	}
    else {
      return adapter;
    }
  },

  serializerFor: function(type) {
    let onlineStore = this.get('onlineStore');
    let offlineStore = this.get('offlineStore');
    let serializer = onlineStore.serializerFor(type);
    if (this.get('offlineGlobals').get('isOfflineEnabled')) {
      return this._isOnline() ? decorateSerializer.call(this, serializer) : offlineStore.serializerFor(type);
	}
    else {
      return serializer;
    }
  },

  _decorateMethodAndCall: function(finderType, originMethodName, originMethodArguments, optionsIndex) {
    let onlineStore = this.get('onlineStore');
    let originMethod = onlineStore[originMethodName];
    let decoratedMethod = decorateAPICall(finderType, originMethod);
	if (optionsIndex > -1) {
      let options = originMethodArguments[optionsIndex];
	  options = this.get('offlineGlobals').get('isOfflineEnabled') ? options : Ember.$.extend(true, { bypass: true }, options);
      originMethodArguments[optionsIndex] = options;
    }

    return decoratedMethod.apply(onlineStore, originMethodArguments);
  },

  _isOnline: function() {
    return this.get('offlineGlobals.isOnline');
  }
});
<commit_msg>Add `useOnlineStore` option to `base-store` methods<commit_after>import Ember from 'ember';
import DS from 'ember-data';
import decorateAdapter from './base-store/decorate-adapter';
import decorateSerializer from './base-store/decorate-serializer';
import decorateAPICall from './base-store/decorate-api-call';

/**
 * This should be used as store:main
 *
 * @class BaseStore
 * @extends DS.Store
 */
export default DS.Store.extend({
  onlineStore: null,
  offlineStore: null,
  offlineGlobals: Ember.inject.service('offline-globals'),

  /**
   * Global instance of Syncer that contains methods to sync model.
   *
   * @property syncer
   * @type Syncer
   * @readOnly
   */
  syncer: null,

  init() {
    this._super(...arguments);
    let owner = Ember.getOwner(this);
    if (Ember.isNone(this.get('onlineStore'))) {
      let onlineStore = DS.Store.create(owner.ownerInjection());
      this.set('onlineStore', onlineStore);
    }

    let syncer = owner.lookup('syncer:main');
    this.set('syncer', syncer);

    let offlineStore = owner.lookup('store:local');
    this.set('offlineStore', offlineStore);
  },

  /**
    This method returns a fresh collection from the server, regardless of if there is already records
    in the store or not.
    @method findAll
    @param {String} modelName
    @param {Object} options
    @param {Boolean} [options.useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Promise} promise
  */
  findAll(modelName, options) {
    let offlineStore = this.get('offlineStore');
    let useOnlineStore = options ? options.useOnlineStore : null;
    let useOnlineStoreCondition = (useOnlineStore === true) || (useOnlineStore === null && this._isOnline());
    return useOnlineStoreCondition ? this._decorateMethodAndCall('all', 'findAll', arguments, 1) : offlineStore.findAll.apply(offlineStore, arguments);
  },

  /**
   * This method returns a record for a given type and id combination.
   * NOTE: this will trigger syncUp twice, this is OK. And since this is
   *  a public method, we probably want to preserve this.
    @method findRecord
    @param {String} modelName
    @param {String|Integer} id
    @param {Object} options
    @param {Boolean} [options.useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Promise} promise
   */
  findRecord(modelName, id, options) {
    let offlineStore = this.get('offlineStore');
    let useOnlineStore = options ? options.useOnlineStore : null;
    let useOnlineStoreCondition = (useOnlineStore === true) || (useOnlineStore === null && this._isOnline());
    return useOnlineStoreCondition ? this._decorateMethodAndCall('single', 'findRecord', arguments, 2) : offlineStore.findRecord.apply(offlineStore, arguments);
  },

  /**
    This method is called by the record's `reload` method.
    This method calls the adapter's `find` method, which returns a promise. When
    **that** promise resolves, `reloadRecord` will resolve the promise returned
    by the record's `reload`.
    @method reloadRecord
    @private
    @param {DS.Model} internalModel
    @return {Promise} promise
  */
  reloadRecord() {
    let offlineStore = this.get('offlineStore');
    return this._isOnline() ? this._decorateMethodAndCall('single', 'reloadRecord', arguments, -1) : offlineStore.reloadRecord.apply(offlineStore, arguments);
  },

  /**
    Query for records that meet certain criteria. Resolves with DS.RecordArray.
    @method query
    @param {String} modelName
    @param {Object} query
    @param {Boolean} [query.useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Promise} promise
  */
  query(modelName, query) {
    let offlineStore = this.get('offlineStore');
    let useOnlineStore = query ? query.useOnlineStore : null;
    if (query.useOnlineStore) {
      delete query.useOnlineStore;
    }
    let useOnlineStoreCondition = (useOnlineStore === true) || (useOnlineStore === null && this._isOnline());
    return useOnlineStoreCondition ? this._decorateMethodAndCall('multiple', 'query', arguments, -1) : offlineStore.query.apply(offlineStore, arguments);
  },

  /**
    Query for record that meet certain criteria. Resolves with single record.
    @method query
    @param {String} modelName
    @param {Object} query
    @param {Boolean} [query.useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Promise} promise
  */
  queryRecord(modelName, query) {
    let offlineStore = this.get('offlineStore');
    let useOnlineStore = query ? query.useOnlineStore : null;
    if (query.useOnlineStore) {
      delete query.useOnlineStore;
    }
    let useOnlineStoreCondition = (useOnlineStore === true) || (useOnlineStore === null && this._isOnline());
    return useOnlineStoreCondition ? this._decorateMethodAndCall('single', 'queryRecord', arguments, -1) : offlineStore.queryRecord.apply(offlineStore, arguments);
  },

  /**
    Create a new record in the current store. The properties passed to this method are set on the newly created record.
    @method createRecord
    @param {String} modelName
    @param {Object} inputProperties A hash of properties to set on the newly created record.
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Promise} promise
  */
  createRecord() {
    return this._callSuperMethod('createRecord', 2, arguments);
  },

  /**
    For symmetry, a record can be deleted via the store.
    @method deleteRecord
    @param {DS.Model} record
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
  */
  deleteRecord() {
    return this._callSuperMethod('deleteRecord', 1, arguments);
  },

  /**
    Get the reference for the specified record.
    @method getReference
    @param {String} type
    @param {String|Integer} id
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {RecordReference} promise
  */
  getReference() {
    return this._callSuperMethod('getReference', 2, arguments);
  },

  /**
    Returns true if a record for a given type and ID is already loaded.
    @method hasRecordForId
    @param {String|DS.Model} modelName
    @param {String|Integer} inputId
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Boolean}
  */
  hasRecordForId() {
    return this._callSuperMethod('hasRecordForId', 2, arguments);
  },

  /**
    Converts a json payload into the normalized form that {{#crossLink "BaseStore/push:method"}}{{/crossLink}} expects.
    @method normalize
    @param {String} modelName The name of the model type for this payload
    @param {Object} payload
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Object} The normalized payload
  */
  normalize() {
    return this._callSuperMethod('normalize', 2, arguments);
  },

  /**
    This method returns a filtered array that contains all of the known records for a given type in the store.
    @method peekAll
    @param {String} modelName
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {DS.RecordArray}
  */
  peekAll() {
    return this._callSuperMethod('peekAll', 1, arguments);
  },

  /**
    Get a record by a given type and ID without triggering a fetch.
    @method peekRecord
    @param {String} modelName
    @param {String|Integer} id
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {DS.Model|null} Record
  */
  peekRecord() {
    return this._callSuperMethod('peekRecord', 2, arguments);
  },

  /**
    Push some data for a given type into the store.
    @method push
    @param {Object} data
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {DS.Model|Array} The record(s) that was created or updated.
  */
  push() {
    return this._callSuperMethod('push', 1, arguments);
  },

  /**
    Push some raw data into the store.
    @method pushPayload
    @param {String} modelName
    @param {Object} inputPayload
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
  */
  pushPayload() {
    return this._callSuperMethod('pushPayload', 2, arguments);
  },

  /**
    This method returns if a certain record is already loaded in the store.
    @method recordIsLoaded
    @param {String} modelName
    @param {String|Integer} id
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {Boolean}
  */
  recordIsLoaded() {
    return this._callSuperMethod('recordIsLoaded', 2, arguments);
  },

  /**
    This method unloads all records in the store.
    @method unloadAll
    @param {String} modelName
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
  */
  unloadAll() {
    return this._callSuperMethod('unloadAll', 1, arguments);
  },

  /**
    For symmetry, a record can be unloaded via the store. Only non-dirty records can be unloaded.
    @method unloadRecord
    @param {DS.Model} record
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
  */
  unloadRecord() {
    return this._callSuperMethod('unloadRecord', 1, arguments);
  },

  /**
    Returns an instance of the adapter for a given type.
    @method adapterFor
    @param {String} modelName
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {DS.Adapter or subclass} Adapter
  */
  adapterFor(modelName, useOnlineStore) {
    let onlineStore = this.get('onlineStore');
    let offlineStore = this.get('offlineStore');
    let adapter = onlineStore.adapterFor(modelName);
    if (this.get('offlineGlobals').get('isOfflineEnabled')) {
      let useOnlineStoreCondition = useOnlineStore || (Ember.isNone(useOnlineStore) && this._isOnline());
      return useOnlineStoreCondition ? decorateAdapter.call(this, adapter) : offlineStore.adapterFor(modelName);
    }
    else {
      return adapter;
    }
  },

  /**
    Returns an instance of the serializer for a given type.
    @method serializerFor
    @param {String} modelName
    @param {Boolean} [useOnlineStore] Allow to explicitly specify online or offline store using independently of global online status
    @return {DS.Serializer or subclass} Serializer
  */
  serializerFor(modelName, useOnlineStore) {
    let onlineStore = this.get('onlineStore');
    let offlineStore = this.get('offlineStore');
    let serializer = onlineStore.serializerFor(modelName);
    if (this.get('offlineGlobals').get('isOfflineEnabled')) {
      let useOnlineStoreCondition = useOnlineStore || (Ember.isNone(useOnlineStore) && this._isOnline());
      return useOnlineStoreCondition ? decorateSerializer.call(this, serializer) : offlineStore.serializerFor(modelName);
    }
    else {
      return serializer;
    }
  },

  /*
    Decorate specified method of online store for add extra syncing features.
  */
  _decorateMethodAndCall(finderType, originMethodName, originMethodArguments, optionsIndex) {
    let onlineStore = this.get('onlineStore');
    let originMethod = onlineStore[originMethodName];
    let decoratedMethod = decorateAPICall(finderType, originMethod);
	  if (optionsIndex > -1) {
      let options = originMethodArguments[optionsIndex];
	    options = this.get('offlineGlobals').get('isOfflineEnabled') ? options : Ember.$.extend(true, { bypass: true }, options);
      originMethodArguments[optionsIndex] = options;
    }

    return decoratedMethod.apply(onlineStore, originMethodArguments);
  },

  /*
    Detect global online status.
  */
  _isOnline() {
    return this.get('offlineGlobals.isOnline');
  },

  /*
    Pass control flow to online or offline store depend on global online status
    and explicitly specified store to use.
  */
  _callSuperMethod(methodName, useOnlineStoreParamNum, ...args) {
    let onlineStore = this.get('onlineStore');
    let offlineStore = this.get('offlineStore');
    let useOnlineStore = (args[0].length - 1) >= useOnlineStoreParamNum ? args[0][useOnlineStoreParamNum] : null;
    let useOnlineStoreCondition = useOnlineStore || (Ember.isNone(useOnlineStore) && this._isOnline());
    return useOnlineStoreCondition ? onlineStore[methodName].apply(onlineStore, args[0]) : offlineStore[methodName].apply(offlineStore, args[0]);
  }
});
<|endoftext|>


<commit_before>'use strict';

const incheon = require('../../../../../');
const Renderer = incheon.render.Renderer;

class MyRenderer extends Renderer {

    constructor(gameEngine, clientEngine) {
        super(gameEngine, clientEngine);
        this.sprites = {};
    }

    draw() {
        super.draw();
    }

    addObject(objData, options) {
        let sprite = {};

        // add this object to the renderer:
        // if (objData.class == PlayerAvatar) {
        //     ...
        // }

        Object.assign(sprite, options);
        this.sprites[objData.id] = sprite;

        return sprite;
    }

    removeObject(obj) {
        obj.destroy();
        delete this.sprites[obj.id];
    }

}

module.exports = MyRenderer;
<commit_msg>Updated example<commit_after>'use strict';

const incheon = require('../../../../../');
const Renderer = incheon.render.Renderer;

class MyRenderer extends Renderer {

    constructor(gameEngine, clientEngine) {
        super(gameEngine, clientEngine);
        this.sprites = {};
    }

    draw() {
        super.draw();
    }

    addObject(objData, options) {
        let sprite = {};

        // add this object to the renderer:
        // if (objData instanceof PlayerAvatar) {
        //     ...
        // }

        Object.assign(sprite, options);
        this.sprites[objData.id] = sprite;

        return sprite;
    }

    removeObject(obj) {
        obj.destroy();
        delete this.sprites[obj.id];
    }

}

module.exports = MyRenderer;
<|endoftext|>


<commit_before>/*
    ***** BEGIN LICENSE BLOCK *****

    Copyright  2009 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org

    This file is part of Zotero.

    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.

	Based on nsChromeExtensionHandler example code by Ed Anuff at
	http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol

    ***** END LICENSE BLOCK *****
*/

/*
	Based on nsICommandLineHandler example code at
	https://developer.mozilla.org/en/Chrome/Command_Line
*/

const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=zotero";
const clh_CID = Components.ID("{531828f8-a16c-46be-b9aa-14845c3b010f}");
const clh_category = "m-zotero";
const clh_description = "Zotero Command Line Handler";

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

/**
 * The XPCOM component that implements nsICommandLineHandler.
 */
function ZoteroCommandLineHandler() {}
ZoteroCommandLineHandler.prototype = {
	/* nsISupports */
	QueryInterface : XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler,
			Components.interfaces.nsIFactory, Components.interfaces.nsISupports]),

	/* nsICommandLineHandler */
	handle : function(cmdLine) {
		// handler for Zotero integration commands
		// this is typically used on Windows only, via WM_COPYDATA rather than the command line
		var agent = cmdLine.handleFlagWithParam("ZoteroIntegrationAgent", false);
		if(agent) {
			// Don't open a new window
			cmdLine.preventDefault = true;

			var command = cmdLine.handleFlagWithParam("ZoteroIntegrationCommand", false);
			var docId = cmdLine.handleFlagWithParam("ZoteroIntegrationDocument", false);

			// Not quite sure why this is necessary to get the appropriate scoping
			var Zotero = this.Zotero;
			Zotero.setTimeout(function() { Zotero.Integration.execCommand(agent, command, docId) }, 0);
		}

		// handler for Windows IPC commands
		var param = cmdLine.handleFlagWithParam("ZoteroIPC", false);
		if(param) {
			// Don't open a new window
			cmdLine.preventDefault = true;
			this.Zotero.IPC.parsePipeInput(param);
		}

		// special handler for "zotero" URIs at the command line to prevent them from opening a new
		// window
		if(this.Zotero.isStandalone) {
			var param = cmdLine.handleFlagWithParam("url", false);
			if(param) {
				var uri = cmdLine.resolveURI(param);
				if(uri.schemeIs("zotero")) {
					// Don't open a new window
					cmdLine.preventDefault = true;

					Components.classes["@mozilla.org/network/protocol;1?name=zotero"]
							.createInstance(Components.interfaces.nsIProtocolHandler).newChannel(uri);
				}
			}
		}
	},

	classDescription: clh_description,
	classID: clh_CID,
	contractID: clh_contractID,
	service: true,
	_xpcom_categories: [{category:"command-line-handler", entry:clh_category}],
	QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler,
	                                       Components.interfaces.nsISupports])
};

ZoteroCommandLineHandler.prototype.__defineGetter__("Zotero", function() {
	if(!this._Zotero) {
		this._Zotero = Components.classes["@zotero.org/Zotero;1"]
				.getService(Components.interfaces.nsISupports).wrappedJSObject;
	}
	return this._Zotero;
});

/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
if (XPCOMUtils.generateNSGetFactory) {
	var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroCommandLineHandler]);
} else {
	var NSGetModule = XPCOMUtils.generateNSGetModule([ZoteroCommandLineHandler]);
}<commit_msg>Focus window in command line handler<commit_after>/*
    ***** BEGIN LICENSE BLOCK *****

    Copyright  2009 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org

    This file is part of Zotero.

    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.

	Based on nsChromeExtensionHandler example code by Ed Anuff at
	http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol

    ***** END LICENSE BLOCK *****
*/

/*
	Based on nsICommandLineHandler example code at
	https://developer.mozilla.org/en/Chrome/Command_Line
*/

const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=zotero";
const clh_CID = Components.ID("{531828f8-a16c-46be-b9aa-14845c3b010f}");
const clh_category = "m-zotero";
const clh_description = "Zotero Command Line Handler";

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

/**
 * The XPCOM component that implements nsICommandLineHandler.
 */
function ZoteroCommandLineHandler() {}
ZoteroCommandLineHandler.prototype = {
	/* nsISupports */
	QueryInterface : XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler,
			Components.interfaces.nsIFactory, Components.interfaces.nsISupports]),

	/* nsICommandLineHandler */
	handle : function(cmdLine) {
		// handler for Zotero integration commands
		// this is typically used on Windows only, via WM_COPYDATA rather than the command line
		var agent = cmdLine.handleFlagWithParam("ZoteroIntegrationAgent", false);
		if(agent) {
			// Don't open a new window
			cmdLine.preventDefault = true;

			var command = cmdLine.handleFlagWithParam("ZoteroIntegrationCommand", false);
			var docId = cmdLine.handleFlagWithParam("ZoteroIntegrationDocument", false);

			// Not quite sure why this is necessary to get the appropriate scoping
			var Zotero = this.Zotero;
			Zotero.setTimeout(function() { Zotero.Integration.execCommand(agent, command, docId) }, 0);
		}

		// handler for Windows IPC commands
		var param = cmdLine.handleFlagWithParam("ZoteroIPC", false);
		if(param) {
			// Don't open a new window
			cmdLine.preventDefault = true;
			this.Zotero.IPC.parsePipeInput(param);
		}

		// special handler for "zotero" URIs at the command line to prevent them from opening a new
		// window
		if(this.Zotero.isStandalone) {
			var param = cmdLine.handleFlagWithParam("url", false);
			if(param) {
				var uri = cmdLine.resolveURI(param);
				if(uri.schemeIs("zotero")) {
					// Check for existing window and focus it
					var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
						.getService(Components.interfaces.nsIWindowMediator);
					var win = wm.getMostRecentWindow("navigator:browser");
					if(win) {
						cmdLine.preventDefault = true;
						win.focus();
						Components.classes["@mozilla.org/network/protocol;1?name=zotero"]
							.createInstance(Components.interfaces.nsIProtocolHandler).newChannel(uri);
					}
				}
			}
		}
	},

	classDescription: clh_description,
	classID: clh_CID,
	contractID: clh_contractID,
	service: true,
	_xpcom_categories: [{category:"command-line-handler", entry:clh_category}],
	QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler,
	                                       Components.interfaces.nsISupports])
};

ZoteroCommandLineHandler.prototype.__defineGetter__("Zotero", function() {
	if(!this._Zotero) {
		this._Zotero = Components.classes["@zotero.org/Zotero;1"]
				.getService(Components.interfaces.nsISupports).wrappedJSObject;
	}
	return this._Zotero;
});

/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
if (XPCOMUtils.generateNSGetFactory) {
	var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroCommandLineHandler]);
} else {
	var NSGetModule = XPCOMUtils.generateNSGetModule([ZoteroCommandLineHandler]);
}<|endoftext|>


<commit_before>/* Adapted from https://github.com/muaz-khan/RecordRTC/blob/master/index.html */
var recordingDIV = document.querySelector('.recordrtc');
var recordingMedia = 'record-video';
var recordingPlayer = recordingDIV.querySelector('video.rtcvideo');
var mimeType = 'video/webm';
var fileExtension = 'webm';
var type = 'video';
var defaultWidth;
var defaultHeight;
var timeSlice = false;

var btnStartRecording = document.querySelector('#btn-start-recording');

//recordingPlayer.style.display = 'none';

window.onbeforeunload = function() {
    btnStartRecording.disabled = false;
    recordingMedia.disabled = false;
};

btnStartRecording.onclick = function(event) {
    var button = btnStartRecording;

    if(button.innerHTML === stop_text) {
        button.disabled = true;
        button.disableStateWaiting = true;
        setTimeout(function() {
            button.disabled = false;
            button.disableStateWaiting = false;
        }, 2 * 1000);

        button.innerHTML = start_recording_text;

        function stopStream() {
            if(button.stream && button.stream.stop) {
                let tracks = button.stream.getTracks();
                // Stop each track instead of stopping the whole stream.
                tracks.forEach(function(track) {
                    track.stop();
                });
                button.stream = null;
            }

            videoBitsPerSecond = null;
        }

        if(button.recordRTC) {
            if(button.recordRTC.length) {
                button.recordRTC[0].stopRecording(function(url) {
                });
            }
            else {
                button.recordRTC.stopRecording(function(url) {
                    if(button.blobs && button.blobs.length) {
                        var blob = new File(button.blobs, getFileName(fileExtension), {
                            type: mimeType
                        });

                        button.recordRTC.getBlob = function() {
                            return blob;
                        };

                        url = URL.createObjectURL(blob);
                    }

                    button.recordingEndedCallback(url);
                    saveToDiskOrOpenNewTab(button.recordRTC);
                    stopStream();
                });
            }
        }

        return;
    }

    if(!event) return;

    button.disabled = true;

    var commonConfig = {
        onMediaCaptured: function(stream) {
            button.stream = stream;
            if(button.mediaCapturedCallback) {
                button.mediaCapturedCallback();
            }

            button.innerHTML = stop_recording_text;
            button.disabled = false;
        },
        onMediaStopped: function() {
            button.innerHTML = start_recording_text;

            if(!button.disableStateWaiting) {
                button.disabled = false;
            }
        },
        onMediaCapturingFailed: function(error) {
            console.error('onMediaCapturingFailed:', error);
            commonConfig.onMediaStopped();
        }
    };

    // Record only camera, no audio
    if(recordingMedia === 'record-video') {
        captureVideo(commonConfig);

        var options = {
            type: type,
            mimeType: mimeType,
            disableLogs: params.disableLogs || false,
            //getNativeBlob: false, // enable it for longer recordings
            video: recordingPlayer
        };

        button.mediaCapturedCallback = function() {
            if(typeof MediaRecorder === 'undefined') { // opera or chrome etc.
                button.recordRTC = [];

                if(!params.bufferSize) {
                    // it fixes audio issues whilst recording 720p
                    params.bufferSize = 16384;
                }

                if(params.bufferSize) {
                    options.bufferSize = parseInt(params.bufferSize);
                }

                if(params.frameInterval) {
                    options.frameInterval = parseInt(params.frameInterval);
                }

                if(videoBitsPerSecond) {
                    options.videoBitsPerSecond = videoBitsPerSecond;
                }

                var videoRecorder = RecordRTC(button.stream, options);

                // Start recording
                videoRecorder.initRecorder(function() {
                    videoRecorder.startRecording();
                });

                button.recordRTC.push(videoRecorder);

                button.recordingEndedCallback = function() {
                    recordingPlayer.parentNode.appendChild(document.createElement('hr'));
                };
                return;
            }

            if(videoBitsPerSecond) {
                options.videoBitsPerSecond = videoBitsPerSecond;
            }

            button.recordRTC = RecordRTC(button.stream, options);

            button.recordingEndedCallback = function(url) {
                setVideoURL(url);
            };

            button.recordRTC.startRecording();
        };
    }
};

function captureVideo(config) {
    captureUserMedia({video: true, audio: false}, function(videoStream) {
        config.onMediaCaptured(videoStream);

        addStreamStopListener(videoStream, function() {
            config.onMediaStopped();
        });
    }, function(error) {
        config.onMediaCapturingFailed(error);
    });
}

var videoBitsPerSecond;

function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
    if(mediaConstraints.video == true) {
        mediaConstraints.video = {};
    }
    videoBitsPerSecond = null;

    navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(stream) {
        successCallback(stream);

        setVideoURL(stream);
    }).catch(function(error) {
        if(error && error.name === 'ConstraintNotSatisfiedError') {
            alert(resolution_error_text);
        }

        errorCallback(error);
    });
}

function saveToDiskOrOpenNewTab(recordRTC) {
    var fileName = getFileName(fileExtension);

    // upload to server
    recordingDIV.querySelector('#upload-to-server').parentNode.style.display = 'block';
    recordingDIV.querySelector('#upload-to-server').disabled = false;
    recordingDIV.querySelector('#upload-to-server').onclick = function() {
        if(!recordRTC) return alert(no_recording_found_text);
        this.disabled = true;

        var button = this;
        uploadToServer(fileName, recordRTC, function(progress, fileURL) {
            if(progress === 'ended') {
                button.disabled = false;
                button.innerHTML = download_text;
                var alert = document.createElement("div");
                alert.setAttribute('class', 'alert alert-success');
                alert.innerHTML = upload_completed_text;
                button.parentNode.appendChild(alert);
                button.onclick = function() {
                    SaveFileURLToDisk(fileURL, fileName);
                };

                setVideoURL(fileURL);
                return;
            }
            button.innerHTML = progress;
        });
    };
}

function uploadToServer(fileName, recordRTC, callback) {
    var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob();

    blob = new File([blob], getFileName(fileExtension), {
        type: mimeType
    });

    // create FormData
    var formData = new FormData();
    formData.append('videofile', blob);
    formData.append('gloss', gloss_pk);
    formData.append('csrfmiddlewaretoken', csrf_token);

    callback('Uploading recorded-file to server.');

    makeXMLHttpRequest('/video/upload/recorded/', formData, function(progress, responseJSON) {
        if (progress !== 'upload-ended') {
            callback(progress);
            return;
        }
        responseJSON = JSON.parse(responseJSON);
        // Parse the video id from json key 'videoid'
        var initialURL = '/video/'+responseJSON["videoid"]+'/';
        callback('ended', initialURL);
    });
}

function makeXMLHttpRequest(url, data, callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            // Get video id, so that we can link to the created one
            callback('upload-ended', request.response);
        }
    };

    request.upload.onloadstart = function() {
        callback('Upload started');
    };

    request.upload.onprogress = function(event) {
        callback('Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%");
    };

    request.upload.onload = function() {
        callback('progress-about-to-end');
    };

    request.upload.onload = function() {
        callback('progress-ended');
    };

    request.upload.onerror = function(error) {
        callback('Failed to upload to server');
    };

    request.upload.onabort = function(error) {
        callback('Upload aborted.');
    };

    request.upload.onloadend = function() {
        callback('Done.');
    }

    request.open('POST', url);
    request.send(data);
}

function getRandomString() {
    if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) {
        var a = window.crypto.getRandomValues(new Uint32Array(3)),
            token = '';
        for (var i = 0, l = a.length; i < l; i++) {
            token += a[i].toString(36);
        }
        return token;
    } else {
        return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
    }
}
function getFileName(fileExtension) {
    return 'RecordRTC-' + (new Date).toISOString().replace(/:|\./g, '-')+ '-' + getRandomString() + '.' + fileExtension;
}

function SaveFileURLToDisk(fileUrl, fileName) {
    var hyperlink = document.createElement('a');
    hyperlink.href = fileUrl;
    hyperlink.target = '_blank';
    hyperlink.download = fileName || fileUrl;

    (document.body || document.documentElement).appendChild(hyperlink);
    hyperlink.onclick = function() {
       (document.body || document.documentElement).removeChild(hyperlink);

        // required for Firefox
        window.URL.revokeObjectURL(hyperlink.href);
    };

    var mouseEvent = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
    });

    hyperlink.dispatchEvent(mouseEvent);

}

function getURL(arg) {
    var url = arg;

    if(arg instanceof Blob || arg instanceof File) {
        url = URL.createObjectURL(arg);
    }

    if(arg instanceof RecordRTC || arg.getBlob) {
        url = URL.createObjectURL(arg.getBlob());
    }

    if(arg instanceof MediaStream || arg.getTracks || arg.getVideoTracks) {
        // Using MediaStream with URL.createObjectURL is deprecated,
        // use MediaSource instead.
        // url = URL.createObjectURL(arg);
    }

    return url;
}

function setVideoURL(arg) {
    var url = getURL(arg);

    var parentNode = recordingPlayer.parentNode;
    parentNode.removeChild(recordingPlayer);
    parentNode.innerHTML = '';

    var elem = 'video';

    recordingPlayer = document.createElement(elem);

    if(arg instanceof MediaStream) {
        recordingPlayer.muted = true;
    }

    recordingPlayer.addEventListener('loadedmetadata', function() {
        if(navigator.userAgent.toLowerCase().indexOf('android') == -1) return;

        // android
        setTimeout(function() {
            if(typeof recordingPlayer.play === 'function') {
                recordingPlayer.play();
            }
        }, 2000);
    }, false);

    recordingPlayer.poster = '';

    if(arg instanceof MediaStream) {
        recordingPlayer.srcObject = arg;
    }
    else {
        recordingPlayer.src = url;
    }

    if(typeof recordingPlayer.play === 'function') {
        recordingPlayer.play();
    }

    recordingPlayer.controls = true;
    parentNode.appendChild(recordingPlayer);
}
<commit_msg>Trying to choose VP8 for webcam recording, added ideal resolution. For some reason some Chrome version recorded H264 into webm container, therefore trying to pick VP8 here.<commit_after>/* Adapted from https://github.com/muaz-khan/RecordRTC/blob/master/index.html */
var recordingDIV = document.querySelector('.recordrtc');
var recordingMedia = 'record-video';
var recordingPlayer = recordingDIV.querySelector('video.rtcvideo');
var mimeType = 'video/webm\;codecs=vp8';
var fileExtension = 'webm';
var type = 'video';
var defaultWidth;
var defaultHeight;
var timeSlice = false;

var btnStartRecording = document.querySelector('#btn-start-recording');

//recordingPlayer.style.display = 'none';

window.onbeforeunload = function() {
    btnStartRecording.disabled = false;
    recordingMedia.disabled = false;
};

btnStartRecording.onclick = function(event) {
    var button = btnStartRecording;

    if(button.innerHTML === stop_text) {
        button.disabled = true;
        button.disableStateWaiting = true;
        setTimeout(function() {
            button.disabled = false;
            button.disableStateWaiting = false;
        }, 2 * 1000);

        button.innerHTML = start_recording_text;

        function stopStream() {
            if(button.stream && button.stream.stop) {
                var tracks = button.stream.getTracks();
                // Stop each track instead of stopping the whole stream.
                tracks.forEach(function(track) {
                    track.stop();
                });
                button.stream = null;
            }

            videoBitsPerSecond = null;
        }

        if(button.recordRTC) {
            if(button.recordRTC.length) {
                button.recordRTC[0].stopRecording(function(url) {
                });
            }
            else {
                button.recordRTC.stopRecording(function(url) {
                    if(button.blobs && button.blobs.length) {
                        var blob = new File(button.blobs, getFileName(fileExtension), {
                            type: mimeType
                        });

                        button.recordRTC.getBlob = function() {
                            return blob;
                        };

                        url = URL.createObjectURL(blob);
                    }

                    button.recordingEndedCallback(url);
                    saveToDiskOrOpenNewTab(button.recordRTC);
                    stopStream();
                });
            }
        }

        return;
    }

    if(!event) return;

    button.disabled = true;

    var commonConfig = {
        onMediaCaptured: function(stream) {
            button.stream = stream;
            if(button.mediaCapturedCallback) {
                button.mediaCapturedCallback();
            }

            button.innerHTML = stop_recording_text;
            button.disabled = false;
        },
        onMediaStopped: function() {
            button.innerHTML = start_recording_text;

            if(!button.disableStateWaiting) {
                button.disabled = false;
            }
        },
        onMediaCapturingFailed: function(error) {
            console.error('onMediaCapturingFailed:', error);
            commonConfig.onMediaStopped();
        }
    };

    // Record only camera, no audio
    if(recordingMedia === 'record-video') {
        captureVideo(commonConfig);

        var options = {
            type: type,
            mimeType: mimeType,
            disableLogs: params.disableLogs || false,
            //getNativeBlob: false, // enable it for longer recordings
            video: recordingPlayer
        };

        button.mediaCapturedCallback = function() {
            if(typeof MediaRecorder === 'undefined') { // opera or chrome etc.
                button.recordRTC = [];

                if(!params.bufferSize) {
                    // it fixes audio issues whilst recording 720p
                    params.bufferSize = 16384;
                }

                if(params.bufferSize) {
                    options.bufferSize = parseInt(params.bufferSize);
                }

                if(params.frameInterval) {
                    options.frameInterval = parseInt(params.frameInterval);
                }

                if(videoBitsPerSecond) {
                    options.videoBitsPerSecond = videoBitsPerSecond;
                }

                var videoRecorder = RecordRTC(button.stream, options);

                // Start recording
                videoRecorder.initRecorder(function() {
                    videoRecorder.startRecording();
                });

                button.recordRTC.push(videoRecorder);

                button.recordingEndedCallback = function() {
                    recordingPlayer.parentNode.appendChild(document.createElement('hr'));
                };
                return;
            }

            if(videoBitsPerSecond) {
                options.videoBitsPerSecond = videoBitsPerSecond;
            }

            button.recordRTC = RecordRTC(button.stream, options);

            button.recordingEndedCallback = function(url) {
                setVideoURL(url);
            };

            button.recordRTC.startRecording();
        };
    }
};

function captureVideo(config) {
    var constraints = {
        audio: false,
        video: {
            width: { ideal: 1280, max: 1920 },
            height: { ideal: 720, max: 1080 }
        }
    }
    captureUserMedia(constraints, function(videoStream) {
        config.onMediaCaptured(videoStream);

        addStreamStopListener(videoStream, function() {
            config.onMediaStopped();
        });
    }, function(error) {
        config.onMediaCapturingFailed(error);
    });
}

var videoBitsPerSecond;

function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
    if(mediaConstraints.video == true) {
        mediaConstraints.video = {};
    }
    videoBitsPerSecond = null;

    navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(stream) {
        successCallback(stream);

        setVideoURL(stream);
    }).catch(function(error) {
        if(error && error.name === 'ConstraintNotSatisfiedError') {
            alert(resolution_error_text);
        }

        errorCallback(error);
    });
}

function saveToDiskOrOpenNewTab(recordRTC) {
    var fileName = getFileName(fileExtension);

    // upload to server
    recordingDIV.querySelector('#upload-to-server').parentNode.style.display = 'block';
    recordingDIV.querySelector('#upload-to-server').disabled = false;
    recordingDIV.querySelector('#upload-to-server').onclick = function() {
        if(!recordRTC) return alert(no_recording_found_text);
        this.disabled = true;

        var button = this;
        uploadToServer(fileName, recordRTC, function(progress, fileURL) {
            if(progress === 'ended') {
                button.disabled = false;
                button.innerHTML = download_text;
                var alert = document.createElement("div");
                alert.setAttribute('class', 'alert alert-success');
                alert.innerHTML = upload_completed_text;
                button.parentNode.appendChild(alert);
                button.onclick = function() {
                    SaveFileURLToDisk(fileURL, fileName);
                };

                setVideoURL(fileURL);
                return;
            }
            button.innerHTML = progress;
        });
    };
}

function uploadToServer(fileName, recordRTC, callback) {
    var blob = recordRTC instanceof Blob ? recordRTC : recordRTC.getBlob();

    blob = new File([blob], getFileName(fileExtension), {
        type: mimeType
    });

    // create FormData
    var formData = new FormData();
    formData.append('videofile', blob);
    formData.append('gloss', gloss_pk);
    formData.append('csrfmiddlewaretoken', csrf_token);

    callback('Uploading recorded-file to server.');

    makeXMLHttpRequest('/video/upload/recorded/', formData, function(progress, responseJSON) {
        if (progress !== 'upload-ended') {
            callback(progress);
            return;
        }
        responseJSON = JSON.parse(responseJSON);
        // Parse the video id from json key 'videoid'
        var initialURL = '/video/'+responseJSON["videoid"]+'/';
        callback('ended', initialURL);
    });
}

function makeXMLHttpRequest(url, data, callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            // Get video id, so that we can link to the created one
            callback('upload-ended', request.response);
        }
    };

    request.upload.onloadstart = function() {
        callback('Upload started');
    };

    request.upload.onprogress = function(event) {
        callback('Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%");
    };

    request.upload.onload = function() {
        callback('progress-about-to-end');
    };

    request.upload.onload = function() {
        callback('progress-ended');
    };

    request.upload.onerror = function(error) {
        callback('Failed to upload to server');
    };

    request.upload.onabort = function(error) {
        callback('Upload aborted.');
    };

    request.upload.onloadend = function() {
        callback('Done.');
    }

    request.open('POST', url);
    request.send(data);
}

function getRandomString() {
    if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) {
        var a = window.crypto.getRandomValues(new Uint32Array(3)),
            token = '';
        for (var i = 0, l = a.length; i < l; i++) {
            token += a[i].toString(36);
        }
        return token;
    } else {
        return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
    }
}
function getFileName(fileExtension) {
    return 'RecordRTC-' + (new Date).toISOString().replace(/:|\./g, '-')+ '-' + getRandomString() + '.' + fileExtension;
}

function SaveFileURLToDisk(fileUrl, fileName) {
    var hyperlink = document.createElement('a');
    hyperlink.href = fileUrl;
    hyperlink.target = '_blank';
    hyperlink.download = fileName || fileUrl;

    (document.body || document.documentElement).appendChild(hyperlink);
    hyperlink.onclick = function() {
       (document.body || document.documentElement).removeChild(hyperlink);

        // required for Firefox
        window.URL.revokeObjectURL(hyperlink.href);
    };

    var mouseEvent = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
    });

    hyperlink.dispatchEvent(mouseEvent);

}

function getURL(arg) {
    var url = arg;

    if(arg instanceof Blob || arg instanceof File) {
        url = URL.createObjectURL(arg);
    }

    if(arg instanceof RecordRTC || arg.getBlob) {
        url = URL.createObjectURL(arg.getBlob());
    }

    if(arg instanceof MediaStream || arg.getTracks || arg.getVideoTracks) {
        // Using MediaStream with URL.createObjectURL is deprecated,
        // use MediaSource instead.
        // url = URL.createObjectURL(arg);
    }

    return url;
}

function setVideoURL(arg) {
    var url = getURL(arg);

    var parentNode = recordingPlayer.parentNode;
    parentNode.removeChild(recordingPlayer);
    parentNode.innerHTML = '';

    var elem = 'video';

    recordingPlayer = document.createElement(elem);

    if(arg instanceof MediaStream) {
        recordingPlayer.muted = true;
    }

    recordingPlayer.addEventListener('loadedmetadata', function() {
        if(navigator.userAgent.toLowerCase().indexOf('android') == -1) return;

        // android
        setTimeout(function() {
            if(typeof recordingPlayer.play === 'function') {
                recordingPlayer.play();
            }
        }, 2000);
    }, false);

    recordingPlayer.poster = '';

    if(arg instanceof MediaStream) {
        recordingPlayer.srcObject = arg;
    }
    else {
        recordingPlayer.src = url;
    }

    if(typeof recordingPlayer.play === 'function') {
        recordingPlayer.play();
    }

    recordingPlayer.controls = true;
    parentNode.appendChild(recordingPlayer);
}
<|endoftext|>


<commit_before>var roleHarvester = require('role.harvester');
var roleUpgrader = require('role.upgrader');
var roleBuilder = require('role.builder');
var roleRepairer = require('role.repairer');
var roleTransporter = require('role.transporter');
var roleDriller = require('role.driller');
var roleWallRepairer = require('role.wallrepairer');
var helper = require('helper');

module.exports.loop = function () {

    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            console.log('Clearing non-existing creep memory:', name);
        }
    }

    /*****************AUTO SPAWN*************************/
    if (Game.spawns.DCOS.spawning == null){
    var harvesters = _.filter(Game.creeps, (creep) => creep.memory.role == 'harvester');
    //console.log(harvesters.length + ' ' + Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]));
    if(harvesters.length < 0 && !Game.spawns.DCOS.canCreateCreep([WORK,WORK,CARRY,MOVE,MOVE])){
        var newName = Game.spawns.DCOS.createCreep([WORK,WORK,CARRY,MOVE,MOVE], undefined, {role: 'harvester', isHarvesting: false});
        console.log('Spawning new harvester: ' + newName);
    }
    else {
        var drillers = _.filter(Game.creeps, (creep) => creep.memory.role == 'driller');
        if (drillers.length < 1 && !(Game.spawns.DCOS.canCreateCreep([WORK,WORK,WORK,WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,WORK,WORK,WORK,CARRY,MOVE], undefined, {role: 'driller'});
            console.log('Spawning new driller: ' + newName);
        }
        var transporter = _.filter(Game.creeps, (creep) => creep.memory.role == 'transporter');
        if (transporter.length < 2 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,CARRY,MOVE,MOVE,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,CARRY,MOVE,MOVE,MOVE], undefined, {role: 'transporter'});
            console.log('Spawning new transporter: ' + newName);
        }
        var builders = _.filter(Game.creeps, (creep) => creep.memory.role == 'builder');
        if (builders.length < 5 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE,MOVE], undefined, {role: 'builder'});
            console.log('Spawning new builder: ' + newName);
        }
        var upgraders = _.filter(Game.creeps, (creep) => creep.memory.role == 'upgrader');
        if (upgraders.length < 1 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'upgrader'});
            console.log('Spawning new upgrader: ' + newName);
        }
        var repairers = _.filter(Game.creeps, (creep) => creep.memory.role == 'repairer');
        if (repairers.length < 3 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'repairer', filling: false});
            console.log('Spawning new repairer: ' + newName);
        }
        var wallrepairers = _.filter(Game.creeps, (creep) => creep.memory.role == 'wallrepairer');
        var targets = Game.spawns.DCOS.room.find(FIND_STRUCTURES, {
            filter: object => (object.hits < object.hitsMax && object.structureType == STRUCTURE_WALL)
            });
        if (wallrepairers.length < 3 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE])) && targets.length > 0){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'wallrepairer', filling: false});
            console.log('Spawning new wallrepairer: ' + newName);
        }
    }
    }

    /****************DEFENSE**************************/
    var tower = Game.getObjectById('578e40603ca308113b2f77b4');
    if(tower) {
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => (structure.hits < structure.hitsMax && !structure.type == STRUCTURE_WALL)
        });
        if(closestDamagedStructure) {
            tower.repair(closestDamagedStructure);
        }

        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(closestHostile) {
            tower.attack(closestHostile);
        }
    }

    /**************CREEPS*****************************/
    //helper.setHarvesting();

    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'harvester') {
            roleHarvester.run(creep);
        }
        if(creep.memory.role == 'upgrader') {
            roleUpgrader.run(creep);
        }
        if(creep.memory.role == 'builder') {
            roleBuilder.run(creep);
        }
        if(creep.memory.role == 'repairer') {
            roleRepairer.run(creep);
        }
        if(creep.memory.role == 'transporter') {
            roleTransporter.run(creep);
        }
        if(creep.memory.role == 'driller') {
            roleDriller.run(creep);
        }
        if(creep.memory.role == 'wallrepairer') {
            roleWallRepairer.run(creep);
        }
    }
}<commit_msg>2 drillers for room<commit_after>var roleHarvester = require('role.harvester');
var roleUpgrader = require('role.upgrader');
var roleBuilder = require('role.builder');
var roleRepairer = require('role.repairer');
var roleTransporter = require('role.transporter');
var roleDriller = require('role.driller');
var roleWallRepairer = require('role.wallrepairer');
var helper = require('helper');

module.exports.loop = function () {

    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            console.log('Clearing non-existing creep memory:', name);
        }
    }

    /*****************AUTO SPAWN*************************/
    if (Game.spawns.DCOS.spawning == null){
    var harvesters = _.filter(Game.creeps, (creep) => creep.memory.role == 'harvester');
    //console.log(harvesters.length + ' ' + Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]));
    if(harvesters.length < 0 && !Game.spawns.DCOS.canCreateCreep([WORK,WORK,CARRY,MOVE,MOVE])){
        var newName = Game.spawns.DCOS.createCreep([WORK,WORK,CARRY,MOVE,MOVE], undefined, {role: 'harvester', isHarvesting: false});
        console.log('Spawning new harvester: ' + newName);
    }
    else {
        var drillers = _.filter(Game.creeps, (creep) => creep.memory.role == 'driller');
        if (drillers.length < 2 && !(Game.spawns.DCOS.canCreateCreep([WORK,WORK,WORK,WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,WORK,WORK,WORK,CARRY,MOVE], undefined, {role: 'driller'});
            console.log('Spawning new driller: ' + newName);
        }
        var transporter = _.filter(Game.creeps, (creep) => creep.memory.role == 'transporter');
        if (transporter.length < 2 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,CARRY,MOVE,MOVE,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,CARRY,MOVE,MOVE,MOVE], undefined, {role: 'transporter'});
            console.log('Spawning new transporter: ' + newName);
        }
        var builders = _.filter(Game.creeps, (creep) => creep.memory.role == 'builder');
        if (builders.length < 5 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE,MOVE], undefined, {role: 'builder'});
            console.log('Spawning new builder: ' + newName);
        }
        var upgraders = _.filter(Game.creeps, (creep) => creep.memory.role == 'upgrader');
        if (upgraders.length < 1 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'upgrader'});
            console.log('Spawning new upgrader: ' + newName);
        }
        var repairers = _.filter(Game.creeps, (creep) => creep.memory.role == 'repairer');
        if (repairers.length < 3 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE]))){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'repairer', filling: false});
            console.log('Spawning new repairer: ' + newName);
        }
        var wallrepairers = _.filter(Game.creeps, (creep) => creep.memory.role == 'wallrepairer');
        var targets = Game.spawns.DCOS.room.find(FIND_STRUCTURES, {
            filter: object => (object.hits < object.hitsMax && object.structureType == STRUCTURE_WALL)
            });
        if (wallrepairers.length < 3 && !(Game.spawns.DCOS.canCreateCreep([WORK,CARRY,MOVE])) && targets.length > 0){
            var newName = Game.spawns.DCOS.createCreep([WORK,CARRY,MOVE], undefined, {role: 'wallrepairer', filling: false});
            console.log('Spawning new wallrepairer: ' + newName);
        }
    }
    }

    /****************DEFENSE**************************/
    var tower = Game.getObjectById('578e40603ca308113b2f77b4');
    if(tower) {
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => (structure.hits < structure.hitsMax && !structure.type == STRUCTURE_WALL)
        });
        if(closestDamagedStructure) {
            tower.repair(closestDamagedStructure);
        }

        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(closestHostile) {
            tower.attack(closestHostile);
        }
    }

    /**************CREEPS*****************************/
    //helper.setHarvesting();

    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'harvester') {
            roleHarvester.run(creep);
        }
        if(creep.memory.role == 'upgrader') {
            roleUpgrader.run(creep);
        }
        if(creep.memory.role == 'builder') {
            roleBuilder.run(creep);
        }
        if(creep.memory.role == 'repairer') {
            roleRepairer.run(creep);
        }
        if(creep.memory.role == 'transporter') {
            roleTransporter.run(creep);
        }
        if(creep.memory.role == 'driller') {
            roleDriller.run(creep);
        }
        if(creep.memory.role == 'wallrepairer') {
            roleWallRepairer.run(creep);
        }
    }
}<|endoftext|>


<commit_before>var URL = require("url");
var buster = require("buster-core");

var capturedClient = require("./captured-client");

module.exports = {
    capturePath: "/capture",

    create: function (busterResources, sessionMiddleware, server) {
        var instance = Object.create(this);
        instance.capturedClients = [];
        instance.busterResources = busterResources;
        instance.server = server;
        bindToSessionMiddleware.call(instance, sessionMiddleware);

        return instance;
    },

    respond: function (req, res) {
        var url = URL.parse(req.url);

        if (url.pathname == this.capturePath) {
            this.logger.info("Capturing new client");
            captureClient.call(this, req, res);
            return true;
        }

        for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
            if (this.capturedClients[i].respond(req, res, url.pathname)) return true;
        }
    },

    startSession: function (session) {
        this.logger.debug("Broadcasting session start to captured clients");
        this.currentSession = session;
        for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
            this.capturedClients[i].startSession(session);
        }
    },

    endSession: function () {
        this.logger.debug("Broadcasting session end to captured clients");
        this.currentSession = null;
        for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
            this.capturedClients[i].endSession();
        }
    },

    header: function (height, resourceSetOpts) {
        this.headerHeight = height;
        resourceSetOpts.contextPath = "/clientHeader";
        this.headerResourceSet = this.busterResources.createResourceSet(resourceSetOpts);
        return this.headerResourceSet;
    }
};

function captureClient(req, res) {
    if (typeof(this.oncapture) != "function") {
        res.writeHead(500);
        res.write("Client was created with no 'oncapture' handler.");
        res.end();
        return;
    }

    var client = capturedClient.create(this.server, this.busterResources,
                                       this.headerResourceSet, this.headerHeight,
                                       this.currentSession);
    client.on("end", function () {
        unloadClient.call(this, client);
    }.bind(this));
    this.capturedClients.push(client);
    this.oncapture(req, res, client);
}

function unloadClient(client) {
    for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
        if (this.capturedClients[i] === client) {
            this.capturedClients.splice(i, 1);
            break;
        }
    }
}

function bindToSessionMiddleware(sessionMiddleware) {
    sessionMiddleware.on("session:start", function (session) {
        this.startSession(session);
    }.bind(this));

    sessionMiddleware.on("session:end", function () {
        this.endSession();
    }.bind(this));
}<commit_msg>Making private methods startSession and endSession on capture middleware private.<commit_after>var URL = require("url");
var buster = require("buster-core");

var capturedClient = require("./captured-client");

module.exports = {
    capturePath: "/capture",

    create: function (busterResources, sessionMiddleware, server) {
        var instance = Object.create(this);
        instance.capturedClients = [];
        instance.busterResources = busterResources;
        instance.server = server;
        bindToSessionMiddleware.call(instance, sessionMiddleware);

        return instance;
    },

    respond: function (req, res) {
        var url = URL.parse(req.url);

        if (url.pathname == this.capturePath) {
            this.logger.info("Capturing new client");
            captureClient.call(this, req, res);
            return true;
        }

        for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
            if (this.capturedClients[i].respond(req, res, url.pathname)) return true;
        }
    },

    header: function (height, resourceSetOpts) {
        this.headerHeight = height;
        resourceSetOpts.contextPath = "/clientHeader";
        this.headerResourceSet = this.busterResources.createResourceSet(resourceSetOpts);
        return this.headerResourceSet;
    }
};

function captureClient(req, res) {
    if (typeof(this.oncapture) != "function") {
        res.writeHead(500);
        res.write("Client was created with no 'oncapture' handler.");
        res.end();
        return;
    }

    var client = capturedClient.create(this.server, this.busterResources,
                                       this.headerResourceSet, this.headerHeight,
                                       this.currentSession);
    client.on("end", function () {
        unloadClient.call(this, client);
    }.bind(this));
    this.capturedClients.push(client);
    this.oncapture(req, res, client);
}

function unloadClient(client) {
    for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
        if (this.capturedClients[i] === client) {
            this.capturedClients.splice(i, 1);
            break;
        }
    }
}

function bindToSessionMiddleware(sessionMiddleware) {
    sessionMiddleware.on("session:start", function (session) {
        startSession.call(this, session);
    }.bind(this));

    sessionMiddleware.on("session:end", function () {
        endSession.call(this);
    }.bind(this));
}

function startSession(session) {
    this.logger.debug("Broadcasting session start to captured clients");
    this.currentSession = session;
    for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
        this.capturedClients[i].startSession(session);
    }
};

function endSession() {
    this.logger.debug("Broadcasting session end to captured clients");
    this.currentSession = null;
    for (var i = 0, ii = this.capturedClients.length; i < ii; i++) {
        this.capturedClients[i].endSession();
    }
};<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'TableCellFormatter',
  extends: 'FObjectProperty',

  requires: [
    'foam.core.FObjectProperty',
    'foam.u2.view.FnFormatter',
  ],

  properties: [
    {
      name: 'of',
      value: 'foam.u2.view.Formatter'
    },
    {
      name: 'adapt',
      value: function(o, f, prop) {
        if ( foam.Function.isInstance(f) ) {
          return prop.FnFormatter.create({f: f});
        }
        return prop.FObjectProperty.ADAPT.value.call(this, o, f, prop);
      }
    },
    {
      name: 'value',
      adapt: function(_, v) {
        return this.adapt.call(this, _, v, this);
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'TableCellPropertyRefinement',

  refines: 'foam.core.Property',

  properties: [
    {
      name: 'tableHeaderFormatter',
      value: function(axiom) {
        this.add(axiom.label || foam.String.labelize(axiom.name));
      }
    },
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      factory: function() {
        return foam.u2.view.FnFormatter.create({
          class: 'foam.u2.view.FnFormatter',
          f: function(value, obj, axiom) {
            this.add(value);
          }
        })
      }
    },
    {
      class: 'Int',
      name: 'tableWidth'
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'ActionTableCellFormatterRefinement',
  refines: 'foam.core.Action',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(_, obj, axiom) {
        this.
          startContext({ data: obj }).
          tag(axiom, {
            size: 'SMALL',
            buttonStyle: 'SECONDARY'
          }).
          endContext();
      }
    },
    {
      name: 'tableHeaderFormatter',
      value: function(axiom) {
        this.add(axiom.label);
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'EnumTableCellFormatterRefinement',
  refines: 'foam.core.Enum',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.add(value.label)
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectPropertyTableCellFormatterRefinement',
  refines: 'foam.core.FObjectProperty',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(obj) {
        this.callIf(obj, function() {
          this.start()
            .add(obj.toSummary())
          .end();
        })
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'UnitValueTableCellFormatterRefinement',
  refines: 'foam.core.UnitValue',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value, obj, axiom) {
        var unitProp = obj.cls_.getAxiomByName(axiom.unitPropName);
        if ( ! unitProp ) {
          console.warn(obj.cls_.name, ' does not have the property: ', axiom.unitPropName);
          this.add(value);
          return;
        }
        var self = this;
        this.add(foam.core.ExpressionSlot.create({
          args: [obj.slot(unitProp.name), obj.slot(axiom.name)],
          code: (unitId, propValue) => {
            // TODO: Replace currencyDAO with unitDAO
            return foam.core.PromiseSlot.create({
              promise: obj.__context__.currencyDAO.find(unitId).then((unit) => {
                var formatted = unit.format(propValue);
                self.tooltip = formatted;
                return formatted;
              })
            });
          }
        }));
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'StringArrayTableCellFormatterRefinement',
  refines: 'foam.core.StringArray',
  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.add(value.join(', '));
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectArrayTableCellFormatterRefinement',
  refines: 'foam.core.FObjectArray',
  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.callIf(value, function() {
          this.add(value.map(o => o.toSummary()).join(', '));
        });
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DateTableCellFormatterRefinement',
  refines: 'foam.core.Date',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(date) {
        // allow the browser to deal with this since we are technically using the user's preference
        if ( date ) {
          var formattedDate = date.toLocaleDateString();
          this.add(formattedDate);
          this.tooltip = formattedDate;
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DateTimeTableCellFormatterRefinement',
  refines: 'foam.core.DateTime',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(date) {
        // allow the browser to deal with this since we are technically using the user's preference
        if ( date ) {
          var formattedDate = date.toLocaleDateString();
          this.add(formattedDate);
          this.tooltip = formattedDate;
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DurationTableCellFormatterRefinement',
  refines: 'foam.core.Duration',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        value = Math.round(value);
        var hours = Math.floor(value / 3600000);
        value -= hours * 3600000;
        var minutes = Math.floor(value / 60000);
        value -= minutes * 60000;
        var seconds = Math.floor(value / 1000);
        value -= seconds * 1000;
        var milliseconds = value % 1000;

        // For long durations, don't show milliseconds
        if ( hours ) seconds = 0;

        // For longer durations, don't show seconds
        if ( minutes || hours ) milliseconds = 0;

        var formatted = [[hours, 'h'], [minutes, 'm'], [seconds, 's'], [milliseconds, 'ms']].reduce((acc, cur) => {
          return cur[0] > 0 ? acc.concat([cur[0] + cur[1]]) : acc;
        }, []).join(' ');

        this.add(formatted || '0ms');
      }
    }
  ]
});
<commit_msg>Indlude time in DateTime tableCellFormatter.<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'TableCellFormatter',
  extends: 'FObjectProperty',

  requires: [
    'foam.core.FObjectProperty',
    'foam.u2.view.FnFormatter',
  ],

  properties: [
    {
      name: 'of',
      value: 'foam.u2.view.Formatter'
    },
    {
      name: 'adapt',
      value: function(o, f, prop) {
        if ( foam.Function.isInstance(f) ) {
          return prop.FnFormatter.create({f: f});
        }
        return prop.FObjectProperty.ADAPT.value.call(this, o, f, prop);
      }
    },
    {
      name: 'value',
      adapt: function(_, v) {
        return this.adapt.call(this, _, v, this);
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'TableCellPropertyRefinement',

  refines: 'foam.core.Property',

  properties: [
    {
      name: 'tableHeaderFormatter',
      value: function(axiom) {
        this.add(axiom.label || foam.String.labelize(axiom.name));
      }
    },
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      factory: function() {
        return foam.u2.view.FnFormatter.create({
          class: 'foam.u2.view.FnFormatter',
          f: function(value, obj, axiom) {
            this.add(value);
          }
        })
      }
    },
    {
      class: 'Int',
      name: 'tableWidth'
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'ActionTableCellFormatterRefinement',
  refines: 'foam.core.Action',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(_, obj, axiom) {
        this.
          startContext({ data: obj }).
          tag(axiom, {
            size: 'SMALL',
            buttonStyle: 'SECONDARY'
          }).
          endContext();
      }
    },
    {
      name: 'tableHeaderFormatter',
      value: function(axiom) {
        this.add(axiom.label);
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'EnumTableCellFormatterRefinement',
  refines: 'foam.core.Enum',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.add(value.label)
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectPropertyTableCellFormatterRefinement',
  refines: 'foam.core.FObjectProperty',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(obj) {
        this.callIf(obj, function() {
          this.start()
            .add(obj.toSummary())
          .end();
        })
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'UnitValueTableCellFormatterRefinement',
  refines: 'foam.core.UnitValue',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value, obj, axiom) {
        var unitProp = obj.cls_.getAxiomByName(axiom.unitPropName);
        if ( ! unitProp ) {
          console.warn(obj.cls_.name, ' does not have the property: ', axiom.unitPropName);
          this.add(value);
          return;
        }
        var self = this;
        this.add(foam.core.ExpressionSlot.create({
          args: [obj.slot(unitProp.name), obj.slot(axiom.name)],
          code: (unitId, propValue) => {
            // TODO: Replace currencyDAO with unitDAO
            return foam.core.PromiseSlot.create({
              promise: obj.__context__.currencyDAO.find(unitId).then((unit) => {
                var formatted = unit.format(propValue);
                self.tooltip = formatted;
                return formatted;
              })
            });
          }
        }));
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'StringArrayTableCellFormatterRefinement',
  refines: 'foam.core.StringArray',
  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.add(value.join(', '));
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectArrayTableCellFormatterRefinement',
  refines: 'foam.core.FObjectArray',
  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        this.callIf(value, function() {
          this.add(value.map(o => o.toSummary()).join(', '));
        });
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DateTableCellFormatterRefinement',
  refines: 'foam.core.Date',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(date) {
        // allow the browser to deal with this since we are technically using the user's preference
        if ( date ) {
          var formattedDate = date.toLocaleDateString();
          this.add(formattedDate);
          this.tooltip = formattedDate;
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DateTimeTableCellFormatterRefinement',
  refines: 'foam.core.DateTime',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(date) {
        // allow the browser to deal with this since we are technically using the user's preference
        if ( date ) {
          // toLocaleString includes date and time
          var formattedDate = date.toLocaleString();
          this.add(formattedDate);
          this.tooltip = formattedDate;
        }
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2.view',
  name: 'DurationTableCellFormatterRefinement',
  refines: 'foam.core.Duration',

  properties: [
    {
      class: 'foam.u2.view.TableCellFormatter',
      name: 'tableCellFormatter',
      value: function(value) {
        value = Math.round(value);
        var hours = Math.floor(value / 3600000);
        value -= hours * 3600000;
        var minutes = Math.floor(value / 60000);
        value -= minutes * 60000;
        var seconds = Math.floor(value / 1000);
        value -= seconds * 1000;
        var milliseconds = value % 1000;

        // For long durations, don't show milliseconds
        if ( hours ) seconds = 0;

        // For longer durations, don't show seconds
        if ( minutes || hours ) milliseconds = 0;

        var formatted = [[hours, 'h'], [minutes, 'm'], [seconds, 's'], [milliseconds, 'ms']].reduce((acc, cur) => {
          return cur[0] > 0 ? acc.concat([cur[0] + cur[1]]) : acc;
        }, []).join(' ');

        this.add(formatted || '0ms');
      }
    }
  ]
});
<|endoftext|>


<commit_before>var titleInput = $('.title-input-js');
var descriptionInput = $('.description-input-js');
var saveButton = $('.save-button');
var i = 0;
var x = ['Swill', 'Plausible', 'Genius'];

$(document).ready(function(){
  renderIdeas();
});

function createNewIdea() {
  var title = titleInput.val();
  var description = descriptionInput.val();
  var id = Date.now();
  var details = JSON.stringify({'id': id, 'title': title, 'description': description, 'quality': 'Swill'});
  localStorage.setItem(id, details);

};

function clearIdeas() {
  $('ul').empty();
}

function renderIdeas() {
  for (var i in window.localStorage){
    var idea = JSON.parse(localStorage.getItem(i));
    var title = idea['title'];
    var description = idea['description'];
    var quality = idea['quality'];
    var id = idea['id'];
    renderTheIdea(id, title, description, quality);
  }
}

function renderTheIdea(id, title, description, quality) {
  $('ul').prepend(
    '
' +
      '
' +
      '
' + title + '
' +
      '<button class="delete-button" type=button></button>' +
      '
' +
      '
' + description + '
' +
      '
' +
      '<button class="upvote-button" type=button></button>' +
      '<button class="downvote-button" type=button></button>' +
      '
' + 'ranking: ' + quality + '
' +
      '
' +
    '
');
};

saveButton.on('click', function(){
  createNewIdea();
  clearIdeas();
  renderIdeas();
});

$('ul').on('click', '.delete-button', function() {
  $(this).parent().parent().remove('li');

});

$('ul').on('click', '.upvote-button', function() {
  var qualityOutput = $('.quality-value');
  if (i < 2) {
    i = (i+1);
    qualityOutput.replaceWith('
' + 'ranking: ' + x[i] + '
');
  }
  // if (i == 2) {
  //     $('.upvote-button').prop('disabled', true);
  //   }
});

$('ul').on('click', '.downvote-button', function() {
  var qualityOutput = $('.quality-value');
  if (i > 0) {
    i = (i-1);
    qualityOutput.replaceWith('
' + 'ranking: ' + x[i] + '
');
  }
  // if (i == 0) {
  //   $('.downvote-button').prop('disabled', true);
  // }
});

$('#search-bar').keyup(function(){
   var valThis = $(this).val().toLowerCase();
    $('li').each(function(){
     var text = $(this).text().toLowerCase();
        (text.indexOf(valThis) == 0) ? $(this).show() : $(this).hide();
   });
  });
<commit_msg>refactor2<commit_after>var titleInput = $('.title-input-js');
var descriptionInput = $('.description-input-js');
var saveButton = $('.save-button');
var i = 0;
var x = ['Swill', 'Plausible', 'Genius'];

$(document).ready(function(){
  renderIdeas();
});

function createNewIdea() {
  var title = titleInput.val();
  var description = descriptionInput.val();
  var id = Date.now();
  var details = JSON.stringify({'id': id, 'title': title, 'description': description, 'quality': 'Swill'});
  localStorage.setItem(id, details);

};

function clearIdeas() {
  $('ul').empty();
}

function renderIdeas() {
  for (var i in window.localStorage){
    var idea = JSON.parse(localStorage.getItem(i));
    var title = idea['title'];
    var description = idea['description'];
    var quality = idea['quality'];
    var id = idea['id'];
    renderTheIdea(id, title, description, quality);
  }
}

function renderTheIdea(id, title, description, quality) {
  $('ul').prepend(
    '
' +
      '
' +
      '
' + title + '
' +
      '<button class="delete-button" type=button></button>' +
      '
' +
      '
' + description + '
' +
      '
' +
      '<button class="upvote-button" type=button></button>' +
      '<button class="downvote-button" type=button></button>' +
      '
' + 'ranking: ' + quality + '
' +
      '
' +
    '
');
};

function destroyIdea( {
  localStorage.removeIdea(id);
})

saveButton.on('click', function(){
  createNewIdea();
  clearIdeas();
  renderIdeas();
});

$('ul').on('click', '.delete-button', function() {
  $(this).parent().parent().remove('li');
  destroyIdea();
  clearIdeas();
  renderIdeas();
});

$('ul').on('click', '.upvote-button', function() {
  var qualityOutput = $('.quality-value');
  if (i < 2) {
    i = (i+1);
    qualityOutput.replaceWith('
' + 'ranking: ' + x[i] + '
');
  }
  // if (i == 2) {
  //     $('.upvote-button').prop('disabled', true);
  //   }
});

$('ul').on('click', '.downvote-button', function() {
  var qualityOutput = $('.quality-value');
  if (i > 0) {
    i = (i-1);
    qualityOutput.replaceWith('
' + 'ranking: ' + x[i] + '
');
  }
  // if (i == 0) {
  //   $('.downvote-button').prop('disabled', true);
  // }
});

$('#search-bar').keyup(function(){
   var valThis = $(this).val().toLowerCase();
    $('li').each(function(){
     var text = $(this).text().toLowerCase();
        (text.indexOf(valThis) == 0) ? $(this).show() : $(this).hide();
   });
  });
<|endoftext|>


<commit_before>App.AssignmentsController = App.ListSuperController.extend({
    columns : ['#','Priority','Creator','Drone','Actions'],
    element : "assignment",
    searchFields : ["creator","drone"]
});

App.AssignmentsAddController = Ember.ArrayController.extend({
	selected: null,
	checkpoints: Ember.A([
		{ id: 0,  latitude: null, longitude: null, altitude: null, waitingTime: null }
	]),

	// ACTIONS
	actions: {
		/*
		 * Save the assignment in the database
		 */
		save: function(){
			var checkpoints = this.get('checkpoints');
			// Get all the checkpoints defining the route
			route = [];
            for (i = 0; i < checkpoints.length; ++i) {
                if(checkpoints[i].latitude != null && checkpoints[i].longitude != null && checkpoints[i].altitude != null) {
                    var location = new Object();
                    location.longitude = checkpoints[i].longitude;
                    location.latitude = checkpoints[i].latitude;
                    location.altitude = checkpoints[i].altitude;
                    var checkpoint = new Object();
                    checkpoint.location = location;
                    if(checkpoints[i].value != null)
                        checkpoint.waitingTime = checkpoints[i].waitingTime;
                    route.push(checkpoint);
                }
            }
			// Create an json object
			var assignment = new Object();
			assignment.route = route;
			assignment.priority = this.priority;
			var jsonObject = new Object();
			jsonObject.assignment = assignment;
			// Send the object to the server for saving
			var result = this.customAdapter.post('assignment', jsonObject);
			var self = this;
			result.then(
				function(data) { self.success(data.assignment.id); },
				function(data) { self.failure(data); }
			);
		},

		/*
		 * Add an checkpoint or a basestation (based on the selection
		 * made by the user). Adding a checkpoint results in appending
		 * a extra row to the form (cfr. RENDERING).
		 * Adding an basestation results in filling in the coordinates
		 * of that basestation into an empty row.
		 */
		add: function() {
			var checkpoints = this.get('checkpoints');
			if(this.selected != null) {
				var self = this;
				this.customAdapter.find('basestation', this.selected).then(function(data){
					$("select option").filter(function() {
						return $(this).text() == 'Checkpoint';
					}).prop('selected', true);
					self.set('selected', null);

					var addRow = true;
					for (i = 0; i < checkpoints.length; ++i) {
						if(checkpoints[i].latitude == null && checkpoints[i].longitude == null && checkpoints[i].altitude == null) {
							Ember.set(checkpoints[i], 'latitude', data.location.latitude);
							Ember.set(checkpoints[i], 'longitude', data.location.longitude);
							Ember.set(checkpoints[i], 'altitude', data.location.altitude);
							Ember.set(checkpoints[i], 'waitingTime', data.location.waitingTime);
							addRow = false;
							break;
						}
					}
					if(addRow)
						checkpoints.pushObject({ id: checkpoints.length,  latitude: data.location.latitude, longitude: data.location.longitude, altitude: data.location.altitude, waitingTime: data.location.waitingTime });
				});
			}
			else
				checkpoints.pushObject({ id: checkpoints.length,  latitude: null, longitude: null, altitude: null, waitingTime: null });
		},

		swap: function(nextID) {
			var checkpoints = this.get('checkpoints');
			var prevID = nextID - 1;
			var prevLongitude = checkpoints[prevID].longitude;
			var prevLatitude = checkpoints[prevID].latitude;
			var prevAltitude = checkpoints[prevID].altitude;
			var prevWaitingTime = checkpoints[prevID].waitingTime;
			Ember.set(checkpoints[prevID], 'latitude', checkpoints[nextID].latitude);
			Ember.set(checkpoints[prevID], 'longitude', checkpoints[nextID].longitude);
			Ember.set(checkpoints[prevID], 'altitude', checkpoints[nextID].altitude);
			Ember.set(checkpoints[prevID], 'waitingTime', checkpoints[nextID].waitingTime);
			Ember.set(checkpoints[nextID], 'latitude', prevLatitude);
			Ember.set(checkpoints[nextID], 'longitude', prevLongitude);
			Ember.set(checkpoints[nextID], 'altitude', prevAltitude);
			Ember.set(checkpoints[nextID], 'waitingTime', prevWaitingTime);
		}
	}
});<commit_msg>Undo removed lines causing error<commit_after>App.AssignmentsController = App.ListSuperController.extend({
    columns : ['#','Priority','Creator','Drone','Actions'],
    element : "assignment",
    searchFields : ["creator","drone"]
});

App.AssignmentsAddController = Ember.ArrayController.extend({
	selected: null,
	checkpoints: Ember.A([
		{ id: 0,  latitude: null, longitude: null, altitude: null, waitingTime: null }
	]),

	// ACTIONS
	actions: {
		/*
		 * Save the assignment in the database
		 */
		save: function(){
			var checkpoints = this.get('checkpoints');
			// Get all the checkpoints defining the route
			route = [];
            for (i = 0; i < checkpoints.length; ++i) {
                if(checkpoints[i].latitude != null && checkpoints[i].longitude != null && checkpoints[i].altitude != null) {
                    var location = new Object();
                    location.longitude = checkpoints[i].longitude;
                    location.latitude = checkpoints[i].latitude;
                    location.altitude = checkpoints[i].altitude;
                    var checkpoint = new Object();
                    checkpoint.location = location;
                    if(checkpoints[i].value != null)
                        checkpoint.waitingTime = checkpoints[i].waitingTime;
                    route.push(checkpoint);
                }
            }
			// Create an json object
			var assignment = new Object();
			assignment.route = route;
			assignment.priority = this.priority;
			var jsonObject = new Object();
			jsonObject.assignment = assignment;
			// Send the object to the server for saving
			var result = this.customAdapter.post('assignment', jsonObject);
			var self = this;
			result.then(
				function(data) { self.success(data.assignment.id); },
				function(data) { self.failure(data); }
			);
		},

		/*
		 * Add an checkpoint or a basestation (based on the selection
		 * made by the user). Adding a checkpoint results in appending
		 * a extra row to the form (cfr. RENDERING).
		 * Adding an basestation results in filling in the coordinates
		 * of that basestation into an empty row.
		 */
		add: function() {
			var checkpoints = this.get('checkpoints');
			if(this.selected != null) {
				var self = this;
				this.customAdapter.find('basestation', this.selected).then(function(data){
					$("select option").filter(function() {
						return $(this).text() == 'Checkpoint';
					}).prop('selected', true);
					self.set('selected', null);

					var addRow = true;
					for (i = 0; i < checkpoints.length; ++i) {
						if(checkpoints[i].latitude == null && checkpoints[i].longitude == null && checkpoints[i].altitude == null) {
							Ember.set(checkpoints[i], 'latitude', data.location.latitude);
							Ember.set(checkpoints[i], 'longitude', data.location.longitude);
							Ember.set(checkpoints[i], 'altitude', data.location.altitude);
							Ember.set(checkpoints[i], 'waitingTime', data.location.waitingTime);
							addRow = false;
							break;
						}
					}
					if(addRow)
						checkpoints.pushObject({ id: checkpoints.length,  latitude: data.location.latitude, longitude: data.location.longitude, altitude: data.location.altitude, waitingTime: data.location.waitingTime });
				});
			}
			else
				checkpoints.pushObject({ id: checkpoints.length,  latitude: null, longitude: null, altitude: null, waitingTime: null });
		},

		swap: function(nextID) {
			var checkpoints = this.get('checkpoints');
			var prevID = nextID - 1;
			var prevLongitude = checkpoints[prevID].longitude;
			var prevLatitude = checkpoints[prevID].latitude;
			var prevAltitude = checkpoints[prevID].altitude;
			var prevWaitingTime = checkpoints[prevID].waitingTime;
			Ember.set(checkpoints[prevID], 'latitude', checkpoints[nextID].latitude);
			Ember.set(checkpoints[prevID], 'longitude', checkpoints[nextID].longitude);
			Ember.set(checkpoints[prevID], 'altitude', checkpoints[nextID].altitude);
			Ember.set(checkpoints[prevID], 'waitingTime', checkpoints[nextID].waitingTime);
			Ember.set(checkpoints[nextID], 'latitude', prevLatitude);
			Ember.set(checkpoints[nextID], 'longitude', prevLongitude);
			Ember.set(checkpoints[nextID], 'altitude', prevAltitude);
			Ember.set(checkpoints[nextID], 'waitingTime', prevWaitingTime);
		}
	},

	/*
	 * Called on an successful save to the server.
	 */
	success: function(id) {
		this.priority = '';
		this.transitionToRoute('assignment', id);

	},

	/*
	 * Called on a failed save to the server.
	 */
	failure: function(data) {
		if (data.status == 400) {
			if(!$('#assignmentAlert')[0]) {
				$('#assignmentAddAlert')
					.append($('<div>')
						.attr('id', 'assignmentAlert')
						.attr('class', 'alert alert-danger alert-dismissible')
						.attr('role', 'alert')
					);
			}
			$('#assignmentAlert').text('');
			if(data.responseJSON.route)
				$('#assignmentAlert').append($('<p>').text('Route: at least one checkpoint (latitude, longitude and altitude) is required'));
			if(data.responseJSON.priority)
				$('#droneAlert').append($('<p>').text('Priority: ' + data.responseJSON.priority));
		}
	},
});<|endoftext|>