<commit_before>/**
 * Convert a object to string.
 *
 * @static
 * @param {*} object
 * @returns string or empty if null or undefined
 **/
module.exports = function toString(object) {
    if (object === null || object === undefined || isNaN(obhect)) {
        return '';
    }
    return object.toString();
};
<commit_msg>Update toString.js<commit_after>/**
 * Convert a object to string.
 *
 * @static
 * @param {*} object
 * @returns string or empty if null or undefined
 **/
module.exports = function toString(object) {
    if (object === null || object === undefined || isNaN(object)) {
        return '';
    }
    return object.toString();
};
<|endoftext|>


<commit_before>var nodemiral = require('nodemiral');
var fs = require('fs');
var path = require('path');
var util = require('util');

var SCRIPT_DIR = path.resolve(__dirname, '../../scripts/linux');
var TEMPLATES_DIR = path.resolve(__dirname, '../../templates/linux');

exports.setup = function(config) {
  var taskList = nodemiral.taskList('Setup (linux)');

  // Installation
  if(config.setupNode) {
    taskList.executeScript('Installing Node.js: ' + config.nodeVersion, {
      script: path.resolve(SCRIPT_DIR, 'install-node.sh'),
      vars: {
        nodeVersion: config.nodeVersion
      }
    });
  }

  if(config.setupPhantom) {
    taskList.executeScript('Installing PhantomJS', {
      script: path.resolve(SCRIPT_DIR, 'install-phantomjs.sh')
    });
  }

  taskList.executeScript('Setting up Environment', {
    script: path.resolve(SCRIPT_DIR, 'setup-env.sh'),
    vars: {
      appName: config.appName
    }
  });

  if(config.setupMongo) {
    taskList.copy('Copying MongoDB configuration', {
      src: path.resolve(TEMPLATES_DIR, 'mongodb.conf'),
      dest: '/etc/mongodb.conf'
    });

    taskList.executeScript('Installing MongoDB', {
      script: path.resolve(SCRIPT_DIR, 'install-mongodb.sh')
    });
  }

  if(config.ssl) {
    installStud(taskList);
    configureStud(taskList, config.ssl.pem, config.ssl.backendPort);
  }

  //Configurations
  taskList.copy('Configuring upstart', {
    src: path.resolve(TEMPLATES_DIR, 'meteor.conf'),
    dest: '/etc/init/' + config.appName + '.conf',
    vars: {
      appName: config.appName
    }
  });

  return taskList;
};

exports.deploy = function(bundlePath, env, deployCheckWaitTime, appName, enableUploadProgressBar) {
  var taskList = nodemiral.taskList("Deploy app '" + appName + "' (linux)");

  console.log(bundlePath + ' => ' + '/opt/' + appName + '/tmp/bundle.tar.gz');
  taskList.copy('Uploading bundle', {
    src: bundlePath,
    dest: '/opt/' + appName + '/tmp/bundle.tar.gz',
    progressBar: enableUploadProgressBar
  });

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  taskList.copy('Creating build.sh', {
    src: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    dest: '/opt/' + appName + '/build.sh',
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  // deploying
  taskList.executeScript('Invoking deployment process', {
    script: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  return taskList;
};

exports.reconfig = function(env, appName) {
  var taskList = nodemiral.taskList("Updating configurations (linux)");

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.restart = function(appName) {
  var taskList = nodemiral.taskList("Restarting Application (linux)");

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.stop = function(appName) {
  var taskList = nodemiral.taskList("Stopping Application (linux)");

  //stopping
  taskList.execute('Stopping app', {
    command: '(sudo stop ' + appName + ')'
  });

  return taskList;
};

exports.start = function(appName) {
  var taskList = nodemiral.taskList("Starting Application (linux)");

  //starting
  taskList.execute('Starting app', {
    command: '(sudo start ' + appName + ')'
  });

  return taskList;
};

function installStud(taskList) {
  taskList.executeScript('Installing Stud', {
    script: path.resolve(SCRIPT_DIR, 'install-stud.sh')
  });
}

function configureStud(taskList, pemFilePath, port) {
  var backend = {host: '127.0.0.1', port: port};

  taskList.copy('Configuring Stud for Upstart', {
    src: path.resolve(TEMPLATES_DIR, 'stud.init.conf'),
    dest: '/etc/init/stud.conf'
  });

  taskList.copy('Configuring SSL', {
    src: pemFilePath,
    dest: '/opt/stud/ssl.pem'
  });

  taskList.copy('Configuring Stud', {
    src: path.resolve(TEMPLATES_DIR, 'stud.conf'),
    dest: '/opt/stud/stud.conf',
    vars: {
      backend: util.format('[%s]:%d', backend.host, backend.port)
    }
  });

  taskList.execute('Verifying SSL Configurations (ssl.pem)', {
    command: 'stud --test --config=/opt/stud/stud.conf'
  });

  //restart stud
  taskList.execute('Starting Stud', {
    command: '(sudo stop stud || :) && (sudo start stud || :)'
  });
}
<commit_msg>Show more details to the console<commit_after>var nodemiral = require('nodemiral');
var fs = require('fs');
var path = require('path');
var util = require('util');

var SCRIPT_DIR = path.resolve(__dirname, '../../scripts/linux');
var TEMPLATES_DIR = path.resolve(__dirname, '../../templates/linux');

exports.setup = function(config) {
  var taskList = nodemiral.taskList('Setup (linux)');

  // Installation
  if(config.setupNode) {
    taskList.executeScript('Installing Node.js: ' + config.nodeVersion, {
      script: path.resolve(SCRIPT_DIR, 'install-node.sh'),
      vars: {
        nodeVersion: config.nodeVersion
      }
    });
  }

  if(config.setupPhantom) {
    taskList.executeScript('Installing PhantomJS', {
      script: path.resolve(SCRIPT_DIR, 'install-phantomjs.sh')
    });
  }

  taskList.executeScript('Setting up environment variable script', {
    script: path.resolve(SCRIPT_DIR, 'setup-env.sh'),
    vars: {
      appName: config.appName
    }
  });

  if (config.setupMongo) {
    // If the user prefers some mongodb config, read the option
    taskList.copy('Copying MongoDB configuration', {
      src: path.resolve(TEMPLATES_DIR, 'mongodb.conf'),
      dest: '/etc/mongodb.conf'
    });
    taskList.executeScript('Installing MongoDB', {
      script: path.resolve(SCRIPT_DIR, 'install-mongodb.sh')
    });
  }

  if (config.ssl) {
    installStud(taskList);
    configureStud(taskList, config.ssl.pem, config.ssl.backendPort);
  }

  var upstartConfig = '/etc/init/' + config.appName + '.conf';
  taskList.copy('Configuring upstart: ' + upstartConfig, {
    src: path.resolve(TEMPLATES_DIR, 'meteor.conf'),
    dest: upstartConfig,
    vars: {
      appName: config.appName
    }
  });

  return taskList;
};

exports.deploy = function(bundlePath, env, deployCheckWaitTime, appName, enableUploadProgressBar) {
  var taskList = nodemiral.taskList("Deploy app '" + appName + "' (linux)");

  console.log(bundlePath + ' => ' + '/opt/' + appName + '/tmp/bundle.tar.gz');
  taskList.copy('Uploading bundle', {
    src: bundlePath,
    dest: '/opt/' + appName + '/tmp/bundle.tar.gz',
    progressBar: enableUploadProgressBar
  });

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  taskList.copy('Creating build.sh', {
    src: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    dest: '/opt/' + appName + '/build.sh',
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  // deploying
  taskList.executeScript('Invoking deployment process', {
    script: path.resolve(TEMPLATES_DIR, 'deploy.sh'),
    vars: {
      deployCheckWaitTime: deployCheckWaitTime || 10,
      appName: appName
    }
  });

  return taskList;
};

exports.reconfig = function(env, appName) {
  var taskList = nodemiral.taskList("Updating configurations (linux)");

  taskList.copy('Setting up Environment Variables', {
    src: path.resolve(TEMPLATES_DIR, 'env.sh'),
    dest: '/opt/' + appName + '/config/env.sh',
    vars: {
      env: env || {},
      appName: appName
    }
  });

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.restart = function(appName) {
  var taskList = nodemiral.taskList("Restarting Application (linux)");

  //restarting
  taskList.execute('Restarting app', {
    command: '(sudo stop ' + appName + ' || :) && (sudo start ' + appName + ')'
  });

  return taskList;
};

exports.stop = function(appName) {
  var taskList = nodemiral.taskList("Stopping Application (linux)");

  //stopping
  taskList.execute('Stopping app', {
    command: '(sudo stop ' + appName + ')'
  });

  return taskList;
};

exports.start = function(appName) {
  var taskList = nodemiral.taskList("Starting Application (linux)");

  //starting
  taskList.execute('Starting app', {
    command: '(sudo start ' + appName + ')'
  });

  return taskList;
};

function installStud(taskList) {
  taskList.executeScript('Installing Stud', {
    script: path.resolve(SCRIPT_DIR, 'install-stud.sh')
  });
}

function configureStud(taskList, pemFilePath, port) {
  var backend = {host: '127.0.0.1', port: port};

  taskList.copy('Configuring Stud for Upstart', {
    src: path.resolve(TEMPLATES_DIR, 'stud.init.conf'),
    dest: '/etc/init/stud.conf'
  });

  taskList.copy('Configuring SSL', {
    src: pemFilePath,
    dest: '/opt/stud/ssl.pem'
  });

  taskList.copy('Configuring Stud', {
    src: path.resolve(TEMPLATES_DIR, 'stud.conf'),
    dest: '/opt/stud/stud.conf',
    vars: {
      backend: util.format('[%s]:%d', backend.host, backend.port)
    }
  });

  taskList.execute('Verifying SSL Configurations (ssl.pem)', {
    command: 'stud --test --config=/opt/stud/stud.conf'
  });

  //restart stud
  taskList.execute('Starting Stud', {
    command: '(sudo stop stud || :) && (sudo start stud || :)'
  });
}
<|endoftext|>


<commit_before>/*
	Class: UI.Container
		The UI.Container class defines objects manage the content of the container
		that manage containers use by several object like windows, menus.
*/

/**
 * [initialize description]
 * @class  UI.Container
 * @extends {UI.Component}
 * @author Jerome Vial
 */
define([
	"UI/Component/Component",
	"UI/Container/Display"
], function(
	Component,
	Display
) {

	var exports = new Class({

		Extends: Component,

		Implements: [Options, Events, Display],

		name: 'container',

		options: {
			name: 'container',

			node: null,

			tag: 'div',
			/*resizable: false,
			resizeBorders: ['top','right','bottom','left']*/
		},

		/**
		 * [initialize description]
		 * @param  {[type]} options [description]
		 * @return {[type]}         [description]
		 */
		initialize: function(options){
			this.parent(options);

			if (this.options.comp) {
				this._initComp(this.options.comp);
			} else {
				this._initComponent();
			}

			return this;
		},

		/*
		Method: _initElement
			private function

			Creates html structure and inject it to the dom. The container is _initElement with two elements: the wrapper and the content.
			If the option scroll is set to true, it will also add the scrollbar object

		Returns:
			(void)

		See also:
			<UI.Component::_initElement>
		*/
		_initElement: function() {
			//_log.debug('_initElement', this);
			this.parent();

			var opts = this.options;
			this.menu = {};

			if ( opts.head ) this._initHead( opts.head );
			if ( opts.menu ) this.setMenu( opts.menu );
			if ( this.name === 'window' ) this._initBody();
			if ( opts.useOverlay ) this._initOverlay();

			if ( opts.foot ) this._initFoot( opts.foot );

			var self = this;
			this.addEvent('injected', function() {
				var direction = self.container.getStyle('flex-direction');
				//_log.debug('direction', direction, this.element);
			});

			if (this.options.useUnderlay)
				this._initUnderlay();
		},

		/**
		 * [_initComponent description]
		 * @return {[type]} [description]
		 */
		_initComponent: function() {
			var self = this,
				opts = this.options;

			if (opts.node === null) return;

			//_log.debug('_initComponent', opts.node);

			this.node = [];

			if (typeOf(opts.node) === 'array') {
				for (var i = 0; i < opts.node.length; i++) {
					this.addComponent(opts.node[i]);
				}
			} else if (typeOf(opts.node) === 'object') {
				var node = opts.node;

				this.addComponent(node);
			}

		},

		/**
		 * Initialize internal container components
		 * @param  {Mixin} comp Compenent description
		 * @return {[type]}      [description]
		 */
		_initComp: function(comp) {
			//_log.debug('_initComp', comp);
			var self = this;

			if (typeOf(comp) === 'string' ) {
				this.addComp(comp);
			} else if (typeOf(comp) === 'object' ){

			} else if (typeOf(comp) === 'array' ) {
				comp.each(function(name) {
					self.addComp(name);
				});
			}
		},

		/**
		 * [_initComp description]
		 * @param  {[type]} name [description]
		 * @return {[type]}      [description]
		 */
		addComp: function(name, position, element) {
			//_log.debug('addComp', name, position, element);
			var self = this;
			position = position || 'bottom';
			element = element || this.element;

			//_log.debug('_addComp', name);

			if (!element) {
				_warn('Container is ', element);
				return;
			}

			var comp = this[name] = new Element('div')
				.addClass('container-'+name)
				.inject(element, position);

			return comp;
			/*this.addEvents({
				resize: function() {
					//_log.debug('resize from head', this, this.head.getSize().y+'px');
					this.element.setStyle('padding-top', this.head.getSize().y+'px');
				}
			});*/
		},

		/*
		Method: _initClass
			private function

			_initClass container related class

		Returns:
			(void)
		*/
		_initClass: function(){
			this.parent();

			this.element.addClass('ui-container');
		},

		/*
		Method: _initHead
			private function

			create an overlay displayed when container is disabled (when moved or resized)

		Returns:
			(void)
		 */
		_initHead: function() {
			var self = this;

			this.head = new Element('div')
				.addClass('container-head')
				.inject(this.element,'top')
				.addEvent('dblclick', function() {
					self.fireEvent('max');
				});
		},

		/**
		 * [setTitle description]
		 * @param {[type]} title [description]
		 */
		setTitle: function(title){
			if (this.title && this.head)
				return this.title.set('text', title);
		},

		/**
		 * [setTitle description]
		 * @param {[type]} title [description]
		 */
		getTitle: function(){
			//_log.debug('getTitle', this.title);
			if (this.title)
				return this.title.get('html');
		},

		/**
		 * [setMenu description]
		 * @deprecated Use toolbar instead
		 * @param {[type]} opts [description]
		 */
		/*setMenu: function(opts) {
			console.log('setMenu', opts);
			var self = this,
				comp = opts.comp || 'head';

			if (!this[comp])
				this['_init'+comp.capitalize()]();

			var container = this[comp].getElement('.'+comp+'-menu');

			if (!container) {
				container = new Element('div', {
					'class': comp+'-menu'
				}).inject(this[comp]);
			}

			//_log.debug('_init'+comp.capitalize());
			var menu = new Menu(opts);

			this.menu[opts.name] = menu;

			// _log.debug('setMenu', opts.name, menu);

			menu.addEvents({
				'toggle': function() {
					self.fireEvent('resize');
				},
				'change': function(value) {
					self.fireEvent('menuChange', value);
				}
			}).inject(container);

			this.addEvents({
				onMinimize: function() {
					menu.hide();
				},
				onNormalize: function() {
					menu.show();
				}
			});

			//  need to find an event driven solution
			this.element.setStyle('padding-top', this[comp].getSize().y+'px');

			return menu;
		},*/

		/**
		 * [_initFoot description]
		 * @param  {[type]} options [description]
		 * @return {[type]}         [description]
		 */
		_initFoot: function(options) {
			var self = this;

			this.foot = new Element('div', {
				'class': 'container-foot'
			}).inject(this.element, 'bottom');
		},

		/**
		 * [_initStatus description]
		 * @param  {[type]} component [description]
		 * @param  {[type]} context   [description]
		 * @return {[type]}           [description]
		 */
		_initStatus: function(component, context) {
			var self = this;

			component = component || 'foot';

			if (!this[component])
				this['_init'+component.capitalize()]();

			this.status = new Element('div', {
				'class': 'container-status'
			}).inject(this[component]);
		},

		/**
		 * create an overlay displayed when container is disabled (when moved or resized)
		 * @return {[type]} [description]
		 */
		_initOverlay: function() {
			var self = this;

			this.overlay = new Element('div', {
				'class': 'container-overlay'
			}).inject(this.element);

			this.addEvent('onLoadComplete', function() {
				this.overlay.hide();
			});

			this.overlay.hide();

			this.addEvents({
				onBlur: function() {
					//_log.debug('blur');
					self.overlay.show();
				},
				onDragComplete: function() {
					//_log.debug('darg com', ui.window.underlay);
					self.overlay.hide();
				},
				onDragStart: function(){
					//_log.debug('darg start', this);
					self.overlay.show();
				},
				onResizeComplete: function() {
					self.overlay.hide();
					this.coord = this.element.getCoordinates();
				},
				onResizeStart: function() {
					self.overlay.show();
				}
			});
		},

		/**
		 * [_initUnderlay description]
		 * @return {[type]} [description]
		 */
		_initUnderlay: function() {
			//_log.debug('_initUnderlay', this.device);
			var self = this;

			this.underlay = new Element('div', {
				'class': 'dialog-underlay',
				styles: {
					zIndex: 10,
					//display: 'none'
				}
			}).inject(this.element, 'before');

			this.underlay.addEvent('click', function() {
				_log.debug('click underlay');
				self.minimize();
			});

	 		this.addEvent('close', function(){
				self.underlay.destroy();
			});
	   	},

	   	/**
	   	 * [focus description]
	   	 * @return {[type]} [description]
	   	 */
		focus: function(){
			this.setState('focus');
		}
	});

	return exports;
});
<commit_msg>documentation<commit_after>/**
 * The UI.Container class defines objects manage the content of the container
 * that manage containers use by several object like windows, menus.
 * @class  UI.Container
 * @extends {UI.Component}
 * @author Jerome Vial
 */
define([
	'UI/Component/Component',
	'UI/Container/Display'
], function(
	Component,
	Display
) {

	var exports = new Class({

		Extends: Component,

		Implements: [Options, Events, Display],

		name: 'container',

		options: {
			name: 'container',

			node: null,

			tag: 'div',
			/*resizable: false,
			resizeBorders: ['top','right','bottom','left']*/
		},

		/**
		 * [initialize description]
		 * @param  {Object} options [description]
		 * @return {Object}         [description]
		 */
		initialize: function(options) {
			this.parent(options);

			if (this.options.comp) {
				this._initComp(this.options.comp);
			} else {
				this._initComponent();
			}

			return this;
		},

		/**
		 * Creates html structure and inject it to the dom.
		 * The container is _initElement with two elements: the wrapper and the content.
		 * If the option scroll is set to true, it will also add the scrollbar object
		 * @return {void}
		 */
		_initElement: function() {
			//_log.debug('_initElement', this);
			this.parent();

			var opts = this.options;
			this.menu = {};

			if (opts.head) {
				this._initHead(opts.head);
			}
			if (opts.menu) {
				this.setMenu(opts.menu);
			}
			if (this.name === 'window') {
				this._initBody();
			}
			if (opts.useOverlay) {
				this._initOverlay();
			}

			if (opts.foot) {
				this._initFoot(opts.foot);
			}

			var self = this;
			this.addEvent('injected', function() {
				var direction = self.container.getStyle('flex-direction');
				_log.debug('direction', direction, this.element);
			});

			if (this.options.useUnderlay) {
				this._initUnderlay();
			}
		},

		/**
		 * [_initComponent description]
		 * @return {void}
		 */
		_initComponent: function() {
			var opts = this.options;

			if (opts.node === null) {
				return;
			}

			//_log.debug('_initComponent', opts.node);

			this.node = [];

			if (typeOf(opts.node) === 'array') {
				for (var i = 0; i < opts.node.length; i++) {
					this.addComponent(opts.node[i]);
				}
			} else if (typeOf(opts.node) === 'object') {
				var node = opts.node;

				this.addComponent(node);
			}

		},

		/**
		 * Initialize internal container components
		 * @param  {Mixin} comp Compenent description
		 * @return {void}
		 */
		_initComp: function(comp) {
			//_log.debug('_initComp', comp);
			var self = this;

			if (typeOf(comp) === 'string') {
				this.addComp(comp);
			} else if (typeOf(comp) === 'object') {
				_log.debug('object');
			} else if (typeOf(comp) === 'array') {
				comp.each(function(name) {
					self.addComp(name);
				});
			}
		},

		/**
		 * [_initComp description]
		 * @param  {string} name
		 * @param  {string} position
		 * @param  {DOMElement} element
		 * @return {DOMElement|void}
		 */
		addComp: function(name, position, element) {
			//_log.debug('addComp', name, position, element);
			position = position || 'bottom';
			element = element || this.element;

			//_log.debug('_addComp', name);

			if (!element) {
				_log.warn('Container is ', element);
				return;
			}

			var comp = this[name] = new Element('div')
				.addClass('container-' + name)
				.inject(element, position);

			return comp;
			/*this.addEvents({
				resize: function() {
					//_log.debug('resize from head', this, this.head.getSize().y+'px');
					this.element.setStyle('padding-top', this.head.getSize().y+'px');
				}
			});*/
		},

		/**
		 * _initClass container related class
		 * @return {void}
		 */
		_initClass: function() {
			this.parent();

			this.element.addClass('ui-container');
		},

		/**
		 * create an overlay displayed when container is disabled (when moved or resized)
		 * @return {void}
		 */
		_initHead: function() {
			var self = this;

			this.head = new Element('div')
				.addClass('container-head')
				.inject(this.element, 'top')
				.addEvent('dblclick', function() {
					self.fireEvent('max');
				});
		},

		/**
		 * [setTitle description]
		 * @param {string} title
		 */
		setTitle: function(title) {
			if (this.title && this.head) {
				return this.title.set('text', title);
			}
		},

		/**
		 * [setTitle description]
		 * @return {string}
		 */
		getTitle: function() {
			//_log.debug('getTitle', this.title);
			if (this.title) {
				return this.title.get('html');
			}
		},

		/*setMenu: function(opts) {
			console.log('setMenu', opts);
			var self = this,
				comp = opts.comp || 'head';

			if (!this[comp])
				this['_init'+comp.capitalize()]();

			var container = this[comp].getElement('.'+comp+'-menu');

			if (!container) {
				container = new Element('div', {
					'class': comp+'-menu'
				}).inject(this[comp]);
			}

			//_log.debug('_init'+comp.capitalize());
			var menu = new Menu(opts);

			this.menu[opts.name] = menu;

			// _log.debug('setMenu', opts.name, menu);

			menu.addEvents({
				'toggle': function() {
					self.fireEvent('resize');
				},
				'change': function(value) {
					self.fireEvent('menuChange', value);
				}
			}).inject(container);

			this.addEvents({
				onMinimize: function() {
					menu.hide();
				},
				onNormalize: function() {
					menu.show();
				}
			});

			//  need to find an event driven solution
			this.element.setStyle('padding-top', this[comp].getSize().y+'px');

			return menu;
		},*/

		/**
		 * [_initFoot description]
		 * @param  {Object} options
		 * @return {void}
		 */
		_initFoot: function( /*options*/ ) {

			this.foot = new Element('div', {
				'class': 'container-foot'
			}).inject(this.element, 'bottom');
		},

		/**
		 * [_initStatus description]
		 * @param  {string} component
		 * @param  {string} context
		 * @return {void}
		 */
		_initStatus: function(component /*, context*/ ) {

			component = component || 'foot';

			if (!this[component]) {
				this['_init' + component.capitalize()]();
			}

			this.status = new Element('div', {
				'class': 'container-status'
			}).inject(this[component]);
		},

		/**
		 * create an overlay displayed when container is disabled (when moved or resized)
		 * @return {void} [description]
		 */
		_initOverlay: function() {
			var self = this;

			this.overlay = new Element('div', {
				'class': 'container-overlay'
			}).inject(this.element);

			this.addEvent('onLoadComplete', function() {
				this.overlay.hide();
			});

			this.overlay.hide();

			this.addEvents({
				onBlur: function() {
					//_log.debug('blur');
					self.overlay.show();
				},
				onDragComplete: function() {
					//_log.debug('darg com', ui.window.underlay);
					self.overlay.hide();
				},
				onDragStart: function() {
					//_log.debug('darg start', this);
					self.overlay.show();
				},
				onResizeComplete: function() {
					self.overlay.hide();
					this.coord = this.element.getCoordinates();
				},
				onResizeStart: function() {
					self.overlay.show();
				}
			});
		},

		/**
		 * [_initUnderlay description]
		 * @return {void}
		 */
		_initUnderlay: function() {
			//_log.debug('_initUnderlay', this.device);
			var self = this;

			this.underlay = new Element('div', {
				'class': 'dialog-underlay',
				styles: {
					zIndex: 10,
					//display: 'none'
				}
			}).inject(this.element, 'before');

			this.underlay.addEvent('click', function() {
				_log.debug('click underlay');
				self.minimize();
			});

			this.addEvent('close', function() {
				self.underlay.destroy();
			});
		},

		/**
		 * [focus description]
		 * @return {void}
		 */
		focus: function() {
			this.setState('focus');
		}
	});

	return exports;
});
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: Number.js                                                            \\
// Module: Core                                                               \\
// Requires: Core.js                                                          \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

Number.implement({
    /**
        Method: Number#limit

        Limits the number to be within the given range.

        Parameters:
            min - {Number} The minimum allowed value.
            max - {Number} The maximum allowed value.

        Returns:
            {Number} The nearest number to the current value within the allowed
            range.
    */
    limit: function ( min, max ) {
        return this < min ? min : this > max ? max : this;
    },

    /**
        Method: Number#mod

        Returns the number mod n.

        Parameters:
            n - {Number}

        Returns:
            {Number} The number mod n.
    */
    mod: function ( n ) {
        var m = this % n;
        return m < 0 ? m + n : m;
    }
});
<commit_msg>Ensure Number#limit returns a primitive number.<commit_after>// -------------------------------------------------------------------------- \\
// File: Number.js                                                            \\
// Module: Core                                                               \\
// Requires: Core.js                                                          \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

Number.implement({
    /**
        Method: Number#limit

        Limits the number to be within the given range.

        Parameters:
            min - {Number} The minimum allowed value.
            max - {Number} The maximum allowed value.

        Returns:
            {Number} The nearest number to the current value within the allowed
            range.
    */
    limit: function ( min, max ) {
        // +0 is required to unbox 'this' back into a primitive number in IE.
        // Otherwise you get a boxed value, which amongst other things makes 0 a
        // truthy value, leading to all sorts of interesting behaviour...
        return this < min ? min : this > max ? max : this + 0;
    },

    /**
        Method: Number#mod

        Returns the number mod n.

        Parameters:
            n - {Number}

        Returns:
            {Number} The number mod n.
    */
    mod: function ( n ) {
        var m = this % n;
        return m < 0 ? m + n : m;
    }
});
<|endoftext|>


<commit_before>
module.exports = function(gulp, config) {

	return function(done) {
		if(!config.templates) return done()
		var c = require('better-console')
		c.info('~ templates')

		var gulpFilter = require('gulp-filter')
		var gulpJade = require('gulp-jade')
		var jade = require('jade')
		var jadeInheritance = require('gulp-jade-inheritance')
		var jf = require('jsonfile')
		var path = require('path')
		var plumber = require('gulp-plumber')
		var gulpif = require('gulp-if')
		var cache = require('gulp-cached')

		var filterJade = gulpFilter('**/*.jade')
		var filterStatic = gulpFilter('**/*.{html,htm}')

		var templatesData = {}

		if(config.data) {
			for(key in config.data){
				var value = config.data[key]

				// Read data from external JSON files
				if(typeof value == 'string' && ~value.indexOf('.json')){
					value = jf.readFileSync(path.resolve(config.dir, value), { throws: false })
					if(value === null) {
						c.error('Error in JSON data parsing for file ' + config.data[key])
					}
				}

				templatesData[key] = value
			}
		}

		var task = gulp.src(config.templates)

		// Init plumber in devmode
		if(config.devmode){
			task = task.pipe(plumber({ errorHandler: require('../helpers/error_handler') }))
		}

		// Static part
		task = task.pipe(filterStatic)
			.pipe(filterStatic.restore())
		// Jade part
			.pipe(filterJade)
			.pipe(gulpif(config._lastChanged, jadeInheritance({ basedir: config.dir })))
			.pipe(gulpJade({
				jade: jade,
				locals: templatesData,
				pretty: true,
				cache: true
			}))
			.pipe(filterJade.restore())
			.pipe(cache('templates', { optimizeMemory: true }))

		return task.pipe(gulp.dest(config.dist_folder))
	}
}
<commit_msg>templates: passes doctype: html to Jade for correct attribute rendering<commit_after>
module.exports = function(gulp, config) {

	return function(done) {
		if(!config.templates) return done()
		var c = require('better-console')
		c.info('~ templates')

		var gulpFilter = require('gulp-filter')
		var gulpJade = require('gulp-jade')
		var jade = require('jade')
		var jadeInheritance = require('gulp-jade-inheritance')
		var jf = require('jsonfile')
		var path = require('path')
		var plumber = require('gulp-plumber')
		var gulpif = require('gulp-if')
		var cache = require('gulp-cached')

		var filterJade = gulpFilter('**/*.jade')
		var filterStatic = gulpFilter('**/*.{html,htm}')

		var templatesData = {}

		if(config.data) {
			for(key in config.data){
				var value = config.data[key]

				// Read data from external JSON files
				if(typeof value == 'string' && ~value.indexOf('.json')){
					value = jf.readFileSync(path.resolve(config.dir, value), { throws: false })
					if(value === null) {
						c.error('Error in JSON data parsing for file ' + config.data[key])
					}
				}

				templatesData[key] = value
			}
		}

		var task = gulp.src(config.templates)

		// Init plumber in devmode
		if(config.devmode){
			task = task.pipe(plumber({ errorHandler: require('../helpers/error_handler') }))
		}

		// Static part
		task = task.pipe(filterStatic)
			.pipe(filterStatic.restore())
		// Jade part
			.pipe(filterJade)
			.pipe(gulpif(config._lastChanged, jadeInheritance({ basedir: config.dir })))
			.pipe(gulpJade({
				jade: jade,
				locals: templatesData,
				pretty: true,
				cache: true,
				doctype: 'html'
			}))
			.pipe(filterJade.restore())
			.pipe(cache('templates', { optimizeMemory: true }))

		return task.pipe(gulp.dest(config.dist_folder))
	}
}
<|endoftext|>


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

var requestAnimationFrame = global.requestAnimationFrame
    || global.mozRequestAnimationFrame
    || global.webkitRequestAnimationFrame
    || global.msRequestAnimationFrame
    || function(callback) { return global.setTimeout(callback, 1000 / 60); };

var cancelAnimationFrame = global.cancelAnimationFrame
    || global.mozCancelAnimationFrame
    || global.webkitCancelAnimationFrame
    || global.msCancelAnimationFrame
    || function(id) { clearTimeout(id); };

  /**
   * options:
   *    animationDuration in seconds
   *    animationDelay in seconds
   */
  function Animator(callback, options) {
    if(!options.steps) {
      throw new Error("steps option missing")
    }
    this.options = options;
    this.running = false;
    this._tick = this._tick.bind(this);
    this._t0 = +new Date();
    this.callback = callback;
    this._time = 0.0;
    this.options = torque.extend({
        animationDelay: 0,
        maxDelta: 0.2,
        loop: true
    }, this.options);

    this.rescale();

  }

  Animator.prototype = {

    start: function() {
      this.running = true;
      requestAnimationFrame(this._tick);
      this.options.onStart && this.options.onStart();
    },

    isRunning: function() {
      return this.running;
    },

    stop: function() {
      this.pause();
      this.time(0);
      this.options.onStop && this.options.onStop();
    },

    // real animation time
    time: function(_) {
      if (!arguments.length) return this._time;
      this._time = _;
      var t = this.range(this.domain(this._time));
      this.callback(t);
    },

    toggle: function() {
      if (this.running) {
        this.pause()
      } else {
        this.start()
      }
    },

    rescale: function() {
      this.domainInv = torque.math.linear(this.options.animationDelay, this.options.animationDelay + this.options.animationDuration);
      this.domain = this.domainInv.invert();
      this.range = torque.math.linear(0, this.options.steps);
      this.rangeInv = this.range.invert();
      this.time(this._time);
      return this;
    },

    duration: function(_) {
      if (!arguments.length)  return this.options.animationDuration;
      this.options.animationDuration = _;
      if (this.time() > _) {
        this.time(0);
      }
      this.rescale();
      return this;
    },

    steps: function(_) {
      this.options.steps = _;
      return this.rescale();
    },

    step: function(s) {
      if(arguments.length === 0) return this.range(this.domain(this._time));
      this._time = this.domainInv(this.rangeInv(s));
    },

    pause: function() {
      this.running = false;
      cancelAnimationFrame(this._tick);
      this.options.onPause && this.options.onPause();
    },

    _tick: function() {
      var t1 = +new Date();
      var delta = (t1 - this._t0)*0.001;
      // if delta is really big means the tab lost the focus
      // at some point, so limit delta change
      delta = Math.min(this.options.maxDelta, delta);
      this._t0 = t1;
      this._time += delta;
      this.time(this._time);
      if(this.step() >= this.options.steps) {
        this._time = 0;
      }
      if(this.running) {
        requestAnimationFrame(this._tick);
      }
    }

  };

module.exports = Animator;
<commit_msg>pauses animation at end if loop is false<commit_after>var torque = require('./');

var requestAnimationFrame = global.requestAnimationFrame
    || global.mozRequestAnimationFrame
    || global.webkitRequestAnimationFrame
    || global.msRequestAnimationFrame
    || function(callback) { return global.setTimeout(callback, 1000 / 60); };

var cancelAnimationFrame = global.cancelAnimationFrame
    || global.mozCancelAnimationFrame
    || global.webkitCancelAnimationFrame
    || global.msCancelAnimationFrame
    || function(id) { clearTimeout(id); };

  /**
   * options:
   *    animationDuration in seconds
   *    animationDelay in seconds
   */
  function Animator(callback, options) {
    if(!options.steps) {
      throw new Error("steps option missing")
    }
    this.options = options;
    this.running = false;
    this._tick = this._tick.bind(this);
    this._t0 = +new Date();
    this.callback = callback;
    this._time = 0.0;
    this.options = torque.extend({
        animationDelay: 0,
        maxDelta: 0.2,
        loop: options.loop
    }, this.options);

    this.rescale();

  }

  Animator.prototype = {

    start: function() {
      this.running = true;
      requestAnimationFrame(this._tick);
      this.options.onStart && this.options.onStart();
    },

    isRunning: function() {
      return this.running;
    },

    stop: function() {
      this.pause();
      this.time(0);
      this.options.onStop && this.options.onStop();
    },

    // real animation time
    time: function(_) {
      if (!arguments.length) return this._time;
      this._time = _;
      var t = this.range(this.domain(this._time));
      this.callback(t);
    },

    toggle: function() {
      if (this.running) {
        this.pause()
      } else {
        this.start()
      }
    },

    rescale: function() {
      this.domainInv = torque.math.linear(this.options.animationDelay, this.options.animationDelay + this.options.animationDuration);
      this.domain = this.domainInv.invert();
      this.range = torque.math.linear(0, this.options.steps);
      this.rangeInv = this.range.invert();
      this.time(this._time);
      return this;
    },

    duration: function(_) {
      if (!arguments.length)  return this.options.animationDuration;
      this.options.animationDuration = _;
      if (this.time() > _) {
        this.time(0);
      }
      this.rescale();
      return this;
    },

    steps: function(_) {
      this.options.steps = _;
      return this.rescale();
    },

    step: function(s) {
      if(arguments.length === 0) return this.range(this.domain(this._time));
      this._time = this.domainInv(this.rangeInv(s));
    },

    pause: function() {
      this.running = false;
      cancelAnimationFrame(this._tick);
      this.options.onPause && this.options.onPause();
    },

    _tick: function() {
      var t1 = +new Date();
      var delta = (t1 - this._t0)*0.001;
      // if delta is really big means the tab lost the focus
      // at some point, so limit delta change
      delta = Math.min(this.options.maxDelta, delta);
      this._t0 = t1;
      this._time += delta;
      this.time(this._time);
      if(this.step() >= this.options.steps) {
        this._time = 0;
        if(!this.options.loop){
          this.pause();
        }
      }
      if(this.running) {
        requestAnimationFrame(this._tick);
      }
    }

  };

module.exports = Animator;
<|endoftext|>


<commit_before>const util = require('util')
const jsonParser = require('../jsonparser.js')

class base {
  constructor (parent, file, options) {
    this.options = options
    this.parent = parent
    this.file = file
    this.lineCounter = 0
    this.localLineCounter = 0
    this.stream = null
    this._throughStream = null
    this.metaStream = null
    this.elementsToSkip = 0

    // buffers data while it awaiting transport
    this.bufferedData = []

    // determine if splitter should be used
    this.shouldSplit = (!!parent.options.fileSize && parent.options.fileSize !== -1) ||
                       (!!parent.options.maxRows && parent.options.maxRows !== -1)
  }

  _resume () {
    [this.stream, this._throughStream, this.metaStream].forEach(stream => stream.resume())
  }

  _pause () {
    [this.metaStream, this._throughStream, this.stream].forEach(stream => stream.pause())
  }

  // accept callback
  // return (error, arr) where arr is an array of objects
  get (limit, offset, callback) {
    this.thisGetLimit = limit
    this.thisGetCallback = callback
    this.localLineCounter = 0

    if (this.lineCounter === 0) {
      this.setupGet(offset)
        .catch(e => {
          this.completeBatch(e, this.thisGetCallback)
        })
    } else {
      this._resume()
    }

    if (this.streamEnded) {
      this.completeBatch(null, this.thisGetCallback)
    }
  }

  async setupGet (offset) {
    throw new Error('Not Yet Implemented')
  }

  __setupStreamEvents () {
    this.stream.on('data', elem => {
      if (this.elementsToSkip > 0) {
        this.elementsToSkip--
      } else {
        this.bufferedData.push(elem)
      }

      this.localLineCounter++
      this.lineCounter++

      if (this.localLineCounter === this.thisGetLimit) {
        this.completeBatch(null, this.thisGetCallback)
      }
    })

    this.stream.on('error', e => {
      this.parent.emit('error', e)
    })

    this.stream.on('end', () => {
      this.streamEnded = true
      this.completeBatch(null, this.thisGetCallback, this.streamEnded)
    })
  }

  __handleData (data) {
    let lineCounter = 0
    data.forEach(elem => {
      let targetElem
      // Select _source if sourceOnly
      if (this.parent.options.sourceOnly === true) {
        targetElem = elem._source
      } else {
        targetElem = elem
      }

      if (this.parent.options.format && this.parent.options.format.toLowerCase() === 'human') {
        this.log(util.inspect(targetElem, false, 10, true))
      } else {
        this.log(jsonParser.stringify(targetElem, this.parent))
      }

      lineCounter++
    })
    return lineCounter
  }

  completeBatch (error, callback, streamEnded) {
    const data = []

    this._pause()

    if (error) { return callback(error) }

    // if we are skipping, have no data, and there is more to read we should continue on
    if (!streamEnded && this.elementsToSkip > 0 && this.bufferedData.length === 0) {
      return this._resume()
    }

    while (this.bufferedData.length > 0) {
      data.push(this.bufferedData.pop())
    }

    return callback(null, data)
  }

  set (data, limit, offset, callback) {
    throw new Error('Not Yet Implemented')
  }

  log (line) {
    throw new Error('Not Yet Implemented')
  }
}

module.exports = base
<commit_msg>fix --offset cause v8 oom<commit_after>const util = require('util')
const jsonParser = require('../jsonparser.js')

class base {
  constructor (parent, file, options) {
    this.options = options
    this.parent = parent
    this.file = file
    this.lineCounter = 0
    this.localLineCounter = 0
    this.stream = null
    this._throughStream = null
    this.metaStream = null
    this.elementsToSkip = 0

    // buffers data while it awaiting transport
    this.bufferedData = []

    // determine if splitter should be used
    this.shouldSplit = (!!parent.options.fileSize && parent.options.fileSize !== -1) ||
                       (!!parent.options.maxRows && parent.options.maxRows !== -1)
  }

  _resume () {
    [this.stream, this._throughStream, this.metaStream].forEach(stream => stream.resume())
  }

  _pause () {
    [this.metaStream, this._throughStream, this.stream].forEach(stream => stream.pause())
  }

  // accept callback
  // return (error, arr) where arr is an array of objects
  get (limit, offset, callback) {
    this.thisGetLimit = limit
    this.thisGetCallback = callback
    this.localLineCounter = 0

    if (this.lineCounter === 0) {
      this.setupGet(offset)
        .catch(e => {
          this.completeBatch(e, this.thisGetCallback)
        })
    } else {
      this._resume()
    }

    if (this.streamEnded) {
      this.completeBatch(null, this.thisGetCallback)
    }
  }

  async setupGet (offset) {
    throw new Error('Not Yet Implemented')
  }

  __setupStreamEvents () {
    this.stream.on('data', elem => {
      if (this.elementsToSkip > 0) {
        this.elementsToSkip--
      } else {
        this.bufferedData.push(elem)
        this.localLineCounter++
      }

      this.lineCounter++

      if (this.localLineCounter === this.thisGetLimit) {
        this.completeBatch(null, this.thisGetCallback)
      }
    })

    this.stream.on('error', e => {
      this.parent.emit('error', e)
    })

    this.stream.on('end', () => {
      this.streamEnded = true
      this.completeBatch(null, this.thisGetCallback, this.streamEnded)
    })
  }

  __handleData (data) {
    let lineCounter = 0
    data.forEach(elem => {
      let targetElem
      // Select _source if sourceOnly
      if (this.parent.options.sourceOnly === true) {
        targetElem = elem._source
      } else {
        targetElem = elem
      }

      if (this.parent.options.format && this.parent.options.format.toLowerCase() === 'human') {
        this.log(util.inspect(targetElem, false, 10, true))
      } else {
        this.log(jsonParser.stringify(targetElem, this.parent))
      }

      lineCounter++
    })
    return lineCounter
  }

  completeBatch (error, callback, streamEnded) {
    const data = []

    this._pause()

    if (error) { return callback(error) }

    // if we are skipping, have no data, and there is more to read we should continue on
    if (!streamEnded && this.elementsToSkip > 0 && this.bufferedData.length === 0) {
      return this._resume()
    }

    while (this.bufferedData.length > 0) {
      data.push(this.bufferedData.pop())
    }

    return callback(null, data)
  }

  set (data, limit, offset, callback) {
    throw new Error('Not Yet Implemented')
  }

  log (line) {
    throw new Error('Not Yet Implemented')
  }
}

module.exports = base
<|endoftext|>


<commit_before>// TODO:
//  * support 1 nested multipart level
//    (see second multipart example here:
//     http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
//  * support limits.fieldNameSize
//     -- this will require modifications to utils.parseParams

var ReadableStream = require('readable-stream'),
    Dicer = require('dicer'),
    inherits = require('util').inherits,
    jsencoding = require('../../deps/encoding/encoding');

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

var RE_BOUNDARY = /^boundary$/i,
    RE_FIELD = /^form-data$/i,
    RE_CHARSET = /^charset$/i,
    RE_FILENAME = /^filename$/i,
    RE_NAME = /^name$/i;

Multipart.detect = /^multipart\//i;
function Multipart(boy, limits, headers, parsedConType) {
  var boundary, i, len;
  for (i = 0, len = parsedConType.length; i < len; ++i) {
    if (RE_BOUNDARY.test(parsedConType[i][0])) {
      boundary = parsedConType[i][1];
      break;
    }
  }

  if (!boundary)
    throw new Error('Multipart: Boundary not found');

  var fieldSizeLimit = (limits && limits.fieldSize) || (1 * 1024 * 1024),
      fileSizeLimit = (limits && limits.fileSize) || Infinity,
      filesLimit = (limits && limits.files) || Infinity,
      fieldsLimit = (limits && limits.fields) || Infinity,
      partsLimit = (limits && limits.parts) || Infinity;

  var nfiles = 0, nfields = 0, nparts = 0, self = this;

  this._finished = false;
  this._boy = boy;

  this.parser = new Dicer({
    boundary: boundary,
    maxHeaderPairs: (limits && limits.headerPairs)
  });
  this.parser.on('part', function(part) {
    if (++nparts > partsLimit) {
      this.parser.removeAllListeners('part');
      return;
    }
    part.once('header', function(header) {
      var contype, fieldname, parsed, charset, encoding, filename, nsize = 0;

      if (header['content-type']) {
        parsed = utils.parseParams(header['content-type'][0]);
        contype = parsed[0].toLowerCase();
        for (i = 0, len = parsed.length; i < len; ++i) {
          if (RE_CHARSET.test(parsed[i][0])) {
            charset = parsed[i][1].toLowerCase();
            break;
          }
        }
      }
      if (charset === undefined)
        charset = 'iso-8859-1';

      if (header['content-disposition']) {
        parsed = utils.parseParams(header['content-disposition'][0]);
        if (!RE_FIELD.test(parsed[0]))
          return;
        for (i = 0, len = parsed.length; i < len; ++i) {
          if (RE_NAME.test(parsed[i][0]))
            fieldname = parsed[i][1];
          else if (RE_FILENAME.test(parsed[i][0]))
            filename = parsed[i][1];
        }
      } else
        return;

      if (header['content-transfer-encoding'])
        encoding = header['content-transfer-encoding'].toLowerCase();
      else
        encoding = '7bit';

      var onData, onEnd;
      if (contype === 'application/octet-stream' || filename !== undefined) {
        // file field
        if (nfiles === filesLimit)
          return;

        ++nfiles;
        var file = new FileStream();
        boy.emit('file', fieldname, file, filename);

        onData = function(data) {
          if ((nsize += data.length) > fileSizeLimit) {
            file.emit('data', data.slice(0, (fileSizeLimit - nsize)));
            file.emit('limit');
            part.removeAllListeners('data');
          } else
            file.emit('data', data);
        };

        onEnd = function() {
          file.emit('end');
        };
      } else {
        // non-file field
        if (nfields === fieldsLimit)
          return;

        ++nfields;
        var buffer = '', truncated = false;

        onData = function(data) {
          if ((nsize += data.length) > fieldSizeLimit) {
            buffer += data.toString('binary', 0, (fieldSizeLimit - nsize));
            truncated = true;
            part.removeAllListeners('data');
          } else
            buffer += data.toString('binary');
        };

        onEnd = function() {
          if (charset !== 'ascii' && buffer.length) {
            if (jsencoding.encodingExists(charset)) {
              try {
                buffer = jsencoding.TextDecoder(charset)
                                   .decode(new Buffer(buffer, 'binary'));
              } catch(e) {}
            }
          }
          boy.emit('field', fieldname, buffer, truncated);
        };
      }
      part.on('data', onData);
      part.once('end', onEnd);
    });
  });
  this.parser.once('end', function() {
    self._finished = true;
    boy.emit('end');
  });
}

Multipart.prototype.write = function(data) {
  this.parser.write(data);
};

Multipart.prototype.end = function() {
  this.parser.reset();
  if (!this._finished) {
    this._finished = true;
    this._boy.emit('end');
  }
};

function FileStream() {
  if (!(this instanceof FileStream))
    return new FileStream();
  ReadableStream.call(this);
}
inherits(FileStream, ReadableStream);

FileStream.prototype._read = function(n) {};

module.exports = Multipart;
<commit_msg>multipart: reduce code<commit_after>// TODO:
//  * support 1 nested multipart level
//    (see second multipart example here:
//     http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
//  * support limits.fieldNameSize
//     -- this will require modifications to utils.parseParams

var ReadableStream = require('readable-stream'),
    Dicer = require('dicer'),
    inherits = require('util').inherits,
    jsencoding = require('../../deps/encoding/encoding');

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

var RE_BOUNDARY = /^boundary$/i,
    RE_FIELD = /^form-data$/i,
    RE_CHARSET = /^charset$/i,
    RE_FILENAME = /^filename$/i,
    RE_NAME = /^name$/i;

Multipart.detect = /^multipart\//i;
function Multipart(boy, limits, headers, parsedConType) {
  var boundary, i, len;
  for (i = 0, len = parsedConType.length; i < len; ++i) {
    if (RE_BOUNDARY.test(parsedConType[i][0])) {
      boundary = parsedConType[i][1];
      break;
    }
  }

  if (!boundary)
    throw new Error('Multipart: Boundary not found');

  var fieldSizeLimit = (limits && limits.fieldSize) || (1 * 1024 * 1024),
      fileSizeLimit = (limits && limits.fileSize) || Infinity,
      filesLimit = (limits && limits.files) || Infinity,
      fieldsLimit = (limits && limits.fields) || Infinity,
      partsLimit = (limits && limits.parts) || Infinity;

  var nfiles = 0, nfields = 0, nparts = 0, self = this;

  this._finished = false;
  this._boy = boy;

  this.parser = new Dicer({
    boundary: boundary,
    maxHeaderPairs: (limits && limits.headerPairs)
  });
  this.parser.on('part', function(part) {
    if (++nparts > partsLimit) {
      this.parser.removeAllListeners('part');
      return;
    }
    part.once('header', function(header) {
      var contype, fieldname, parsed, charset, encoding, filename, nsize = 0;

      if (header['content-type']) {
        parsed = utils.parseParams(header['content-type'][0]);
        contype = parsed[0].toLowerCase();
        for (i = 0, len = parsed.length; i < len; ++i) {
          if (RE_CHARSET.test(parsed[i][0])) {
            charset = parsed[i][1].toLowerCase();
            break;
          }
        }
      }
      if (charset === undefined)
        charset = 'iso-8859-1';

      if (header['content-disposition']) {
        parsed = utils.parseParams(header['content-disposition'][0]);
        if (!RE_FIELD.test(parsed[0]))
          return;
        for (i = 0, len = parsed.length; i < len; ++i) {
          if (RE_NAME.test(parsed[i][0]))
            fieldname = parsed[i][1];
          else if (RE_FILENAME.test(parsed[i][0]))
            filename = parsed[i][1];
        }
      } else
        return;

      if (header['content-transfer-encoding'])
        encoding = header['content-transfer-encoding'].toLowerCase();
      else
        encoding = '7bit';

      var onData, onEnd;
      if (contype === 'application/octet-stream' || filename !== undefined) {
        // file field
        if (nfiles === filesLimit)
          return;

        ++nfiles;
        var file = new FileStream();
        boy.emit('file', fieldname, file, filename);

        onData = function(data) {
          if ((nsize += data.length) > fileSizeLimit) {
            file.emit('data', data.slice(0, (fileSizeLimit - nsize)));
            file.emit('limit');
            part.removeAllListeners('data');
          } else
            file.emit('data', data);
        };

        onEnd = function() {
          file.emit('end');
        };
      } else {
        // non-file field
        if (nfields === fieldsLimit)
          return;

        ++nfields;
        var buffer = '', truncated = false;

        onData = function(data) {
          if ((nsize += data.length) > fieldSizeLimit) {
            buffer += data.toString('binary', 0, (fieldSizeLimit - nsize));
            truncated = true;
            part.removeAllListeners('data');
          } else
            buffer += data.toString('binary');
        };

        onEnd = function() {
          if (buffer.length && jsencoding.encodingExists(charset)) {
            try {
              buffer = jsencoding.TextDecoder(charset)
                                 .decode(new Buffer(buffer, 'binary'));
            } catch(e) {}
          }
          boy.emit('field', fieldname, buffer, truncated);
        };
      }
      part.on('data', onData);
      part.once('end', onEnd);
    });
  });
  this.parser.once('end', function() {
    self._finished = true;
    boy.emit('end');
  });
}

Multipart.prototype.write = function(data) {
  this.parser.write(data);
};

Multipart.prototype.end = function() {
  this.parser.reset();
  if (!this._finished) {
    this._finished = true;
    this._boy.emit('end');
  }
};

function FileStream() {
  if (!(this instanceof FileStream))
    return new FileStream();
  ReadableStream.call(this);
}
inherits(FileStream, ReadableStream);

FileStream.prototype._read = function(n) {};

module.exports = Multipart;
<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const path = require('path');
const jsdiff = require('diff');
const {SError} = require('error');
const GroupedQueue = require('grouped-queue');

const binaryDiff = require('./binary-diff');

class AbortedError extends SError {}

class ConflicterConflictError extends SError {}

/**
 * The Conflicter is a module that can be used to detect conflict between files. Each
 * Generator file system helpers pass files through this module to make sure they don't
 * break a user file.
 *
 * When a potential conflict is detected, we prompt the user and ask them for
 * confirmation before proceeding with the actual write.
 *
 * @constructor
 * @property {Boolean} force - same as the constructor argument
 *
 * @param  {TerminalAdapter} adapter - The generator adapter
 * @param  {Boolean} force - When set to true, we won't check for conflict. (the
 *                           conflicter become a passthrough)
 * @param  {Boolean} bail - When set to true, we will abort on first conflict. (used for
 *                           testing reproducibility)
 */
class Conflicter {
  constructor(adapter, force, options = {}) {
    if (typeof options === 'boolean') {
      this.bail = options;
    } else {
      this.bail = options.bail;
      this.ignoreWhitespace = options.ignoreWhitespace;
      this.regenerate = options.regenerate;
      this.dryRun = options.dryRun;
    }

    this.force = force === true;
    this.adapter = adapter;
    this.conflicts = [];

    this.diffOptions = options.diffOptions;

    if (this.bail) {
      // Set ignoreWhitespace as true by default for bail.
      // Probably just testing, so don't override.
      this.ignoreWhitespace = true;
    }

    this.queue = new GroupedQueue(['log', 'conflicts'], false);
  }

  log(file) {
    const logStatus = file.conflicterLog || file.conflicter;
    this._log(logStatus, path.relative(process.cwd(), file.path));
  }

  _log(logStatus, ...args) {
    let log;
    if (typeof logStatus === 'function') {
      log = logStatus;
    } else {
      log = this.adapter.log[logStatus];
      if (log) {
        log = log.bind(this.adapter.log);
      }
    }
    if (log) {
      this.queue.add('log', done => {
        log(...args);
        done();
      });
      this.queue.start();
    }
  }

  /**
   * Print the file differences to console
   *
   * @param  {Object}   file File object respecting this interface: { path, contents }
   */
  _printDiff(file, queue = false) {
    if (file.binary === undefined) {
      file.binary = binaryDiff.isBinary(file.path, file.contents);
    }

    let args;
    let logFunction;
    if (file.binary) {
      logFunction = this.adapter.log.writeln.bind(this.adapter.log);
      args = [binaryDiff.diff(file.path, file.contents)];
    } else {
      const existing = fs.readFileSync(file.path);
      logFunction = this.adapter.diff.bind(this.adapter);
      args = [
        existing.toString(),
        (file.contents || '').toString(),
        file.conflicterChanges
      ];
    }
    if (queue) {
      this._log(logFunction, ...args);
    } else {
      logFunction(...args);
    }
  }

  /**
   * Detect conflicts between file contents at `filepath` with the `contents` passed to the
   * function
   *
   * If `filepath` points to a folder, we'll always return true.
   *
   * Based on detect-conflict module
   *
   * @param  {Object}   file File object respecting this interface: { path, contents }
   * @return {Boolean} `true` if there's a conflict, `false` otherwise.
   */
  _detectConflict(file) {
    let {contents} = file;
    const filepath = path.resolve(file.path);

    // If file path point to a directory, then it's not safe to write
    if (fs.statSync(filepath).isDirectory()) {
      return true;
    }

    if (file.binary === undefined) {
      file.binary = binaryDiff.isBinary(file.path, file.contents);
    }

    const actual = fs.readFileSync(path.resolve(filepath));

    if (!(contents instanceof Buffer)) {
      contents = Buffer.from(contents || '', 'utf8');
    }

    if (file.binary) {
      return actual.toString('hex') !== contents.toString('hex');
    }

    let modified;
    let changes;
    if (this.ignoreWhitespace) {
      changes = jsdiff.diffWords(
        actual.toString(),
        contents.toString(),
        this.diffOptions
      );
      modified = changes.some(change => change.value && change.value.trim() && (change.added || change.removed));
    } else {
      changes = jsdiff.diffLines(
        actual.toString(),
        contents.toString(),
        this.diffOptions
      );
      modified = changes.length > 1 || changes[0].added || changes[0].removed;
    }
    file.conflicterChanges = changes;
    return modified;
  }

  /**
   * Check if a file conflict with the current version on the user disk
   *
   * A basic check is done to see if the file exists, if it does:
   *
   *   1. Read its content from  `fs`
   *   2. Compare it with the provided content
   *   3. If identical, mark it as is and skip the check
   *   4. If diverged, prepare and show up the file collision menu
   *
   * @param {Object} file - Vinyl file
   * @return  {Promise} Promise a status string ('identical', 'create',
   *                       'skip', 'force')
   */
  checkForCollision(file) {
    const rfilepath = path.relative(process.cwd(), file.path);
    if (file.conflicter) {
      this._log(file.conflicter, rfilepath);
      return Promise.resolve(file);
    }

    if (!fs.existsSync(file.path)) {
      if (this.bail) {
        this._log('writeln', 'Aborting ...');
        return Promise.reject(ConflicterConflictError.create('Process aborted by conflict'));
      }

      this._log('create', rfilepath);
      file.conflicter = this.dryRun ? 'skip' : 'create';
      file.conflicterLog = 'create';
      return Promise.resolve(file);
    }

    if (this.force) {
      this._log('force', rfilepath);
      file.conflicter = 'force';
      return Promise.resolve(file);
    }

    if (this._detectConflict(file)) {
      if (this.bail) {
        this.adapter.log.conflict(rfilepath);
        this._printDiff(file);
        this.adapter.log.writeln('Aborting ...');
        return Promise.reject(ConflicterConflictError.create('Process aborted by conflict'));
      }

      if (this.dryRun) {
        this._log('conflict', rfilepath);
        this._printDiff(file, true);
        file.conflicter = 'skip';
        file.conflicterLog = 'conflict';
        return Promise.resolve(file);
      }

      return new Promise((resolve, reject) => {
        this.queue.add('conflicts', next => {
          this.adapter.log.conflict(rfilepath);
          return this._ask(file, 1).then(action => {
            this.adapter.log[action || 'force'](rfilepath);
            file.conflicter = action;
            next();
            resolve(file);
          }).catch(reject);
        });
        this.queue.start();
      });
    }
    this._log('identical', rfilepath);
    if (!this.regenerate) {
      file.conflicter = 'skip';
      file.conflicterLog = 'identical';
      return Promise.resolve(file);
    }

    file.conflicter = 'identical';
    return Promise.resolve(file);
  }

  /**
   * Actual prompting logic
   * @private
   * @param {Object} file vinyl file object
   * @param {Number} counter prompts
   */
  _ask(file, counter) {
    if (file.conflicter) {
      return Promise.resolve(file.conflicter);
    }
    const rfilepath = path.relative(process.cwd(), file.path);
    const prompt = {
      name: 'action',
      type: 'expand',
      message: `Overwrite ${rfilepath}?`,
      choices: [
        {
          key: 'y',
          name: 'overwrite',
          value: 'write'
        },
        {
          key: 'n',
          name: 'do not overwrite',
          value: 'skip'
        },
        {
          key: 'a',
          name: 'overwrite this and all others',
          value: 'force'
        },
        {
          key: 'x',
          name: 'abort',
          value: 'abort'
        }
      ]
    };

    // Only offer diff option for files
    if (fs.statSync(file.path).isFile()) {
      prompt.choices.push({
        key: 'd',
        name: 'show the differences between the old and the new',
        value: 'diff'
      });
    }

    return this.adapter.prompt([prompt]).then(result => {
      if (result.action === 'abort') {
        this.adapter.log.writeln('Aborting ...');
        throw AbortedError.create('Process aborted by user');
      }

      if (result.action === 'diff') {
        this._printDiff(file);

        counter++;
        if (counter === 5) {
          throw new Error(`Recursive error ${prompt.message}`);
        }

        return this._ask(file, counter);
      }

      if (result.action === 'force') {
        this.force = true;
      }

      if (result.action === 'write') {
        return 'force';
      }

      return result.action;
    });
  }
}

module.exports = Conflicter;
<commit_msg>Run the conflicter queue instead of scheduling it.<commit_after>'use strict';
const fs = require('fs');
const path = require('path');
const jsdiff = require('diff');
const {SError} = require('error');
const GroupedQueue = require('grouped-queue');

const binaryDiff = require('./binary-diff');

class AbortedError extends SError {}

class ConflicterConflictError extends SError {}

/**
 * The Conflicter is a module that can be used to detect conflict between files. Each
 * Generator file system helpers pass files through this module to make sure they don't
 * break a user file.
 *
 * When a potential conflict is detected, we prompt the user and ask them for
 * confirmation before proceeding with the actual write.
 *
 * @constructor
 * @property {Boolean} force - same as the constructor argument
 *
 * @param  {TerminalAdapter} adapter - The generator adapter
 * @param  {Boolean} force - When set to true, we won't check for conflict. (the
 *                           conflicter become a passthrough)
 * @param  {Boolean} bail - When set to true, we will abort on first conflict. (used for
 *                           testing reproducibility)
 */
class Conflicter {
  constructor(adapter, force, options = {}) {
    if (typeof options === 'boolean') {
      this.bail = options;
    } else {
      this.bail = options.bail;
      this.ignoreWhitespace = options.ignoreWhitespace;
      this.regenerate = options.regenerate;
      this.dryRun = options.dryRun;
    }

    this.force = force === true;
    this.adapter = adapter;
    this.conflicts = [];

    this.diffOptions = options.diffOptions;

    if (this.bail) {
      // Set ignoreWhitespace as true by default for bail.
      // Probably just testing, so don't override.
      this.ignoreWhitespace = true;
    }

    this.queue = new GroupedQueue(['log', 'conflicts'], false);
  }

  log(file) {
    const logStatus = file.conflicterLog || file.conflicter;
    this._log(logStatus, path.relative(process.cwd(), file.path));
  }

  _log(logStatus, ...args) {
    let log;
    if (typeof logStatus === 'function') {
      log = logStatus;
    } else {
      log = this.adapter.log[logStatus];
      if (log) {
        log = log.bind(this.adapter.log);
      }
    }
    if (log) {
      this.queue.add('log', done => {
        log(...args);
        done();
      });
      this.queue.start();
    }
  }

  /**
   * Print the file differences to console
   *
   * @param  {Object}   file File object respecting this interface: { path, contents }
   */
  _printDiff(file, queue = false) {
    if (file.binary === undefined) {
      file.binary = binaryDiff.isBinary(file.path, file.contents);
    }

    let args;
    let logFunction;
    if (file.binary) {
      logFunction = this.adapter.log.writeln.bind(this.adapter.log);
      args = [binaryDiff.diff(file.path, file.contents)];
    } else {
      const existing = fs.readFileSync(file.path);
      logFunction = this.adapter.diff.bind(this.adapter);
      args = [
        existing.toString(),
        (file.contents || '').toString(),
        file.conflicterChanges
      ];
    }
    if (queue) {
      this._log(logFunction, ...args);
    } else {
      logFunction(...args);
    }
  }

  /**
   * Detect conflicts between file contents at `filepath` with the `contents` passed to the
   * function
   *
   * If `filepath` points to a folder, we'll always return true.
   *
   * Based on detect-conflict module
   *
   * @param  {Object}   file File object respecting this interface: { path, contents }
   * @return {Boolean} `true` if there's a conflict, `false` otherwise.
   */
  _detectConflict(file) {
    let {contents} = file;
    const filepath = path.resolve(file.path);

    // If file path point to a directory, then it's not safe to write
    if (fs.statSync(filepath).isDirectory()) {
      return true;
    }

    if (file.binary === undefined) {
      file.binary = binaryDiff.isBinary(file.path, file.contents);
    }

    const actual = fs.readFileSync(path.resolve(filepath));

    if (!(contents instanceof Buffer)) {
      contents = Buffer.from(contents || '', 'utf8');
    }

    if (file.binary) {
      return actual.toString('hex') !== contents.toString('hex');
    }

    let modified;
    let changes;
    if (this.ignoreWhitespace) {
      changes = jsdiff.diffWords(
        actual.toString(),
        contents.toString(),
        this.diffOptions
      );
      modified = changes.some(change => change.value && change.value.trim() && (change.added || change.removed));
    } else {
      changes = jsdiff.diffLines(
        actual.toString(),
        contents.toString(),
        this.diffOptions
      );
      modified = changes.length > 1 || changes[0].added || changes[0].removed;
    }
    file.conflicterChanges = changes;
    return modified;
  }

  /**
   * Check if a file conflict with the current version on the user disk
   *
   * A basic check is done to see if the file exists, if it does:
   *
   *   1. Read its content from  `fs`
   *   2. Compare it with the provided content
   *   3. If identical, mark it as is and skip the check
   *   4. If diverged, prepare and show up the file collision menu
   *
   * @param {Object} file - Vinyl file
   * @return  {Promise} Promise a status string ('identical', 'create',
   *                       'skip', 'force')
   */
  checkForCollision(file) {
    const rfilepath = path.relative(process.cwd(), file.path);
    if (file.conflicter) {
      this._log(file.conflicter, rfilepath);
      return Promise.resolve(file);
    }

    if (!fs.existsSync(file.path)) {
      if (this.bail) {
        this._log('writeln', 'Aborting ...');
        return Promise.reject(ConflicterConflictError.create('Process aborted by conflict'));
      }

      this._log('create', rfilepath);
      file.conflicter = this.dryRun ? 'skip' : 'create';
      file.conflicterLog = 'create';
      return Promise.resolve(file);
    }

    if (this.force) {
      this._log('force', rfilepath);
      file.conflicter = 'force';
      return Promise.resolve(file);
    }

    if (this._detectConflict(file)) {
      if (this.bail) {
        this.adapter.log.conflict(rfilepath);
        this._printDiff(file);
        this.adapter.log.writeln('Aborting ...');
        return Promise.reject(ConflicterConflictError.create('Process aborted by conflict'));
      }

      if (this.dryRun) {
        this._log('conflict', rfilepath);
        this._printDiff(file, true);
        file.conflicter = 'skip';
        file.conflicterLog = 'conflict';
        return Promise.resolve(file);
      }

      return new Promise((resolve, reject) => {
        this.queue.add('conflicts', next => {
          this.adapter.log.conflict(rfilepath);
          return this._ask(file, 1).then(action => {
            this.adapter.log[action || 'force'](rfilepath);
            file.conflicter = action;
            next();
            resolve(file);
          }).catch(reject);
        });
        this.queue.run();
      });
    }
    this._log('identical', rfilepath);
    if (!this.regenerate) {
      file.conflicter = 'skip';
      file.conflicterLog = 'identical';
      return Promise.resolve(file);
    }

    file.conflicter = 'identical';
    return Promise.resolve(file);
  }

  /**
   * Actual prompting logic
   * @private
   * @param {Object} file vinyl file object
   * @param {Number} counter prompts
   */
  _ask(file, counter) {
    if (file.conflicter) {
      return Promise.resolve(file.conflicter);
    }
    const rfilepath = path.relative(process.cwd(), file.path);
    const prompt = {
      name: 'action',
      type: 'expand',
      message: `Overwrite ${rfilepath}?`,
      choices: [
        {
          key: 'y',
          name: 'overwrite',
          value: 'write'
        },
        {
          key: 'n',
          name: 'do not overwrite',
          value: 'skip'
        },
        {
          key: 'a',
          name: 'overwrite this and all others',
          value: 'force'
        },
        {
          key: 'x',
          name: 'abort',
          value: 'abort'
        }
      ]
    };

    // Only offer diff option for files
    if (fs.statSync(file.path).isFile()) {
      prompt.choices.push({
        key: 'd',
        name: 'show the differences between the old and the new',
        value: 'diff'
      });
    }

    return this.adapter.prompt([prompt]).then(result => {
      if (result.action === 'abort') {
        this.adapter.log.writeln('Aborting ...');
        throw AbortedError.create('Process aborted by user');
      }

      if (result.action === 'diff') {
        this._printDiff(file);

        counter++;
        if (counter === 5) {
          throw new Error(`Recursive error ${prompt.message}`);
        }

        return this._ask(file, counter);
      }

      if (result.action === 'force') {
        this.force = true;
      }

      if (result.action === 'write') {
        return 'force';
      }

      return result.action;
    });
  }
}

module.exports = Conflicter;
<|endoftext|>


<commit_before>var fs = require('graceful-fs');
var path = require('path');
var Q = require('q');
var mkdirp = require('mkdirp');
var createError = require('./createError');

var isWin = process.platform === 'win32';

function createLink(src, dst, type) {
    var dstDir = path.dirname(dst);

    // Create directory
    return Q.nfcall(mkdirp, dstDir)
    // Check if source exists
    .then(function () {
        return Q.nfcall(fs.stat, src)
        .fail(function (error) {
            if (error.code === 'ENOENT') {
                throw createError('Failed to create link to ' + path.basename(src), 'ENOENT', {
                    details: src + ' doest not exists or points to a non-existent file'
                });
            }

            throw error;
        });
    })
    // Create symlink
    .then(function (stat) {
        type = type || (stat.isDirectory() ? 'dir' : 'file');

        return Q.nfcall(fs.symlink, src, dst, type)
        .fail(function (err) {
            if (!isWin || err.code !== 'EPERM') {
                throw err;
            }

            // Try with type "junction" on Windows
            // Junctions behave equally to true symlinks and can be created in
            // non elevated terminal (well, not always..)
            return Q.nfcall(fs.symlink, src, dst, 'junction')
            .fail(function (err) {
                throw createError('Unable to create link to ' + path.basename(src), err.code, {
                    details: err.message.trim() + '\n\nTry running this command in an elevated terminal (run as root/administrator).'
                });
            });
        });
    });
}

module.exports = createLink;
<commit_msg>fix error message<commit_after>var fs = require('graceful-fs');
var path = require('path');
var Q = require('q');
var mkdirp = require('mkdirp');
var createError = require('./createError');

var isWin = process.platform === 'win32';

function createLink(src, dst, type) {
    var dstDir = path.dirname(dst);

    // Create directory
    return Q.nfcall(mkdirp, dstDir)
    // Check if source exists
    .then(function () {
        return Q.nfcall(fs.stat, src)
        .fail(function (error) {
            if (error.code === 'ENOENT') {
                throw createError('Failed to create link to ' + path.basename(src), 'ENOENT', {
                    details: src + ' does not exist or points to a non-existent file'
                });
            }

            throw error;
        });
    })
    // Create symlink
    .then(function (stat) {
        type = type || (stat.isDirectory() ? 'dir' : 'file');

        return Q.nfcall(fs.symlink, src, dst, type)
        .fail(function (err) {
            if (!isWin || err.code !== 'EPERM') {
                throw err;
            }

            // Try with type "junction" on Windows
            // Junctions behave equally to true symlinks and can be created in
            // non elevated terminal (well, not always..)
            return Q.nfcall(fs.symlink, src, dst, 'junction')
            .fail(function (err) {
                throw createError('Unable to create link to ' + path.basename(src), err.code, {
                    details: err.message.trim() + '\n\nTry running this command in an elevated terminal (run as root/administrator).'
                });
            });
        });
    });
}

module.exports = createLink;
<|endoftext|>


<commit_before>/*! @license
 * Shaka Player
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

goog.provide('shaka.util.FakeEvent');

/**
 * @summary Create an Event work-alike object based on the provided dictionary.
 * The event should contain all of the same properties from the dict.
 *
 * @extends {Event}
 */
shaka.util.FakeEvent = class {
  /**
   * @param {string} type
   * @param {Object=} dict
   */
  constructor(type, dict = {}) {
    // Take properties from dict if present.
    for (const key in dict) {
      Object.defineProperty(this, key, {
        value: dict[key],
        writable: true,
        enumerable: true,
      });
    }

    // The properties below cannot be set by the dict.  They are all provided
    // for compatibility with native events.

    /** @const {boolean} */
    this.bubbles = false;

    /** @type {boolean} */
    this.cancelable = false;

    /** @type {boolean} */
    this.defaultPrevented = false;

    /**
     * According to MDN, Chrome uses high-res timers instead of epoch time.
     * Follow suit so that timeStamps on FakeEvents use the same base as
     * on native Events.
     * @const {number}
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp
     */
    this.timeStamp = window.performance && window.performance.now ?
        window.performance.now() : Date.now();

    /** @const {string} */
    this.type = type;

    /** @const {boolean} */
    this.isTrusted = false;

    /** @type {EventTarget} */
    this.currentTarget = null;

    /** @type {EventTarget} */
    this.target = null;

    /**
     * Non-standard property read by FakeEventTarget to stop processing
     * listeners.
     * @type {boolean}
     */
    this.stopped = false;
  }

  /**
   * Prevents the default action of the event.  Has no effect if the event isn't
   * cancellable.
   * @override
   */
  preventDefault() {
    if (this.cancelable) {
      this.defaultPrevented = true;
    }
  }

  /**
   * Stops processing event listeners for this event.  Provided for
   * compatibility with native Events.
   * @override
   */
  stopImmediatePropagation() {
    this.stopped = true;
  }

  /**
   * Does nothing, since FakeEvents do not bubble.  Provided for compatibility
   * with native Events.
   * @override
   */
  stopPropagation() {}
};
<commit_msg>fix(ui): Export FakeEvent for use by UI plugins<commit_after>/*! @license
 * Shaka Player
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

goog.provide('shaka.util.FakeEvent');

/**
 * @summary Create an Event work-alike object based on the provided dictionary.
 * The event should contain all of the same properties from the dict.
 *
 * @extends {Event}
 * @export
 */
shaka.util.FakeEvent = class {
  /**
   * @param {string} type
   * @param {Object=} dict
   */
  constructor(type, dict = {}) {
    // Take properties from dict if present.
    for (const key in dict) {
      Object.defineProperty(this, key, {
        value: dict[key],
        writable: true,
        enumerable: true,
      });
    }

    // The properties below cannot be set by the dict.  They are all provided
    // for compatibility with native events.

    /** @const {boolean} */
    this.bubbles = false;

    /** @type {boolean} */
    this.cancelable = false;

    /** @type {boolean} */
    this.defaultPrevented = false;

    /**
     * According to MDN, Chrome uses high-res timers instead of epoch time.
     * Follow suit so that timeStamps on FakeEvents use the same base as
     * on native Events.
     * @const {number}
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp
     */
    this.timeStamp = window.performance && window.performance.now ?
        window.performance.now() : Date.now();

    /** @const {string} */
    this.type = type;

    /** @const {boolean} */
    this.isTrusted = false;

    /** @type {EventTarget} */
    this.currentTarget = null;

    /** @type {EventTarget} */
    this.target = null;

    /**
     * Non-standard property read by FakeEventTarget to stop processing
     * listeners.
     * @type {boolean}
     */
    this.stopped = false;
  }

  /**
   * Prevents the default action of the event.  Has no effect if the event isn't
   * cancellable.
   * @override
   */
  preventDefault() {
    if (this.cancelable) {
      this.defaultPrevented = true;
    }
  }

  /**
   * Stops processing event listeners for this event.  Provided for
   * compatibility with native Events.
   * @override
   */
  stopImmediatePropagation() {
    this.stopped = true;
  }

  /**
   * Does nothing, since FakeEvents do not bubble.  Provided for compatibility
   * with native Events.
   * @override
   */
  stopPropagation() {}
};
<|endoftext|>


<commit_before>'use strict';
let ProtoBuf = require('protobufjs');
let path = require('path');
let protoPath = path.join(__dirname, '../krpc.proto');
//let krpcBuilder = ProtoBuf.loadProtoFile(protoPath);
//module.exports = ;krpcBuilder.build().krpc.schema

let _root = null;
module.exports = {
    load,
    root: function() {
        return _root;
    }
};

function load(callback) {
    ProtoBuf.load(protoPath, protoBuffLoaded);

    function protoBuffLoaded(err, root) {
        if (err) {
            return callback(err);
        }
        _root = root.lookup('krpc').nested.schema;
        Object.keys(_root).forEach(function(propertyName) {
            module.exports[propertyName] = _root[propertyName];
        });
        callback();
    }
}
<commit_msg>Removing commented out code.<commit_after>'use strict';
let ProtoBuf = require('protobufjs');
let path = require('path');
let protoPath = path.join(__dirname, '../krpc.proto');
let _root = null;
module.exports = {
    load,
    root: function() {
        return _root;
    }
};

function load(callback) {
    ProtoBuf.load(protoPath, protoBuffLoaded);

    function protoBuffLoaded(err, root) {
        if (err) {
            return callback(err);
        }
        _root = root.lookup('krpc').nested.schema;
        Object.keys(_root).forEach(function(propertyName) {
            module.exports[propertyName] = _root[propertyName];
        });
        callback();
    }
}
<|endoftext|>