<commit_before>var _curry2 = require('./internal/_curry2');
var _has = require('./internal/_has');

/**
 * Takes a spec object and a test object; returns true if the test satisfies
 * the spec. Each of the spec's own properties must be a predicate function.
 * Each predicate is applied to the value of the corresponding property of the
 * test object. `where` returns true if all the predicates return true, false
 * otherwise.
 *
 * `where` is well suited to declaratively expressing constraints for other
 * functions such as `filter` and `find`.
 *
 * @func
 * @memberOf R
 * @since v0.1.1
 * @category Object
 * @sig {String: (* -> Boolean)} -> {String: *} -> Boolean
 * @param {Object} spec
 * @param {Object} testObj
 * @return {Boolean}
 * @example
 *
 *      // pred :: Object -> Boolean
 *      var pred = where({
 *        a: equals('foo'),
 *        b: complement(equals('bar')),
 *        x: gt(__, 10),
 *        y: lt(__, 20)
 *      });
 *
 *      pred({a: 'foo', b: 'xxx', x: 11, y: 19}); //=> true
 *      pred({a: 'xxx', b: 'xxx', x: 11, y: 19}); //=> false
 *      pred({a: 'foo', b: 'bar', x: 11, y: 19}); //=> false
 *      pred({a: 'foo', b: 'xxx', x: 10, y: 19}); //=> false
 *      pred({a: 'foo', b: 'xxx', x: 11, y: 20}); //=> false
 */
module.exports = _curry2(function where(spec, testObj) {
  for (var prop in spec) {
    if (_has(prop, spec) && !spec[prop](testObj[prop])) {
      return false;
    }
  }
  return true;
});
<commit_msg>where.js docs: prefix with "R." where needed (#1862)<commit_after>var _curry2 = require('./internal/_curry2');
var _has = require('./internal/_has');

/**
 * Takes a spec object and a test object; returns true if the test satisfies
 * the spec. Each of the spec's own properties must be a predicate function.
 * Each predicate is applied to the value of the corresponding property of the
 * test object. `where` returns true if all the predicates return true, false
 * otherwise.
 *
 * `where` is well suited to declaratively expressing constraints for other
 * functions such as `filter` and `find`.
 *
 * @func
 * @memberOf R
 * @since v0.1.1
 * @category Object
 * @sig {String: (* -> Boolean)} -> {String: *} -> Boolean
 * @param {Object} spec
 * @param {Object} testObj
 * @return {Boolean}
 * @example
 *
 *      // pred :: Object -> Boolean
 *      var pred = R.where({
 *        a: R.equals('foo'),
 *        b: R.complement(R.equals('bar')),
 *        x: R.gt(__, 10),
 *        y: R.lt(__, 20)
 *      });
 *
 *      pred({a: 'foo', b: 'xxx', x: 11, y: 19}); //=> true
 *      pred({a: 'xxx', b: 'xxx', x: 11, y: 19}); //=> false
 *      pred({a: 'foo', b: 'bar', x: 11, y: 19}); //=> false
 *      pred({a: 'foo', b: 'xxx', x: 10, y: 19}); //=> false
 *      pred({a: 'foo', b: 'xxx', x: 11, y: 20}); //=> false
 */
module.exports = _curry2(function where(spec, testObj) {
  for (var prop in spec) {
    if (_has(prop, spec) && !spec[prop](testObj[prop])) {
      return false;
    }
  }
  return true;
});
<|endoftext|>


<commit_before>(function($){
  var ns=$.fn.wipeImages,factory=ns.wipeFactory;
  $.fn.wipeImages.wipes=$.extend($.fn.wipeImages.wipes,{

    blindRight:function(el){
      var opts={
        cols:10,rows:1
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    blindLeft:function(el){
      var opts={
        cols:10,rows:1
      };
      var wipe=new factory(el,opts);
      wipe.reverse();
      wipe.run();
    },
    blindTop:function(el){
      var opts={
        cols:1,rows:5
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    blindBottom:function(el){
      var opts={
        cols:1,rows:5
      };
      var wipe=new factory(el,opts);
      wipe.reverse();
      wipe.run();
    },
    rain:function(el){
      var endHeight=el.height(),opts={
        cols:30,rows:1,
        from:{
          height:"0px"
        },
        to:{
          height:endHeight + "px"
        }
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    randomRain:function(el){
      var endHeight=el.height(),opts={
        cols:30,rows:1,
        from:{
          height:"0px"
        },
        to:{
          height:endHeight + "px"
        }
      };
      var wipe=new factory(el,opts);
      wipe.shuffle();
      wipe.run();
    },
    boxes:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    randomBoxes:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.shuffle();
      wipe.run();
    }
  });
})(jQuery);<commit_msg>Introducing diagonal fade, because we can now group stuff<commit_after>(function($){
  var ns=$.fn.wipeImages,factory=ns.wipeFactory;
  $.fn.wipeImages.wipes=$.extend($.fn.wipeImages.wipes,{

    blindRight:function(el){
      var opts={
        cols:10,rows:1
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    blindLeft:function(el){
      var opts={
        cols:10,rows:1
      };
      var wipe=new factory(el,opts);
      wipe.reverse();
      wipe.run();
    },
    blindTop:function(el){
      var opts={
        cols:1,rows:5
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    blindBottom:function(el){
      var opts={
        cols:1,rows:5
      };
      var wipe=new factory(el,opts);
      wipe.reverse();
      wipe.run();
    },
    rain:function(el){
      var endHeight=el.height(),opts={
        cols:30,rows:1,
        from:{
          height:"0px"
        },
        to:{
          height:endHeight + "px"
        }
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    randomRain:function(el){
      var endHeight=el.height(),opts={
        cols:30,rows:1,
        from:{
          height:"0px"
        },
        to:{
          height:endHeight + "px"
        }
      };
      var wipe=new factory(el,opts);
      wipe.shuffle();
      wipe.run();
    },
    boxes:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.run();
    },
    randomBoxes:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.shuffle();
      wipe.run();
    },
    diagTopLeft:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.to2D();
      wipe.run();
    },
    diagBottomRight:function(el){
      var endHeight=el.height(),opts={
        cols:8,rows:4
      };
      var wipe=new factory(el,opts);
      wipe.reverse();
      wipe.to2D();
      wipe.run();
    }
  });
})(jQuery);<|endoftext|>


<commit_before>/** @ignore */
const { invoke, isFunction } = require('./utilities.js')

/** @ignore */
const { Entity } = require('./entity.js')

/** @ignore */
const { SimpleIndex } = require('./simple_index.js')

/**
 * Class for world.
 *
 * @class      World (name)
 */
class World {
	/**
	 * Constructs an instance of the world.
	 *
	 * @param      {Function}  [indexer=SimpleIndex]  The indexer to use. Default is SimpleIndex. Can use MemoizedQueryIndex if better querying performance is needed, for increased component creation/removal costs.
	 */
	constructor(indexer = SimpleIndex) {
		/** @ignore */
		this.systems = []

		/**
		 * Maps entity IDs to entities
		 * @ignore
		 */
		this.entities = new Map()

		/** @ignore */
		this.components = {}

		/** @ignore */
		this.entityTemplates = {}

		/** @ignore */
		this.idCounter = 1

		/**
		 * Maps entire queries to arrays of entities
		 * @ignore
		 */
		this.index = new indexer(this)
	}

	/**
	 * Removes all entities from the world.
	 * Does not affect registered systems, components, or prototypes.
	 *
	 * @example
	 * world.clear()
	 */
	clear() {
		// Call onRemove on all components of all entities
		for (const [entityId, entity] of this.entities) {
			for (let componentName in entity.data) {
				// Get component, and call onRemove if it exists as a function
				let component = entity.data[componentName]
				invoke(component, 'onRemove')
			}
		}

		// Clear entities
		this.entities = new Map()
		this.index.clear()
	}

	/**
	 * Registers a component type to the world. Components must be constructable. If the component has an onCreate(),
	 * it is passed the entity first, then the rest of the arguments from methods like entity.set(). Also, components
	 * can have an onRemove() method, which gets called when removing that component from an entity.
	 *
	 * @param {string}   name           - The name
	 * @param {function} componentClass - The component class, must be a constructable class or function
	 *
	 * @example
	 * world.component('myComponent', class {
	 *     // It is highly recommended to use onCreate() over constructor(), because the component
	 *     // will have already been added to the entity. In the constructor(), it is not safe to use
	 *     // "entity" because it does not contain the current component while still in the constructor.
	 *     onCreate(entity, some, args) {
	 *         this.entity = entity
	 *         this.some = some
	 *         this.args = args
	 *     }
	 * })
	 * // entity === the new entity object
	 * // some === 10
	 * // args === 500
	 * world.entity().set('myComponent', 10, 500)
	 *
	 * @return {string} Registered component name on success, undefined on failure
	 */
	component(name, componentClass) {
		// Only allow functions and classes to be components
		if (isFunction(componentClass)) {
			this.components[name] = componentClass
			return name
		}
	}

	/**
	 * Creates a new entity in the world
	 *
	 * @param {string} [name] - The prototype name to use
	 *
	 * @example
	 * world.entity()
	 *
	 * @example
	 * world.entity('Player')
	 *
	 * @return {Entity} The new entity created
	 */
	entity(name) {
		let entityId = this.idCounter++
		let entity = new Entity(this, entityId)

		// Use 'name' to get prototype data (if specified)
		if (name && name in this.entityTemplates) {
			// Add all components from prototype
			let template = this.entityTemplates[name]
			for (let componentName in template) {
				// Update component with data from template
				let newComponentData = JSON.parse(template[componentName])
				entity.update(componentName, newComponentData)
			}
		}

		this.entities.set(entityId, entity)
		return entity
	}

	/**
	 * Registers a system to the world.
	 * The order the systems get registered, is the order then run in.
	 *
	 * @example
	 * // Movement system (basic example)
	 * class MovementSystem {
	 *   run(dt) {
	 *     world.every(['position', 'velocity'], (position, velocity) => {
	 *       position.x += velocity.x
	 *       position.y += velocity.y
	 *     })
	 *   }
	 * }
	 * // Input system (advanced example)
	 * class InputSystem {
	 *   constructor(button) {
	 *     // This is showing how you can optionally pass parameters to the system's constructor
	 *     this.button = button
	 *     // See world.setContext() for a simpler way to inject dependencies
	 *   }
	 *   run(dt) {
	 *     if (this.button.isPressed()) {
	 *       world.every(['controlled', 'velocity'], (controlled, velocity, entity) => {
	 *         // Start moving all controlled entities to the right
	 *         velocity.x = 1
	 *         velocity.y = 0
	 *         // Can also use the full entity here, in this case to add a new component
	 *         entity.set('useFuel')
	 *       })
	 *     }
	 *   }
	 * }
	 * // Register systems in order (this method)
	 * world.system(InputSystem, button) // pass button to system constructor
	 * world.system(MovementSystem)
	 * // Run systems (can get dt or frame time)
	 * world.run(1000.0 / 60.0)
	 *
	 * @param {...Object} args - Both signatures are accepted: (components, systemClass, ...args) or (systemClass, ...args).
	 *
	 * **{systemClass}**: The system class to instantiate. Can contain a constructor(), run(), or any other custom methods/properties.
	 *
	 * **[...args]**: The arguments to forward to the system's constructor.
	 *
	 * @return {number} Unique ID of the system on success or undefined on failure
	 */
	system(...args) {
		// Get systemClass and remaining args from args
		const [systemClass, ...rest] = args

		// Make sure the system is valid
		if (isFunction(systemClass)) {
			// Create the system
			const newSystem = new systemClass(...rest)

			// Add the system, return its ID
			return this.systems.push(newSystem) - 1
		}
	}

	/**
	 * Calls run() on all systems. These methods can return true to cause an additional rerun of all systems.
	 * Reruns will not receive the args passed into run(), as a way to identify reruns.
	 *
	 * @example
	 * world.run(deltaTime)
	 *
	 * @example
	 * // Example flow of method call order:
	 * // Setup systems:
	 * world.system(systemA)
	 * world.system(systemB)
	 * // During world.run():
	 * // systemA.run()
	 * // systemB.run()
	 *
	 * @param {...Object} [args] - The arguments to forward to the systems' methods
	 */
	run(...args) {
		let status = true
		// Continue rerunning while any systems return true
		while (status) {
			status = undefined
			for (const system of this.systems) {
				// Try to call the "run" method
				const result = invoke(system, 'run', ...args)
				status = status || result
			}

			// Clear args after first run, so re-runs can be identified
			args = []
		}
	}

	/**
	 * Iterate through components and entities with all of the specified component names
	 *
	 * @example
	 * // Use a callback to process entities one-by-one
	 * world.each('comp', ({ comp }) => { comp.value = 0 })
	 *
	 * @example
	 * // Get an iterator for the entities
	 * const it = world.every('comp')
	 * for (let entity of it) {...}
	 *
	 * @example
	 * // Pass multiple components, arrays, use extra entity parameter,
	 * // and destructure components outside the query
	 * world.each('compA', ['more', 'comps'], 'compB', ({ compA, compC }, entity) => {
	 *   if (compC) compC.foo(compC.bar)
	 *   compA.foo = 'bar'
	 *   entity.remove('compB')
	 * })
	 *
	 * @param {Array}     componentNames - The component names to match entities with. This checks if the entity
	 * has ALL of the specified components, but does not check for additional components.
	 * @param {Function}  callback       - The callback to call for each entity. Takes (entity.data, entity).
	 * Entity data is just an object of {[componentName]: [component]}, that can be destructured with syntax shown
	 * in the examples.
	 *
	 * @return {MapIterator} If no callback specified, then returns a generator to the entities themselves.
	 * Otherwise, returns the last loop iteration status, returned by the callback.
	 */
	each(...args) {
		// Gather component names and a callback (if any) from args
		const compNames = []
		let callback
		for (const arg of args) {
			if (typeof arg === 'string') {
				compNames.push(arg)
			} else if (typeof arg === 'function') {
				callback = arg
			} else if (Array.isArray(arg)) {
				// Add 1-level deep arrays of strings as separate component names
				for (const name of arg) {
					compNames.push(name)
				}
			} else {
				throw new Error(`Unknown argument ${arg} with type ${typeof arg} passed to world.each().`)
			}
		}

		// Get indexed map of entities
		const entities = this.index.query(...compNames)

		if (callback) {
			// Go through the map of entities
			let status
			for (const entity of entities) {
				// Pass component data and the main entity
				status = callback(entity.data, entity)

				// Stop the iteration when the callback returns false
				if (status === false) {
					break
				}
			}
			return status
		}
		return entities
	}

	/**
	 * Returns an entity by ID
	 * Returns undefined if it doesn't exist
	 *
	 * @example
	 * world.getEntityById(123)
	 *
	 * @param {number} entityId - The entity ID to lookup for the entity
	 *
	 * @return {Entity} Entity if found, otherwise undefined
	 */
	getEntityById(entityId) {
		return this.entities.get(entityId)
	}

	/**
	 * Registers entity prototype(s). Any existing prototype names that are the same will be overwritten
	 *
	 * @example
	 * world.prototype({
	 *     Movable: {
	 *         position: {},
	 *         velocity: {}
	 *     }
	 * })
	 *
	 * @param {Object} data - Object structure to register as a prototype. Should be a dictionary with the top level keys
	 * being the prototype names. Can also be a JSON formatted string.
	 *
	 * @return {number} Number of prototypes added.
	 */
	prototype(data) {
		let count = 0

		// Convert to an object when given a string
		if (typeof data === 'string') {
			data = JSON.parse(data)
		}

		// Data must be an object at this point
		if (typeof data === 'object') {
			// Iterate through prototype names
			for (let protoName in data) {
				let inputObject = data[protoName]
				let protoObject = {}
				// Iterate through component names
				for (let compName in inputObject) {
					// Store strings of each component
					protoObject[compName] = JSON.stringify(
						inputObject[compName]
					)
				}
				this.entityTemplates[protoName] = protoObject
				++count
			}
		}

		return count
	}
}

exports.World = World
<commit_msg>Add back get() to world<commit_after>/** @ignore */
const { invoke, isFunction } = require('./utilities.js')

/** @ignore */
const { Entity } = require('./entity.js')

/** @ignore */
const { SimpleIndex } = require('./simple_index.js')

/**
 * Class for world.
 *
 * @class      World (name)
 */
class World {
	/**
	 * Constructs an instance of the world.
	 *
	 * @param      {Function}  [indexer=SimpleIndex]  The indexer to use. Default is SimpleIndex. Can use MemoizedQueryIndex if better querying performance is needed, for increased component creation/removal costs.
	 */
	constructor(indexer = SimpleIndex) {
		/** @ignore */
		this.systems = []

		/**
		 * Maps entity IDs to entities
		 * @ignore
		 */
		this.entities = new Map()

		/** @ignore */
		this.components = {}

		/** @ignore */
		this.entityTemplates = {}

		/** @ignore */
		this.idCounter = 1

		/**
		 * Maps entire queries to arrays of entities
		 * @ignore
		 */
		this.index = new indexer(this)
	}

	/**
	 * Removes all entities from the world.
	 * Does not affect registered systems, components, or prototypes.
	 *
	 * @example
	 * world.clear()
	 */
	clear() {
		// Call onRemove on all components of all entities
		for (const [entityId, entity] of this.entities) {
			for (let componentName in entity.data) {
				// Get component, and call onRemove if it exists as a function
				let component = entity.data[componentName]
				invoke(component, 'onRemove')
			}
		}

		// Clear entities
		this.entities = new Map()
		this.index.clear()
	}

	/**
	 * Registers a component type to the world. Components must be constructable. If the component has an onCreate(),
	 * it is passed the entity first, then the rest of the arguments from methods like entity.set(). Also, components
	 * can have an onRemove() method, which gets called when removing that component from an entity.
	 *
	 * @param {string}   name           - The name
	 * @param {function} componentClass - The component class, must be a constructable class or function
	 *
	 * @example
	 * world.component('myComponent', class {
	 *     // It is highly recommended to use onCreate() over constructor(), because the component
	 *     // will have already been added to the entity. In the constructor(), it is not safe to use
	 *     // "entity" because it does not contain the current component while still in the constructor.
	 *     onCreate(entity, some, args) {
	 *         this.entity = entity
	 *         this.some = some
	 *         this.args = args
	 *     }
	 * })
	 * // entity === the new entity object
	 * // some === 10
	 * // args === 500
	 * world.entity().set('myComponent', 10, 500)
	 *
	 * @return {string} Registered component name on success, undefined on failure
	 */
	component(name, componentClass) {
		// Only allow functions and classes to be components
		if (isFunction(componentClass)) {
			this.components[name] = componentClass
			return name
		}
	}

	/**
	 * Creates a new entity in the world
	 *
	 * @param {string} [name] - The prototype name to use
	 *
	 * @example
	 * world.entity()
	 *
	 * @example
	 * world.entity('Player')
	 *
	 * @return {Entity} The new entity created
	 */
	entity(name) {
		let entityId = this.idCounter++
		let entity = new Entity(this, entityId)

		// Use 'name' to get prototype data (if specified)
		if (name && name in this.entityTemplates) {
			// Add all components from prototype
			let template = this.entityTemplates[name]
			for (let componentName in template) {
				// Update component with data from template
				let newComponentData = JSON.parse(template[componentName])
				entity.update(componentName, newComponentData)
			}
		}

		this.entities.set(entityId, entity)
		return entity
	}

	/**
	 * Registers a system to the world.
	 * The order the systems get registered, is the order then run in.
	 *
	 * @example
	 * // Movement system (basic example)
	 * class MovementSystem {
	 *   run(dt) {
	 *     world.every(['position', 'velocity'], (position, velocity) => {
	 *       position.x += velocity.x
	 *       position.y += velocity.y
	 *     })
	 *   }
	 * }
	 * // Input system (advanced example)
	 * class InputSystem {
	 *   constructor(button) {
	 *     // This is showing how you can optionally pass parameters to the system's constructor
	 *     this.button = button
	 *     // See world.setContext() for a simpler way to inject dependencies
	 *   }
	 *   run(dt) {
	 *     if (this.button.isPressed()) {
	 *       world.every(['controlled', 'velocity'], (controlled, velocity, entity) => {
	 *         // Start moving all controlled entities to the right
	 *         velocity.x = 1
	 *         velocity.y = 0
	 *         // Can also use the full entity here, in this case to add a new component
	 *         entity.set('useFuel')
	 *       })
	 *     }
	 *   }
	 * }
	 * // Register systems in order (this method)
	 * world.system(InputSystem, button) // pass button to system constructor
	 * world.system(MovementSystem)
	 * // Run systems (can get dt or frame time)
	 * world.run(1000.0 / 60.0)
	 *
	 * @param {...Object} args - Both signatures are accepted: (components, systemClass, ...args) or (systemClass, ...args).
	 *
	 * **{systemClass}**: The system class to instantiate. Can contain a constructor(), run(), or any other custom methods/properties.
	 *
	 * **[...args]**: The arguments to forward to the system's constructor.
	 *
	 * @return {number} Unique ID of the system on success or undefined on failure
	 */
	system(...args) {
		// Get systemClass and remaining args from args
		const [systemClass, ...rest] = args

		// Make sure the system is valid
		if (isFunction(systemClass)) {
			// Create the system
			const newSystem = new systemClass(...rest)

			// Add the system, return its ID
			return this.systems.push(newSystem) - 1
		}
	}

	/**
	 * Calls run() on all systems. These methods can return true to cause an additional rerun of all systems.
	 * Reruns will not receive the args passed into run(), as a way to identify reruns.
	 *
	 * @example
	 * world.run(deltaTime)
	 *
	 * @example
	 * // Example flow of method call order:
	 * // Setup systems:
	 * world.system(systemA)
	 * world.system(systemB)
	 * // During world.run():
	 * // systemA.run()
	 * // systemB.run()
	 *
	 * @param {...Object} [args] - The arguments to forward to the systems' methods
	 */
	run(...args) {
		let status = true
		// Continue rerunning while any systems return true
		while (status) {
			status = undefined
			for (const system of this.systems) {
				// Try to call the "run" method
				const result = invoke(system, 'run', ...args)
				status = status || result
			}

			// Clear args after first run, so re-runs can be identified
			args = []
		}
	}

	/**
	 * Iterate through components and entities with all of the specified component names
	 *
	 * @example
	 * // Use a callback to process entities one-by-one
	 * world.each('comp', ({ comp }) => { comp.value = 0 })
	 *
	 * @example
	 * // Get an iterator for the entities
	 * const it = world.every('comp')
	 * for (let entity of it) {...}
	 *
	 * @example
	 * // Pass multiple components, arrays, use extra entity parameter,
	 * // and destructure components outside the query
	 * world.each('compA', ['more', 'comps'], 'compB', ({ compA, compC }, entity) => {
	 *   if (compC) compC.foo(compC.bar)
	 *   compA.foo = 'bar'
	 *   entity.remove('compB')
	 * })
	 *
	 * @param {Array}     componentNames - The component names to match entities with. This checks if the entity
	 * has ALL of the specified components, but does not check for additional components.
	 * @param {Function}  callback       - The callback to call for each entity. Takes (entity.data, entity).
	 * Entity data is just an object of {[componentName]: [component]}, that can be destructured with syntax shown
	 * in the examples.
	 *
	 * @return {MapIterator} If no callback specified, then returns a generator to the entities themselves.
	 * Otherwise, returns the last loop iteration status, returned by the callback.
	 */
	each(...args) {
		// Gather component names and a callback (if any) from args
		const compNames = []
		let callback
		for (const arg of args) {
			if (typeof arg === 'string') {
				compNames.push(arg)
			} else if (typeof arg === 'function') {
				callback = arg
			} else if (Array.isArray(arg)) {
				// Add 1-level deep arrays of strings as separate component names
				for (const name of arg) {
					compNames.push(name)
				}
			} else {
				throw new Error(`Unknown argument ${arg} with type ${typeof arg} passed to world.each().`)
			}
		}

		// Get indexed map of entities
		const entities = this.index.query(...compNames)

		if (callback) {
			// Go through the map of entities
			let status
			for (const entity of entities) {
				// Pass component data and the main entity
				status = callback(entity.data, entity)

				// Stop the iteration when the callback returns false
				if (status === false) {
					break
				}
			}
			return status
		}
		return entities
	}

	/**
	 * Returns an array of entities with matching components
	 * Simplified version of each(), returns an array instead of an iterator.
	 *
	 * @example
	 * const entities = world.get('player', 'sprite')
	 *
	 * @param {Array} componentNames - The component names to match on. See each() for how this matches.
	 *
	 * @return {Array} Array of entities, instead of iterator like each().
	 */
	get(...componentNames) {
		return [...this.each(componentNames)]
	}

	/**
	 * Returns an entity by ID
	 * Returns undefined if it doesn't exist
	 *
	 * @example
	 * world.getEntityById(123)
	 *
	 * @param {number} entityId - The entity ID to lookup for the entity
	 *
	 * @return {Entity} Entity if found, otherwise undefined
	 */
	getEntityById(entityId) {
		return this.entities.get(entityId)
	}

	/**
	 * Registers entity prototype(s). Any existing prototype names that are the same will be overwritten
	 *
	 * @example
	 * world.prototype({
	 *     Movable: {
	 *         position: {},
	 *         velocity: {}
	 *     }
	 * })
	 *
	 * @param {Object} data - Object structure to register as a prototype. Should be a dictionary with the top level keys
	 * being the prototype names. Can also be a JSON formatted string.
	 *
	 * @return {number} Number of prototypes added.
	 */
	prototype(data) {
		let count = 0

		// Convert to an object when given a string
		if (typeof data === 'string') {
			data = JSON.parse(data)
		}

		// Data must be an object at this point
		if (typeof data === 'object') {
			// Iterate through prototype names
			for (let protoName in data) {
				let inputObject = data[protoName]
				let protoObject = {}
				// Iterate through component names
				for (let compName in inputObject) {
					// Store strings of each component
					protoObject[compName] = JSON.stringify(
						inputObject[compName]
					)
				}
				this.entityTemplates[protoName] = protoObject
				++count
			}
		}

		return count
	}
}

exports.World = World
<|endoftext|>


<commit_before>var container = document.createElement("DIV");
container.className = "feedback-button";

container.style.backgroundColor = "#db4437";
container.style.height = "56px";
container.style.width = "56px";
container.style.borderRadius = "50%";
container.style.boxShadow = "0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)";
container.style.cursor = "pointer";
container.style.position = "fixed";
container.style.top = "200px";
container.style.right = "2px";

var image = document.createElement("IMG");
image.src = "https://ssl.gstatic.com/bt/C3341AA7A1A076756462EE2E5CD71C11/2x/bt_speed_dial_2x.png";
image.style.position = "absolute";
image.style.left = "0";
image.style.top = "0";
image.style.marginLeft = "5px";
image.style.marginTop = "5px";

container.appendChild(image);
container.addEventListener("click", function(){ alert("Hello World!"); });
document.body.appendChild(container);
<commit_msg>feedback form added<commit_after>////
// function section
////

var sendFeedback = function (event) {
    event.preventDefault();
    var feedback = this["feedback"].value;
    if (feedback == null || feedback == "") {
        alert("You have to fill the Feedback field");
        return false;
    }
    else {
        alert(feedback);
        closeFeedbackForm();
        return false;
    }
}

var openFeedbackForm = function () {
    form.style.display = "block";
    button.style.display = "none";
}

var closeFeedbackForm = function () {
    form["feedback"].value = "";
    form.style.display = "none";
    button.style.display = "block";
}

////
// DOM section
////

// fk button
var container = document.createElement("DIV");
container.className = "fk-button";
container.style.position = "fixed";
container.style.top = "200px";
container.style.right = "2px";

// button button
var button = document.createElement("DIV");
button.className = "feedback-button";
button.style.position = "relative";
button.style.backgroundColor = "#db4437";
button.style.height = "56px";
button.style.width = "56px";
button.style.borderRadius = "50%";
button.style.boxShadow = "0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)";
button.style.cursor = "pointer";

// button image
var image = document.createElement("IMG");
image.src = "https://ssl.gstatic.com/bt/C3341AA7A1A076756462EE2E5CD71C11/2x/bt_speed_dial_2x.png";
image.style.position = "absolute";
image.style.left = "0";
image.style.top = "0";
image.style.marginLeft = "5px";
image.style.marginTop = "5px";

// feedback form
var form = document.createElement("FORM");
form.method = "post";
form.setAttribute("id","fk-form");
form.style.display = "none";

//input element, text
var i = document.createElement("INPUT");
i.setAttribute("type","textarea");
i.setAttribute("name","feedback");

//input element, Submit button
var s = document.createElement("INPUT");
s.setAttribute("type","submit");
s.setAttribute("value","Submit");

form.appendChild(i);
form.appendChild(s);
form.addEventListener("submit", sendFeedback, false);

// add element to button
button.appendChild(image);
container.appendChild(button);
container.appendChild(form);

// add event on button click
button.addEventListener("click", openFeedbackForm);

// append fk to the document
document.body.appendChild(container);
<|endoftext|>


<commit_before>DEBUG = true;

var fu = exports;

var NOT_FOUND = "Not Found\n";
function notFound(req, res) {
  res.sendHeader(404, [ ["Content-Type", "text/plain"]
                    , ["Content-Length", NOT_FOUND.length]
                    ]);
  res.sendBody(NOT_FOUND);
  res.finish();
}

var getMap = {};

fu.get = function (path, handler) {
  getMap[path] = handler;
};

var server = new node.http.Server(function (req, res) {
  if (req.method === "GET" || req.method === "HEAD") {
    var handler = getMap[req.uri.path] || notFound;

    res.simpleText = function (code, body) {
      res.sendHeader(code, [ ["Content-Type", "text/plain"]
                           , ["Content-Length", body.length]
                           ]);
      res.sendBody(body);
      res.finish();
    };

    res.simpleJSON = function (code, obj) {
      var body = JSON.stringify(obj);
      res.sendHeader(code, [ ["Content-Type", "text/json"]
                           , ["Content-Length", body.length]
                           ]);
      res.sendBody(body);
      res.finish();
    };

    handler(req, res);
  }
});

fu.listen = function (port, host) {
  server.listen(port, host);
  puts("Server at http://" + (host || "127.0.0.1") + ":" + port.toString() + "/");
};

fu.close = function () { server.close(); };

function extname (path) {
  var index = path.lastIndexOf(".");
  return index < 0 ? "" : path.substring(index);
}

fu.staticHandler = function (filename) {
  var body, headers;
  var content_type = fu.mime.lookupExtension(extname(filename));
  var encoding = (content_type.slice(0,4) === "text" ? "utf8" : "raw");

  function loadResponseData(callback) {
    if (body && headers && !DEBUG) {
      callback();
      return;
    }

    node.fs.cat(filename, encoding, function (status, data) {
      if (status != 0) return notFound;

      body = data;
      headers = [ [ "Content-Type"   , content_type ]
                , [ "Content-Length" , body.length ]
                ];
      if (!DEBUG)
        headers.push(["Cache-Control", "public"]);

      puts("static file " + filename + " loaded");
      callback();
    });
  }

  return function (req, res) {
    loadResponseData(function () {
      res.sendHeader(200, headers);
      res.sendBody(body);
      res.finish();
    });
  }
};

// stolen from jack- thanks
fu.mime = {
  // returns MIME type for extension, or fallback, or octet-steam
  lookupExtension : function(ext, fallback) {
    return fu.mime.TYPES[ext.toLowerCase()] || fallback || 'application/octet-stream';
  },

  // List of most common mime-types, stolen from Rack.
  TYPES : { ".3gp"   : "video/3gpp"
          , ".a"     : "application/octet-stream"
          , ".ai"    : "application/postscript"
          , ".aif"   : "audio/x-aiff"
          , ".aiff"  : "audio/x-aiff"
          , ".asc"   : "application/pgp-signature"
          , ".asf"   : "video/x-ms-asf"
          , ".asm"   : "text/x-asm"
          , ".asx"   : "video/x-ms-asf"
          , ".atom"  : "application/atom+xml"
          , ".au"    : "audio/basic"
          , ".avi"   : "video/x-msvideo"
          , ".bat"   : "application/x-msdownload"
          , ".bin"   : "application/octet-stream"
          , ".bmp"   : "image/bmp"
          , ".bz2"   : "application/x-bzip2"
          , ".c"     : "text/x-c"
          , ".cab"   : "application/vnd.ms-cab-compressed"
          , ".cc"    : "text/x-c"
          , ".chm"   : "application/vnd.ms-htmlhelp"
          , ".class"   : "application/octet-stream"
          , ".com"   : "application/x-msdownload"
          , ".conf"  : "text/plain"
          , ".cpp"   : "text/x-c"
          , ".crt"   : "application/x-x509-ca-cert"
          , ".css"   : "text/css"
          , ".csv"   : "text/csv"
          , ".cxx"   : "text/x-c"
          , ".deb"   : "application/x-debian-package"
          , ".der"   : "application/x-x509-ca-cert"
          , ".diff"  : "text/x-diff"
          , ".djv"   : "image/vnd.djvu"
          , ".djvu"  : "image/vnd.djvu"
          , ".dll"   : "application/x-msdownload"
          , ".dmg"   : "application/octet-stream"
          , ".doc"   : "application/msword"
          , ".dot"   : "application/msword"
          , ".dtd"   : "application/xml-dtd"
          , ".dvi"   : "application/x-dvi"
          , ".ear"   : "application/java-archive"
          , ".eml"   : "message/rfc822"
          , ".eps"   : "application/postscript"
          , ".exe"   : "application/x-msdownload"
          , ".f"     : "text/x-fortran"
          , ".f77"   : "text/x-fortran"
          , ".f90"   : "text/x-fortran"
          , ".flv"   : "video/x-flv"
          , ".for"   : "text/x-fortran"
          , ".gem"   : "application/octet-stream"
          , ".gemspec" : "text/x-script.ruby"
          , ".gif"   : "image/gif"
          , ".gz"    : "application/x-gzip"
          , ".h"     : "text/x-c"
          , ".hh"    : "text/x-c"
          , ".htm"   : "text/html"
          , ".html"  : "text/html"
          , ".ico"   : "image/vnd.microsoft.icon"
          , ".ics"   : "text/calendar"
          , ".ifb"   : "text/calendar"
          , ".iso"   : "application/octet-stream"
          , ".jar"   : "application/java-archive"
          , ".java"  : "text/x-java-source"
          , ".jnlp"  : "application/x-java-jnlp-file"
          , ".jpeg"  : "image/jpeg"
          , ".jpg"   : "image/jpeg"
          , ".js"    : "application/javascript"
          , ".json"  : "application/json"
          , ".log"   : "text/plain"
          , ".m3u"   : "audio/x-mpegurl"
          , ".m4v"   : "video/mp4"
          , ".man"   : "text/troff"
          , ".mathml"  : "application/mathml+xml"
          , ".mbox"  : "application/mbox"
          , ".mdoc"  : "text/troff"
          , ".me"    : "text/troff"
          , ".mid"   : "audio/midi"
          , ".midi"  : "audio/midi"
          , ".mime"  : "message/rfc822"
          , ".mml"   : "application/mathml+xml"
          , ".mng"   : "video/x-mng"
          , ".mov"   : "video/quicktime"
          , ".mp3"   : "audio/mpeg"
          , ".mp4"   : "video/mp4"
          , ".mp4v"  : "video/mp4"
          , ".mpeg"  : "video/mpeg"
          , ".mpg"   : "video/mpeg"
          , ".ms"    : "text/troff"
          , ".msi"   : "application/x-msdownload"
          , ".odp"   : "application/vnd.oasis.opendocument.presentation"
          , ".ods"   : "application/vnd.oasis.opendocument.spreadsheet"
          , ".odt"   : "application/vnd.oasis.opendocument.text"
          , ".ogg"   : "application/ogg"
          , ".p"     : "text/x-pascal"
          , ".pas"   : "text/x-pascal"
          , ".pbm"   : "image/x-portable-bitmap"
          , ".pdf"   : "application/pdf"
          , ".pem"   : "application/x-x509-ca-cert"
          , ".pgm"   : "image/x-portable-graymap"
          , ".pgp"   : "application/pgp-encrypted"
          , ".pkg"   : "application/octet-stream"
          , ".pl"    : "text/x-script.perl"
          , ".pm"    : "text/x-script.perl-module"
          , ".png"   : "image/png"
          , ".pnm"   : "image/x-portable-anymap"
          , ".ppm"   : "image/x-portable-pixmap"
          , ".pps"   : "application/vnd.ms-powerpoint"
          , ".ppt"   : "application/vnd.ms-powerpoint"
          , ".ps"    : "application/postscript"
          , ".psd"   : "image/vnd.adobe.photoshop"
          , ".py"    : "text/x-script.python"
          , ".qt"    : "video/quicktime"
          , ".ra"    : "audio/x-pn-realaudio"
          , ".rake"  : "text/x-script.ruby"
          , ".ram"   : "audio/x-pn-realaudio"
          , ".rar"   : "application/x-rar-compressed"
          , ".rb"    : "text/x-script.ruby"
          , ".rdf"   : "application/rdf+xml"
          , ".roff"  : "text/troff"
          , ".rpm"   : "application/x-redhat-package-manager"
          , ".rss"   : "application/rss+xml"
          , ".rtf"   : "application/rtf"
          , ".ru"    : "text/x-script.ruby"
          , ".s"     : "text/x-asm"
          , ".sgm"   : "text/sgml"
          , ".sgml"  : "text/sgml"
          , ".sh"    : "application/x-sh"
          , ".sig"   : "application/pgp-signature"
          , ".snd"   : "audio/basic"
          , ".so"    : "application/octet-stream"
          , ".svg"   : "image/svg+xml"
          , ".svgz"  : "image/svg+xml"
          , ".swf"   : "application/x-shockwave-flash"
          , ".t"     : "text/troff"
          , ".tar"   : "application/x-tar"
          , ".tbz"   : "application/x-bzip-compressed-tar"
          , ".tcl"   : "application/x-tcl"
          , ".tex"   : "application/x-tex"
          , ".texi"  : "application/x-texinfo"
          , ".texinfo" : "application/x-texinfo"
          , ".text"  : "text/plain"
          , ".tif"   : "image/tiff"
          , ".tiff"  : "image/tiff"
          , ".torrent" : "application/x-bittorrent"
          , ".tr"    : "text/troff"
          , ".txt"   : "text/plain"
          , ".vcf"   : "text/x-vcard"
          , ".vcs"   : "text/x-vcalendar"
          , ".vrml"  : "model/vrml"
          , ".war"   : "application/java-archive"
          , ".wav"   : "audio/x-wav"
          , ".wma"   : "audio/x-ms-wma"
          , ".wmv"   : "video/x-ms-wmv"
          , ".wmx"   : "video/x-ms-wmx"
          , ".wrl"   : "model/vrml"
          , ".wsdl"  : "application/wsdl+xml"
          , ".xbm"   : "image/x-xbitmap"
          , ".xhtml"   : "application/xhtml+xml"
          , ".xls"   : "application/vnd.ms-excel"
          , ".xml"   : "application/xml"
          , ".xpm"   : "image/x-xpixmap"
          , ".xsl"   : "application/xml"
          , ".xslt"  : "application/xslt+xml"
          , ".yaml"  : "text/yaml"
          , ".yml"   : "text/yaml"
          , ".zip"   : "application/zip"
          }
};
<commit_msg>Really commit cookie support from András Bártházi.<commit_after>DEBUG = true;

var fu = exports;

var NOT_FOUND = "Not Found\n";
function notFound(req, res) {
  res.sendHeader(404, [ ["Content-Type", "text/plain"]
                    , ["Content-Length", NOT_FOUND.length]
                    ]);
  res.sendBody(NOT_FOUND);
  res.finish();
}

var getMap = {};

fu.get = function (path, handler) {
  getMap[path] = handler;
};

var server = new node.http.Server(function (req, res) {
  if (req.method === "GET" || req.method === "HEAD") {
    var handler = getMap[req.uri.path] || notFound;

    res.simpleText = function (code, body) {
      res.sendHeader(code, [ ["Content-Type", "text/plain"]
                           , ["Content-Length", body.length]
                           ]);
      res.sendBody(body);
      res.finish();
    };

    res.simpleJSON = function (code, obj) {
      var body = JSON.stringify(obj);
      res.sendHeader(code, [ ["Content-Type", "text/json"]
                           , ["Content-Length", body.length]
                           ]);
      res.sendBody(body);
      res.finish();
    };

    req.cookies = {};
    for (var i = 0; i < req.headers.length; i++) {
      if (req.headers[i][0].toLowerCase() == "cookie") {
        var cookies = req.headers[i][1].split(/\s*;\s*/);
        for (var j = 0; j < cookies.length; j++) {
          var pos = cookies[j].indexOf("=");
          var name = cookies[j].substring(0, pos);
          var value = cookies[j].substring(pos+1);
          req.cookies[name] = value;
        }
      }
    }
    res.setCookie = function (name, value) {
      if (!res._cookies) { res._cookies = []; }
      res._cookies.push(name+"="+value);
    };
    res._sendHeader = res.sendHeader;
    res.sendHeader = function (code, headers) {
      if (res._cookies) {
        for (var i=0; i<res._cookies.length; i++) {
          headers.push(["Set-Cookie", res._cookies[i]]);
        }
      }
      res._sendHeader(code, headers);
    };

    handler(req, res);
  }
});

fu.listen = function (port, host) {
  server.listen(port, host);
  puts("Server at http://" + (host || "127.0.0.1") + ":" + port.toString() + "/");
};

fu.close = function () { server.close(); };

function extname (path) {
  var index = path.lastIndexOf(".");
  return index < 0 ? "" : path.substring(index);
}

fu.staticHandler = function (filename) {
  var body, headers;
  var content_type = fu.mime.lookupExtension(extname(filename));
  var encoding = (content_type.slice(0,4) === "text" ? "utf8" : "raw");

  function loadResponseData(callback) {
    if (body && headers && !DEBUG) {
      callback();
      return;
    }

    node.fs.cat(filename, encoding, function (status, data) {
      if (status != 0) return notFound;

      body = data;
      headers = [ [ "Content-Type"   , content_type ]
                , [ "Content-Length" , body.length ]
                ];
      if (!DEBUG)
        headers.push(["Cache-Control", "public"]);

      puts("static file " + filename + " loaded");
      callback();
    });
  }

  return function (req, res) {
    loadResponseData(function () {
      res.sendHeader(200, headers);
      res.sendBody(body);
      res.finish();
    });
  }
};

// stolen from jack- thanks
fu.mime = {
  // returns MIME type for extension, or fallback, or octet-steam
  lookupExtension : function(ext, fallback) {
    return fu.mime.TYPES[ext.toLowerCase()] || fallback || 'application/octet-stream';
  },

  // List of most common mime-types, stolen from Rack.
  TYPES : { ".3gp"   : "video/3gpp"
          , ".a"     : "application/octet-stream"
          , ".ai"    : "application/postscript"
          , ".aif"   : "audio/x-aiff"
          , ".aiff"  : "audio/x-aiff"
          , ".asc"   : "application/pgp-signature"
          , ".asf"   : "video/x-ms-asf"
          , ".asm"   : "text/x-asm"
          , ".asx"   : "video/x-ms-asf"
          , ".atom"  : "application/atom+xml"
          , ".au"    : "audio/basic"
          , ".avi"   : "video/x-msvideo"
          , ".bat"   : "application/x-msdownload"
          , ".bin"   : "application/octet-stream"
          , ".bmp"   : "image/bmp"
          , ".bz2"   : "application/x-bzip2"
          , ".c"     : "text/x-c"
          , ".cab"   : "application/vnd.ms-cab-compressed"
          , ".cc"    : "text/x-c"
          , ".chm"   : "application/vnd.ms-htmlhelp"
          , ".class"   : "application/octet-stream"
          , ".com"   : "application/x-msdownload"
          , ".conf"  : "text/plain"
          , ".cpp"   : "text/x-c"
          , ".crt"   : "application/x-x509-ca-cert"
          , ".css"   : "text/css"
          , ".csv"   : "text/csv"
          , ".cxx"   : "text/x-c"
          , ".deb"   : "application/x-debian-package"
          , ".der"   : "application/x-x509-ca-cert"
          , ".diff"  : "text/x-diff"
          , ".djv"   : "image/vnd.djvu"
          , ".djvu"  : "image/vnd.djvu"
          , ".dll"   : "application/x-msdownload"
          , ".dmg"   : "application/octet-stream"
          , ".doc"   : "application/msword"
          , ".dot"   : "application/msword"
          , ".dtd"   : "application/xml-dtd"
          , ".dvi"   : "application/x-dvi"
          , ".ear"   : "application/java-archive"
          , ".eml"   : "message/rfc822"
          , ".eps"   : "application/postscript"
          , ".exe"   : "application/x-msdownload"
          , ".f"     : "text/x-fortran"
          , ".f77"   : "text/x-fortran"
          , ".f90"   : "text/x-fortran"
          , ".flv"   : "video/x-flv"
          , ".for"   : "text/x-fortran"
          , ".gem"   : "application/octet-stream"
          , ".gemspec" : "text/x-script.ruby"
          , ".gif"   : "image/gif"
          , ".gz"    : "application/x-gzip"
          , ".h"     : "text/x-c"
          , ".hh"    : "text/x-c"
          , ".htm"   : "text/html"
          , ".html"  : "text/html"
          , ".ico"   : "image/vnd.microsoft.icon"
          , ".ics"   : "text/calendar"
          , ".ifb"   : "text/calendar"
          , ".iso"   : "application/octet-stream"
          , ".jar"   : "application/java-archive"
          , ".java"  : "text/x-java-source"
          , ".jnlp"  : "application/x-java-jnlp-file"
          , ".jpeg"  : "image/jpeg"
          , ".jpg"   : "image/jpeg"
          , ".js"    : "application/javascript"
          , ".json"  : "application/json"
          , ".log"   : "text/plain"
          , ".m3u"   : "audio/x-mpegurl"
          , ".m4v"   : "video/mp4"
          , ".man"   : "text/troff"
          , ".mathml"  : "application/mathml+xml"
          , ".mbox"  : "application/mbox"
          , ".mdoc"  : "text/troff"
          , ".me"    : "text/troff"
          , ".mid"   : "audio/midi"
          , ".midi"  : "audio/midi"
          , ".mime"  : "message/rfc822"
          , ".mml"   : "application/mathml+xml"
          , ".mng"   : "video/x-mng"
          , ".mov"   : "video/quicktime"
          , ".mp3"   : "audio/mpeg"
          , ".mp4"   : "video/mp4"
          , ".mp4v"  : "video/mp4"
          , ".mpeg"  : "video/mpeg"
          , ".mpg"   : "video/mpeg"
          , ".ms"    : "text/troff"
          , ".msi"   : "application/x-msdownload"
          , ".odp"   : "application/vnd.oasis.opendocument.presentation"
          , ".ods"   : "application/vnd.oasis.opendocument.spreadsheet"
          , ".odt"   : "application/vnd.oasis.opendocument.text"
          , ".ogg"   : "application/ogg"
          , ".p"     : "text/x-pascal"
          , ".pas"   : "text/x-pascal"
          , ".pbm"   : "image/x-portable-bitmap"
          , ".pdf"   : "application/pdf"
          , ".pem"   : "application/x-x509-ca-cert"
          , ".pgm"   : "image/x-portable-graymap"
          , ".pgp"   : "application/pgp-encrypted"
          , ".pkg"   : "application/octet-stream"
          , ".pl"    : "text/x-script.perl"
          , ".pm"    : "text/x-script.perl-module"
          , ".png"   : "image/png"
          , ".pnm"   : "image/x-portable-anymap"
          , ".ppm"   : "image/x-portable-pixmap"
          , ".pps"   : "application/vnd.ms-powerpoint"
          , ".ppt"   : "application/vnd.ms-powerpoint"
          , ".ps"    : "application/postscript"
          , ".psd"   : "image/vnd.adobe.photoshop"
          , ".py"    : "text/x-script.python"
          , ".qt"    : "video/quicktime"
          , ".ra"    : "audio/x-pn-realaudio"
          , ".rake"  : "text/x-script.ruby"
          , ".ram"   : "audio/x-pn-realaudio"
          , ".rar"   : "application/x-rar-compressed"
          , ".rb"    : "text/x-script.ruby"
          , ".rdf"   : "application/rdf+xml"
          , ".roff"  : "text/troff"
          , ".rpm"   : "application/x-redhat-package-manager"
          , ".rss"   : "application/rss+xml"
          , ".rtf"   : "application/rtf"
          , ".ru"    : "text/x-script.ruby"
          , ".s"     : "text/x-asm"
          , ".sgm"   : "text/sgml"
          , ".sgml"  : "text/sgml"
          , ".sh"    : "application/x-sh"
          , ".sig"   : "application/pgp-signature"
          , ".snd"   : "audio/basic"
          , ".so"    : "application/octet-stream"
          , ".svg"   : "image/svg+xml"
          , ".svgz"  : "image/svg+xml"
          , ".swf"   : "application/x-shockwave-flash"
          , ".t"     : "text/troff"
          , ".tar"   : "application/x-tar"
          , ".tbz"   : "application/x-bzip-compressed-tar"
          , ".tcl"   : "application/x-tcl"
          , ".tex"   : "application/x-tex"
          , ".texi"  : "application/x-texinfo"
          , ".texinfo" : "application/x-texinfo"
          , ".text"  : "text/plain"
          , ".tif"   : "image/tiff"
          , ".tiff"  : "image/tiff"
          , ".torrent" : "application/x-bittorrent"
          , ".tr"    : "text/troff"
          , ".txt"   : "text/plain"
          , ".vcf"   : "text/x-vcard"
          , ".vcs"   : "text/x-vcalendar"
          , ".vrml"  : "model/vrml"
          , ".war"   : "application/java-archive"
          , ".wav"   : "audio/x-wav"
          , ".wma"   : "audio/x-ms-wma"
          , ".wmv"   : "video/x-ms-wmv"
          , ".wmx"   : "video/x-ms-wmx"
          , ".wrl"   : "model/vrml"
          , ".wsdl"  : "application/wsdl+xml"
          , ".xbm"   : "image/x-xbitmap"
          , ".xhtml"   : "application/xhtml+xml"
          , ".xls"   : "application/vnd.ms-excel"
          , ".xml"   : "application/xml"
          , ".xpm"   : "image/x-xpixmap"
          , ".xsl"   : "application/xml"
          , ".xslt"  : "application/xslt+xml"
          , ".yaml"  : "text/yaml"
          , ".yml"   : "text/yaml"
          , ".zip"   : "application/zip"
          }
};
<|endoftext|>


<commit_before>/**
 * @date 2015-01-06
 * @author jialin.hou@raidtalk.com
 */
;(function (window, document, undefined) {
  var gg = {};
  gg.$ = function (selector, element) {
    if (!element) {
      element = document;
    }

    try {
      return element.querySelector(selector);
    } catch (e) {

    }
  };

  gg.$$ = function (selector, element) {
    if (!element) {
      element = document;
    }

    try {
      return element.querySelectorAll(selector);
    } catch (e) {

    }
  };

  gg.id = function (selector, element) {
    if (!element) {
      element = document;
    }

    return element.getElementById(selector);
  };

  window.gg = gg;
})(window, document);<commit_msg>update<commit_after>/**
 * @date 2015-01-06
 * @author jialin.hou@raidtalk.com
 */
;(function (window, document, undefined) {
  var gg = {};
  gg.$ = function (selector, element) {
    if (!element) {
      element = document;
    }

    try {
      return element.querySelector(selector);
    } catch (e) {

    }
  };

  gg.$$ = function (selector, element) {
    if (!element) {
      element = document;
    }

    try {
      return element.querySelectorAll(selector);
    } catch (e) {

    }
  };

  gg.id = function (selector, element) {
    if (!element) {
      element = document;
    }

    return element.getElementById(selector);
  };

  gg.getChildren = function (selector, element) {
    var parent = this.$(selector, element);
    return parent.childNodes;
  };

  /**
   * DOM
   */
  gg.dom = gg.dom || {};
  gg.dom.isElement = function (element) {
    return element && element.nodeType === Node.ELEMENT_NODE;
  }

  gg.dom.firstChild = function (element) {
    return isElement(element) ? element.firstChild : null;
  }

  /**
   * tools (include extend grammer)
   * @type {[type]}
   */
  gg.util = gg.util || {};
  gg.util.isArray = function (obj) {
    return Object.protype.toString.call(obj) === '[Object Array]';
  };

  gg.util.makeArray = function (obj) {
    return Array.prototype.slice.call(obj);
  }

  gg.util.trim = function (string) {
    return string.replace(/^\s|\s$/g, '');
  };

  gg.util.extend = function () {

  };

  window.gg = gg;
})(window, document);<|endoftext|>


<commit_before>#!/usr/bin/env node

// requires
var forge = require('node-forge');
var fs    = require("fs");

// init
var sshpubkey = {};
var pubkey;

// process command line arguments : pubkeyFile
var argv       = process.argv;
var pubkeyfile = argv[2];

// get pubkeyfile
var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
if (!pubkeyfile) {
  pubkeyfile = home + '/.ssh/id_rsa.pub';
}
console.log('getting public key from : ' + pubkeyfile);
try {
  pubkey = fs.readFileSync(pubkeyfile, "utf8");
} catch(e) {
  console.log('could not load : ' + pubkeyfile);
  console.log(e);
  process.exit(-1);
}

// get prefix
try {
  var arr = pubkey.toString().split(' ');
  if (arr.length < 2) {
    throw new Error("Malformed key split length " + arr.length);
  }
  sshpubkey.prefix = arr[0];
  sshpubkey.mainkey = arr[1];
} catch(e) {
  console.log('could not parse key : ' + pubkey);
  console.log(e);
  process.exit(-1);
}

sshpubkey.keybytes = forge.util.decode64(sshpubkey.mainkey);
sshpubkey.keyhex = forge.util.bytesToHex(sshpubkey.keybytes);

sshpubkey.byteslen = 4;

// type
//
//
sshpubkey.typelenstart = 0;
sshpubkey.typelenend = sshpubkey.typelenstart + sshpubkey.byteslen;
sshpubkey.typelenbytes = sshpubkey.keybytes.slice(sshpubkey.typelenstart, sshpubkey.typelenend);
sshpubkey.typelen = sshpubkey.typelenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.typestart = sshpubkey.typelenend;
sshpubkey.typeend = sshpubkey.typestart + sshpubkey.typelen;
sshpubkey.typebytes = sshpubkey.keybytes.slice(sshpubkey.typestart, sshpubkey.typeend);

// exponent
//
//
sshpubkey.exponentlenstart = sshpubkey.typeend;
sshpubkey.exponentlenend = sshpubkey.exponentlenstart + sshpubkey.byteslen;
sshpubkey.exponentlenbytes = sshpubkey.keybytes.slice(sshpubkey.exponentlenstart, sshpubkey.exponentlenend);
sshpubkey.exponentlen = sshpubkey.exponentlenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.exponentstart = sshpubkey.exponentlenend;
sshpubkey.exponentend = sshpubkey.exponentstart + sshpubkey.exponentlen;
sshpubkey.exponentbytes = sshpubkey.keybytes.slice(sshpubkey.exponentstart, sshpubkey.exponentend);

// modulus
//
//
sshpubkey.moduluslenstart = sshpubkey.exponentend;
sshpubkey.moduluslenend = sshpubkey.moduluslenstart + sshpubkey.byteslen;
sshpubkey.moduluslenbytes = sshpubkey.keybytes.slice(sshpubkey.moduluslenstart, sshpubkey.moduluslenend);
sshpubkey.moduluslen = 256*sshpubkey.moduluslenbytes.charCodeAt(sshpubkey.byteslen-2) + sshpubkey.moduluslenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.modulusstart = sshpubkey.moduluslenend;
sshpubkey.modulusend = sshpubkey.modulusstart + sshpubkey.moduluslen;
sshpubkey.modulusbytes = sshpubkey.keybytes.slice(sshpubkey.modulusstart, sshpubkey.modulusend);

console.log(parseInt(forge.util.bytesToHex(sshpubkey.exponentbytes), 16));
console.log(forge.util.bytesToHex(sshpubkey.modulusbytes));
<commit_msg>catch errors getting key hex<commit_after>#!/usr/bin/env node

// requires
var forge = require('node-forge');
var fs    = require("fs");

// init
var sshpubkey = {};
var pubkey;

// process command line arguments : pubkeyFile
var argv       = process.argv;
var pubkeyfile = argv[2];

// get pubkeyfile
var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
if (!pubkeyfile) {
  pubkeyfile = home + '/.ssh/id_rsa.pub';
}
console.log('getting public key from : ' + pubkeyfile);
try {
  pubkey = fs.readFileSync(pubkeyfile, "utf8");
} catch(e) {
  console.log('could not load : ' + pubkeyfile);
  console.log(e);
  process.exit(-1);
}

// get prefix
try {
  var arr = pubkey.toString().split(' ');
  if (arr.length < 2) {
    throw new Error("Malformed key split length " + arr.length);
  }
  sshpubkey.prefix = arr[0];
  sshpubkey.mainkey = arr[1];
} catch(e) {
  console.log('could not parse key : ' + pubkey);
  console.log(e);
  process.exit(-1);
}

// get key bytes
try {
  sshpubkey.byteslen = 4;
  sshpubkey.keybytes = forge.util.decode64(sshpubkey.mainkey);
  sshpubkey.keyhex = forge.util.bytesToHex(sshpubkey.keybytes);
} catch(e) {
  console.log('could not get key hex : ' + pubkey);
  console.log(e);
  process.exit(-1);
}

// type
//
//
sshpubkey.typelenstart = 0;
sshpubkey.typelenend = sshpubkey.typelenstart + sshpubkey.byteslen;
sshpubkey.typelenbytes = sshpubkey.keybytes.slice(sshpubkey.typelenstart, sshpubkey.typelenend);
sshpubkey.typelen = sshpubkey.typelenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.typestart = sshpubkey.typelenend;
sshpubkey.typeend = sshpubkey.typestart + sshpubkey.typelen;
sshpubkey.typebytes = sshpubkey.keybytes.slice(sshpubkey.typestart, sshpubkey.typeend);

// exponent
//
//
sshpubkey.exponentlenstart = sshpubkey.typeend;
sshpubkey.exponentlenend = sshpubkey.exponentlenstart + sshpubkey.byteslen;
sshpubkey.exponentlenbytes = sshpubkey.keybytes.slice(sshpubkey.exponentlenstart, sshpubkey.exponentlenend);
sshpubkey.exponentlen = sshpubkey.exponentlenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.exponentstart = sshpubkey.exponentlenend;
sshpubkey.exponentend = sshpubkey.exponentstart + sshpubkey.exponentlen;
sshpubkey.exponentbytes = sshpubkey.keybytes.slice(sshpubkey.exponentstart, sshpubkey.exponentend);

// modulus
//
//
sshpubkey.moduluslenstart = sshpubkey.exponentend;
sshpubkey.moduluslenend = sshpubkey.moduluslenstart + sshpubkey.byteslen;
sshpubkey.moduluslenbytes = sshpubkey.keybytes.slice(sshpubkey.moduluslenstart, sshpubkey.moduluslenend);
sshpubkey.moduluslen = 256*sshpubkey.moduluslenbytes.charCodeAt(sshpubkey.byteslen-2) + sshpubkey.moduluslenbytes.charCodeAt(sshpubkey.byteslen-1);

sshpubkey.modulusstart = sshpubkey.moduluslenend;
sshpubkey.modulusend = sshpubkey.modulusstart + sshpubkey.moduluslen;
sshpubkey.modulusbytes = sshpubkey.keybytes.slice(sshpubkey.modulusstart, sshpubkey.modulusend);

console.log(parseInt(forge.util.bytesToHex(sshpubkey.exponentbytes), 16));
console.log(forge.util.bytesToHex(sshpubkey.modulusbytes));
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var inherits = require('util').inherits;

var TChannelPeersBase = require('./peers_base.js');
var PeerHeap = require('./peer_heap.js');

function TChannelSubPeers(channel, options) {
    if (!(this instanceof TChannelSubPeers)) {
        return new TChannelSubPeers(channel, options);
    }
    var self = this;
    TChannelPeersBase.call(self, channel, options);

    self.peerScoreThreshold = self.options.peerScoreThreshold || 0;
    self._heap = new PeerHeap();
    self.choosePeerWithHeap = channel.choosePeerWithHeap;
}

inherits(TChannelSubPeers, TChannelPeersBase);

TChannelSubPeers.prototype.close = function close(callback) {
    var self = this;

    var peers = self.values();
    TChannelPeersBase.prototype.close.call(self, peers, callback);
};

TChannelSubPeers.prototype.add = function add(hostPort, options) {
    /* eslint max-statements: [2, 25]*/
    var self = this;

    var peer = self._map[hostPort];
    if (peer) {
        return peer;
    }

    var topChannel = self.channel.topChannel;

    if (hostPort === topChannel.hostPort) {
        return topChannel.peers.getSelfPeer();
    }

    peer = topChannel.peers.add(hostPort, options);

    self._map[hostPort] = peer;
    self._keys.push(hostPort);

    var el = self._heap.add(peer);
    peer.heapElements.push(el);

    return peer;
};

TChannelSubPeers.prototype.clear = function clear() {
    var self = this;

    self._map = Object.create(null);
    self._keys = [];
    self._heap.clear();
};

TChannelSubPeers.prototype._delete = function _del(peer) {
    var self = this;

    delete self._map[peer.hostPort];
    var index = self._keys.indexOf(peer.hostPort);
    popout(self._keys, index);

    for (var i = 0; i < peer.heapElements.length; i++) {
        var el = peer.heapElements[i];
        if (el.heap === self._heap) {
            el.heap.remove(el.index);
            popout(peer.heapElements, i);
            break;
        }
    }
};

TChannelSubPeers.prototype.choosePeer = function choosePeer(req) {
    var self = this;

    if (self.choosePeerWithHeap) {
        return self.chooseHeapPeer(req);
    }

    return self.chooseLinearPeer(req);
};

TChannelSubPeers.prototype.chooseLinearPeer = function chooseLinearPeer(req) {
    /* eslint complexity: [2, 15]*/
    var self = this;

    var hosts = self._keys;
    if (!hosts || !hosts.length) {
        return null;
    }

    var threshold = self.peerScoreThreshold;

    var selectedPeer = null;
    var selectedScore = 0;
    for (var i = 0; i < hosts.length; i++) {
        var hostPort = hosts[i];
        var peer = self._map[hostPort];
        if (!req || !req.triedRemoteAddrs || !req.triedRemoteAddrs[hostPort]) {
            var score = peer.handler.getScore(req);
            var want = score > threshold &&
                       (selectedPeer === null || score > selectedScore);
            if (want) {
                selectedPeer = peer;
                selectedScore = score;
            }
        }
    }

    return selectedPeer;
};

TChannelSubPeers.prototype.chooseHeapPeer = function chooseHeapPeer(req) {
    var self = this;

    if (req && req.triedRemoteAddrs) {
        return self._choosePeerSkipTried(req);
    }

    return self._heap.choose(self.peerScoreThreshold);
};

TChannelSubPeers.prototype._choosePeerSkipTried =
function _choosePeerSkipTried(req) {
    var self = this;

    return self._heap.choose(self.peerScoreThreshold, filterTriedPeers);

    function filterTriedPeers(peer) {
        return !req.triedRemoteAddrs[peer.hostPort];
    }
};

function popout(array, i) {
    if (!array.length) {
        return;
    }

    var j = array.length - 1;
    if (i !== j) {
        var tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    array.pop();
}

module.exports = TChannelSubPeers;
<commit_msg>sub_peers: do not delete non-existant peers<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var inherits = require('util').inherits;

var TChannelPeersBase = require('./peers_base.js');
var PeerHeap = require('./peer_heap.js');

function TChannelSubPeers(channel, options) {
    if (!(this instanceof TChannelSubPeers)) {
        return new TChannelSubPeers(channel, options);
    }
    var self = this;
    TChannelPeersBase.call(self, channel, options);

    self.peerScoreThreshold = self.options.peerScoreThreshold || 0;
    self._heap = new PeerHeap();
    self.choosePeerWithHeap = channel.choosePeerWithHeap;
}

inherits(TChannelSubPeers, TChannelPeersBase);

TChannelSubPeers.prototype.close = function close(callback) {
    var self = this;

    var peers = self.values();
    TChannelPeersBase.prototype.close.call(self, peers, callback);
};

TChannelSubPeers.prototype.add = function add(hostPort, options) {
    /* eslint max-statements: [2, 25]*/
    var self = this;

    var peer = self._map[hostPort];
    if (peer) {
        return peer;
    }

    var topChannel = self.channel.topChannel;

    if (hostPort === topChannel.hostPort) {
        return topChannel.peers.getSelfPeer();
    }

    peer = topChannel.peers.add(hostPort, options);

    self._map[hostPort] = peer;
    self._keys.push(hostPort);

    var el = self._heap.add(peer);
    peer.heapElements.push(el);

    return peer;
};

TChannelSubPeers.prototype.clear = function clear() {
    var self = this;

    self._map = Object.create(null);
    self._keys = [];
    self._heap.clear();
};

TChannelSubPeers.prototype._delete = function _del(peer) {
    var self = this;

    var index = self._keys.indexOf(peer.hostPort);
    if (index === -1) {
        return;
    }

    delete self._map[peer.hostPort];
    popout(self._keys, index);

    for (var i = 0; i < peer.heapElements.length; i++) {
        var el = peer.heapElements[i];
        if (el.heap === self._heap) {
            el.heap.remove(el.index);
            popout(peer.heapElements, i);
            break;
        }
    }
};

TChannelSubPeers.prototype.choosePeer = function choosePeer(req) {
    var self = this;

    if (self.choosePeerWithHeap) {
        return self.chooseHeapPeer(req);
    }

    return self.chooseLinearPeer(req);
};

TChannelSubPeers.prototype.chooseLinearPeer = function chooseLinearPeer(req) {
    /* eslint complexity: [2, 15]*/
    var self = this;

    var hosts = self._keys;
    if (!hosts || !hosts.length) {
        return null;
    }

    var threshold = self.peerScoreThreshold;

    var selectedPeer = null;
    var selectedScore = 0;
    for (var i = 0; i < hosts.length; i++) {
        var hostPort = hosts[i];
        var peer = self._map[hostPort];
        if (!req || !req.triedRemoteAddrs || !req.triedRemoteAddrs[hostPort]) {
            var score = peer.handler.getScore(req);
            var want = score > threshold &&
                       (selectedPeer === null || score > selectedScore);
            if (want) {
                selectedPeer = peer;
                selectedScore = score;
            }
        }
    }

    return selectedPeer;
};

TChannelSubPeers.prototype.chooseHeapPeer = function chooseHeapPeer(req) {
    var self = this;

    if (req && req.triedRemoteAddrs) {
        return self._choosePeerSkipTried(req);
    }

    return self._heap.choose(self.peerScoreThreshold);
};

TChannelSubPeers.prototype._choosePeerSkipTried =
function _choosePeerSkipTried(req) {
    var self = this;

    return self._heap.choose(self.peerScoreThreshold, filterTriedPeers);

    function filterTriedPeers(peer) {
        return !req.triedRemoteAddrs[peer.hostPort];
    }
};

function popout(array, i) {
    if (!array.length) {
        return;
    }

    var j = array.length - 1;
    if (i !== j) {
        var tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    array.pop();
}

module.exports = TChannelSubPeers;
<|endoftext|>


<commit_before>/**
 * The 'id' function is essentially the "base class" for all Objective-C
 * objects that get passed around JS-land.
 */

var proto = exports.proto = Object.create(Function.prototype)
  , core  = require('./core')
  , types = require('./types')
  , SEL   = require('./sel')

/**
 * Wraps up a pointer that is expected to be a compatible Objective-C
 * object that can recieve messages.
 */
exports.wrap = function wrap (pointer) {

  // This 'id' function is syntax sugar around the msgSend function attached to
  // it. 'msgSend' is expecting the selector first, an Array of args second, so
  // this function just massages it into place and returns the result.
  function id () {
    var args = []
      , sel
    if (arguments.length === 1) {
      var arg = arguments[0]
      if (arg.constructor.name == 'String') {
        sel = arg
      } else {
        sel = []
        Object.keys(arg).forEach(function (s) {
          sel.push(s)
          args.push(arg[s])
        })
        sel.push('')
        sel = sel.join(':')
      }
    } else {
      sel = []
      var len = arguments.length
      for (var i=0; i<len; i+=2) {
        sel.push(arguments[i])
        args.push(arguments[i+1])
      }
      sel.push('')
      sel = sel.join(':')
    }
    return id.msgSend(sel, args)
  }

  // Save a reference to the pointer for use by the prototype functions
  id.pointer = pointer;
  // Morph into a MUTANT FUNCTION FREAK!!1!
  id.__proto__ = proto;
  return id;
}
// Avoid a circular dep.
core._idwrap = exports.wrap;

/**
 * A very important function that *does the message sending* between
 * Objective-C objects. When you do `array('addObject', anObject)`, this
 * `msgSend` function is the one that finally gets called to do the dirty work.
 *
 * This function accepts a String selector as the first argument, and an Array
 * of (wrapped) values that get passed to the the message. This function takes
 * care of unwrapping the passing in arguments an wrapping up the result value,
 * if necessary.
 *
 * If you wanted to monkey-patch *every* message that got sent out from an
 * object though NodObjC, this is the place to do it.
 */
proto.msgSend = function msgSend (sel, args) {
  var types = this._getTypes(sel)
    , argTypes = types[1]
    , msgSendFunc = core.get_objc_msgSend(types)
    , unwrappedArgs = core.unwrapValues([this, sel].concat(args), argTypes)
    , rtn = msgSendFunc.apply(null, unwrappedArgs)
  // Process the return value into a wrapped value if needed
  return core.wrapValue(rtn, types[0]);
}

/**
 * Accepts a SEL and queries the current object for the return type and
 * argument types for the given selector. If current object does not implment
 * that selector, then check the superclass, and repeat recursively until
 * a subclass that responds to the selector is found, or until the base class
 * is found (in which case the current obj does not respond to 'sel' and we
 * should throw an Error).
 */
proto._getTypes = function getTypes (sel) {
  var c = this.getClass()
    , t = c._getTypesClass(sel, this.isClass)
  if (!t) throw new Error('Object does not respond to selector: '+sel);
  return t;
}

/**
 * Retrieves the wrapped Class instance for this object.
 */
proto.getClass = function getClass () {
  return exports._wrapClass(this._getClassPointer());
}

/**
 * Returns the node-ffi pointer for the class of this object.
 */
proto._getClassPointer = function getClassPointer () {
  return core.object_getClass(this.pointer)
}

/**
 * Calls 'object_getClassName()' on this object.
 */
proto.getClassName = function () {
  return core.object_getClassName(this.pointer);
}

/**
 * Returns an Array of Strings of the names of methods that the current object
 * will respond to. This function can iterate through the object's superclasses
 * recursively, if you specify a 'maxDepth' number argument.
 */
proto.methods = function methods (maxDepth) {
  var numMethods = new core.Pointer(core.TYPE_SIZE_MAP.uint32)
    , rtn = []
    , classPointer = this._getClassPointer()
    , md = maxDepth || 1
    , depth = 0
  while (depth++ < md && !classPointer.isNull()) {
    var methods = core.class_copyMethodList(classPointer, numMethods)
      , p = methods
      , count = numMethods.getUInt32()
    for (var i=0; i<count; i++) {
      var cur = p.getPointer()
        , name = SEL.toString(core.method_getName(cur))
      if (!~rtn.indexOf(name)) {
        rtn.push(name)
      }
      p = p.seek(core.TYPE_SIZE_MAP.pointer)
    }
    core.free(methods)
    classPointer = core.class_getSuperclass(classPointer)
  }
  return rtn
}

/**
 * The id wrap's overidden toString() function proxies up to the id's
 * description method:  [[id description] UTF8String]
 */
proto.toString = function toString () {
  return this('description')('UTF8String');
}

proto.inspect = function inspect () {
  return this.toString()
}
<commit_msg>Sort the result of id#methods() alphabetically.<commit_after>/**
 * The 'id' function is essentially the "base class" for all Objective-C
 * objects that get passed around JS-land.
 */

var proto = exports.proto = Object.create(Function.prototype)
  , core  = require('./core')
  , types = require('./types')
  , SEL   = require('./sel')

/**
 * Wraps up a pointer that is expected to be a compatible Objective-C
 * object that can recieve messages.
 */
exports.wrap = function wrap (pointer) {

  // This 'id' function is syntax sugar around the msgSend function attached to
  // it. 'msgSend' is expecting the selector first, an Array of args second, so
  // this function just massages it into place and returns the result.
  function id () {
    var args = []
      , sel
    if (arguments.length === 1) {
      var arg = arguments[0]
      if (arg.constructor.name == 'String') {
        sel = arg
      } else {
        sel = []
        Object.keys(arg).forEach(function (s) {
          sel.push(s)
          args.push(arg[s])
        })
        sel.push('')
        sel = sel.join(':')
      }
    } else {
      sel = []
      var len = arguments.length
      for (var i=0; i<len; i+=2) {
        sel.push(arguments[i])
        args.push(arguments[i+1])
      }
      sel.push('')
      sel = sel.join(':')
    }
    return id.msgSend(sel, args)
  }

  // Save a reference to the pointer for use by the prototype functions
  id.pointer = pointer;
  // Morph into a MUTANT FUNCTION FREAK!!1!
  id.__proto__ = proto;
  return id;
}
// Avoid a circular dep.
core._idwrap = exports.wrap;

/**
 * A very important function that *does the message sending* between
 * Objective-C objects. When you do `array('addObject', anObject)`, this
 * `msgSend` function is the one that finally gets called to do the dirty work.
 *
 * This function accepts a String selector as the first argument, and an Array
 * of (wrapped) values that get passed to the the message. This function takes
 * care of unwrapping the passing in arguments an wrapping up the result value,
 * if necessary.
 *
 * If you wanted to monkey-patch *every* message that got sent out from an
 * object though NodObjC, this is the place to do it.
 */
proto.msgSend = function msgSend (sel, args) {
  var types = this._getTypes(sel)
    , argTypes = types[1]
    , msgSendFunc = core.get_objc_msgSend(types)
    , unwrappedArgs = core.unwrapValues([this, sel].concat(args), argTypes)
    , rtn = msgSendFunc.apply(null, unwrappedArgs)
  // Process the return value into a wrapped value if needed
  return core.wrapValue(rtn, types[0]);
}

/**
 * Accepts a SEL and queries the current object for the return type and
 * argument types for the given selector. If current object does not implment
 * that selector, then check the superclass, and repeat recursively until
 * a subclass that responds to the selector is found, or until the base class
 * is found (in which case the current obj does not respond to 'sel' and we
 * should throw an Error).
 */
proto._getTypes = function getTypes (sel) {
  var c = this.getClass()
    , t = c._getTypesClass(sel, this.isClass)
  if (!t) throw new Error('Object does not respond to selector: '+sel);
  return t;
}

/**
 * Retrieves the wrapped Class instance for this object.
 */
proto.getClass = function getClass () {
  return exports._wrapClass(this._getClassPointer());
}

/**
 * Returns the node-ffi pointer for the class of this object.
 */
proto._getClassPointer = function getClassPointer () {
  return core.object_getClass(this.pointer)
}

/**
 * Calls 'object_getClassName()' on this object.
 */
proto.getClassName = function () {
  return core.object_getClassName(this.pointer);
}

/**
 * Returns an Array of Strings of the names of methods that the current object
 * will respond to. This function can iterate through the object's superclasses
 * recursively, if you specify a 'maxDepth' number argument.
 */
proto.methods = function methods (maxDepth) {
  var numMethods = new core.Pointer(core.TYPE_SIZE_MAP.uint32)
    , rtn = []
    , classPointer = this._getClassPointer()
    , md = maxDepth || 1
    , depth = 0
  while (depth++ < md && !classPointer.isNull()) {
    var methods = core.class_copyMethodList(classPointer, numMethods)
      , p = methods
      , count = numMethods.getUInt32()
    for (var i=0; i<count; i++) {
      var cur = p.getPointer()
        , name = SEL.toString(core.method_getName(cur))
      if (!~rtn.indexOf(name)) {
        rtn.push(name)
      }
      p = p.seek(core.TYPE_SIZE_MAP.pointer)
    }
    core.free(methods)
    classPointer = core.class_getSuperclass(classPointer)
  }
  return rtn.sort()
}

/**
 * The id wrap's overidden toString() function proxies up to the id's
 * description method:  [[id description] UTF8String]
 */
proto.toString = function toString () {
  return this('description')('UTF8String');
}

proto.inspect = function inspect () {
  return this.toString()
}
<|endoftext|>


<commit_before>/**
 * RUBY.js
 * enabling ruby-style programming in JavaScript
 * */
(function() {
	window.rb=rb||{};
	function valur(n){
		var a=function(){
			return n;
		};
		a.elsif=a.else=function(){};
		a.valueOf=function(){
			return n.valueOf();
		};
		return a;
	}
	function choiser(){
		this.elsif=function(bool){
			return rb.if(bool);
		};
		this.else=function(fn){
			return fn();
		}
	}
	function ifer(fn){
		return valur(fn());
	}
	function elser(fn){
		return new choiser();
	}
	rb.if=function(bool){
		if(bool){
			return ifer;
		}else{
			return elser;
		}
	}
})();
<commit_msg>Unstandard bug fixed.<commit_after>/**
 * RUBY.js
 * enabling ruby-style programming in JavaScript
 * */
(function() {
	window.rb={};
	function c(e){
		if(typeof e==="function"){
			return e();
		}else{
			return eval(e);
		}
	}
	function valur(n){
		var a=function(){
			return n;
		};
		a.elsif=a.else=function(){
			return this;
		};
		a.valueOf=function(){
			return n.valueOf();
		};
		a.end=n;
		return a;
	}
	function choiser(){
		this.elsif=function(bool){
			return rb.if(bool);
		};
		this.else=function(fn){
			return new valur(c(fn));
		};
	}
	function ifer(fn){
		return valur(c(fn));
	}
	function elser(fn){
		return new choiser();
	}
	rb.if=function(bool){
		if(bool){
			return ifer;
		}else{
			return elser;
		}
	};
})();
<|endoftext|>


<commit_before>var Issue = (function () {
	function Issue () {
		init.call(this);
	};

	function init (name, time, u) {
		this.name = name || '';
		this.time = time || null;
		this.uncertainty = u || null;
		this.issues = [];
		this.form = null;
	}

	var editFlag = false;

	Issue.prototype.showForm = function () {
		$.observable(this).setProperty('form', new Issue());
	};
	Issue.prototype.hideForm = function () {
		editFlag = false;
		$.observable(this).setProperty('form', null);
	};
	Issue.prototype.edit = function () {
		editFlag = true;
		var i = {
			name: this.name,
			time: this.time,
			uncertainty: this.uncertainty
		};
		$.observable(this).setProperty('form', i);
	};
	Issue.prototype.save = function () {
		if(editFlag){
			$.observable(this).setProperty('name',this.form.name);
			$.observable(this).setProperty('time',this.form.time);
			$.observable(this).setProperty('uncertainty',this.form.uncertainty);
		}else{
			$.observable(this.issues).insert(this.form);
		}
		this.hideForm();
	};
	Issue.prototype.read = function (obj) {
		init.call(this, obj.name, obj.time, obj.uncertainty);
		for(var i = 0, l = obj.issues.length; i < l; i++){
			var iss = new Issue();
			iss.read(obj.issues[i]);
			this.issues.push(iss);
		}
	};

	Issue.prototype.recalc = function () {
		if(this.issues.length == 0) return;
		var totalTime = 0;
		var totalUncert = 0;
		for(var i = 0, l = this.issues.length; i < l; i++){
			this.issues[i].recalc();
			totalTime += this.issues[i].time*1;
			totalUncert += this.issues[i].time * this.issues[i].uncertainty;
		}
		$.observable(this).setProperty('time', totalTime);
		$.observable(this).setProperty('uncertainty', totalUncert/totalTime);
	};

	Issue.prototype.truncate = function () {
		$.observable(this).setProperty('issues', []);
		$.observable(this).setProperty('time', 0);
		$.observable(this).setProperty('uncertainty', 0);
	};
	return Issue;
})();

var project = new Issue();
if(localStorage.getItem('project')){
	project.read(JSON.parse(localStorage.getItem('project')));
	project.recalc();
}

$(document).ready(function(){
	var listTmpl = $.templates('#listTmpl');
	var lineFormTmpl = $.templates('#lineFormTmpl');
	var totalTmpl = $.templates('#totalTmpl');

	listTmpl.link('#issues', project);
	totalTmpl.link('#total', project);

	$('#iss-add-line').click(function() {
		project.showForm();
	});
	$('#save').click(function () {
		localStorage.setItem('project', JSON.stringify(project));
	});
	$('#truncate').click(function () {
		if(confirm('Do you really want to truncate all saved data?')){
			localStorage.removeItem('project');
			project.truncate();
		}
	});

	$(document).on('click', '.iss-add', function () {
		$.view(this).data.showForm();
	});
	$(document).on('click', '.iss-add-new', function () {
		$.view(this).data.save();
		project.recalc();
	});
	$(document).on('click', '.iss-edit', function () {
		$.view(this).data.edit();
	});
	$(document).on('click', '.iss-esc', function () {
		$.view(this).data.hideForm();
	});
});
<commit_msg>implementation for 'remove' button<commit_after>var Issue = (function () {
	function Issue () {
		init.call(this);
	};

	function init (name, time, u) {
		this.name = name || '';
		this.time = time || null;
		this.uncertainty = u || null;
		this.issues = [];
		this.form = null;
	}

	function addIssue (issue, hidden) {
		issue.parent = this;
		if(hidden){
			this.issues.push(issue);
		}else{
			$.observable(this.issues).insert(issue);
		}
	}

	var editFlag = false;

	Issue.prototype.showForm = function () {
		$.observable(this).setProperty('form', new Issue());
	};

	Issue.prototype.hideForm = function () {
		editFlag = false;
		$.observable(this).setProperty('form', null);
	};

	Issue.prototype.edit = function () {
		editFlag = true;
		var i = {
			name: this.name,
			time: this.time,
			uncertainty: this.uncertainty
		};
		$.observable(this).setProperty('form', i);
	};

	Issue.prototype.save = function () {
		if(editFlag){
			$.observable(this).setProperty('name',this.form.name);
			$.observable(this).setProperty('time',this.form.time);
			$.observable(this).setProperty('uncertainty',this.form.uncertainty);
		}else{
			addIssue.call(this, this.form);
		}
		this.hideForm();
	};

	Issue.prototype.read = function (obj) {
		init.call(this, obj.name, obj.time, obj.uncertainty);
		for(var i = 0, l = obj.issues.length; i < l; i++){
			var iss = new Issue();
			iss.read(obj.issues[i]);
			addIssue.call(this, iss, true);
		}
	};

	Issue.prototype.recalc = function () {
		if(this.issues.length == 0) return;
		var totalTime = 0;
		var totalUncert = 0;
		for(var i = 0, l = this.issues.length; i < l; i++){
			this.issues[i].recalc();
			totalTime += this.issues[i].time*1;
			totalUncert += this.issues[i].time * this.issues[i].uncertainty;
		}
		$.observable(this).setProperty('time', totalTime);
		$.observable(this).setProperty('uncertainty', totalUncert/totalTime);
	};

	Issue.prototype.truncate = function () {
		$.observable(this).setProperty('issues', []);
		$.observable(this).setProperty('time', 0);
		$.observable(this).setProperty('uncertainty', 0);
	};

	Issue.prototype.remove = function () {
		for(var i = 0, l = this.parent.issues.length; i < l; i++){
			if (this.parent.issues[i] == this) {
				$.observable(this.parent.issues).remove(i);
			};
		}
	};

	return Issue;
})();

var project = new Issue();
if(localStorage.getItem('project')){
	project.read(JSON.parse(localStorage.getItem('project')));
	project.recalc();
}

$(document).ready(function(){
	var listTmpl = $.templates('#listTmpl');
	var lineFormTmpl = $.templates('#lineFormTmpl');
	var totalTmpl = $.templates('#totalTmpl');

	listTmpl.link('#issues', project);
	totalTmpl.link('#total', project);

	$('#iss-add-line').click(function() {
		project.showForm();
	});
	$('#save').click(function () {
		localStorage.setItem('project', JSON.stringify(project));
	});
	$('#truncate').click(function () {
		if(confirm('Do you really want to truncate all saved data?')){
			localStorage.removeItem('project');
			project.truncate();
		}
	});

	$(document).on('click', '.iss-add', function () {
		$.view(this).data.showForm();
	});
	$(document).on('click', '.iss-add-new', function () {
		$.view(this).data.save();
		project.recalc();
	});
	$(document).on('click', '.iss-edit', function () {
		$.view(this).data.edit();
	});
	$(document).on('click', '.iss-rm', function () {
		$.view(this).data.remove();
		project.recalc();
	});
	$(document).on('click', '.iss-esc', function () {
		$.view(this).data.hideForm();
	});
});
<|endoftext|>


<commit_before>function _(el) {return document.getElementById(el);}
function _q(el) {return document.querySelector(el);}
function _a(el) {return document.querySelectorAll(el);}
function _cr(el) {return document.createElement(''+el+'');}
function _rm(el) {el.parentNode.removeChild(el);}
function _ap(el,dest) {dest.appendChild(el);}
function _pp(el,dest) {dest.insertBefore(el,dest.firstChild);}
function _i(el,html) {el.innerHTML=html;}
function _e(el) {el.innerHTML='';}
function escapeHtml(s) { s=s.replace(/&/g,'&'); s=s.replace(/</g,'<'); s=s.replace(/>/g,'>'); s=s.replace(/"/g,'"'); s=s.replace(/'/g,'''); return s}
function notice(msg) { var nt=_cr('div'); _i(nt,msg); nt.className='notice'; _pp(nt,document.body); }
function clean() { [].forEach.call(_a('.notice'),function(e){_rm(e);}); }
<commit_msg>added _sa setAttribute<commit_after>function _(el){return document.getElementById(el);}
function _q(el){return document.querySelector(el);}
function _a(el){return document.querySelectorAll(el);}
function _cr(el){return document.createElement(''+el+'');}
function _rm(el){el.parentNode.removeChild(el);}
function _ap(el,dest){dest.appendChild(el);}
function _pp(el,dest){dest.insertBefore(el,dest.firstChild);}
function _i(el,html){el.innerHTML=html;}
function _e(el){el.innerHTML='';}
function _sa(el,at,v){el.setAttribute(at,v);}
function escapeHtml(s) { s=s.replace(/&/g,'&'); s=s.replace(/</g,'<'); s=s.replace(/>/g,'>'); s=s.replace(/"/g,'"'); s=s.replace(/'/g,'''); return s}
function notice(msg) { var nt=_cr('div'); _i(nt,msg); nt.className='notice'; _pp(nt,document.body); }
function clean() { [].forEach.call(_a('.notice'),function(e){_rm(e);}); }
<|endoftext|>


<commit_before>/**
 * マルチポストモジュール
 *
 * 外部サービスへ投稿する
 */

/**
 * 設定
 */
var config = require('./config.json').twitter;

/**
 * モジュール
 */
//npm : Node Package Manager
var twitter = require('twitter');

/**
 * 関数定義
 */

//投稿
function post(body,tags,user,callback){

	var tagstring = '';
	if(tags.length > 0){
		tagstring = ' #' + tags.join(" #")
	}

	var params = {
		status: body + tagstring,
		include_entities: 1
	};

	var twitest = new twitter(config[user]);
	twitest.post('/statuses/update.json', params, function (err,res) {
		if (err) {
			//DEBUG あとで消す
			console.log({tweet_respons:'**********errrrrrrrrrr***************',
				err:err,
				res:res,
			});
		} else {
			//DEBUG あとで消す
			console.log({tweet_respons:'*************************',
				res:res,
			});
		}
	});
}

/**
 * エクスポート
 */
module.exports = {
	post : post
}
<commit_msg>Twitterの同内容投稿制限が厳しいので一回は.つけて再投稿してみる仮実装<commit_after>/**
 * マルチポストモジュール
 *
 * 外部サービスへ投稿する
 */

/**
 * 設定
 */
var config = require('./config.json').twitter;

/**
 * モジュール
 */
//npm : Node Package Manager
var twitter = require('twitter');

/**
 * 関数定義
 */

//投稿
function post(body,tags,user,callback){

	var tagstring = '';
	if(tags.length > 0){
		tagstring = ' #' + tags.join(" #")
	}

	var params = {
		status: body + tagstring,
		include_entities: 1
	};

	var twitest = new twitter(config[user]);
	twitest.post('/statuses/update.json', params, function (err,res) {
		if (err) {
			//PENDING 重複投稿をどうにか
			if (err.code = 187){
				params.status += '.'
				twitest.post('/statuses/update.json', params, function (err,res) {
					console.log({tweet_respons:'*************************',
						res:res,
					});
				});
			} else {
				//DEBUG あとで消す
				console.log({tweet_respons:'**********errrrrrrrrrr***************',
					err:err,
					res:res,
				});
			}
		} else {
			//DEBUG あとで消す
			console.log({tweet_respons:'*************************',
				res:res,
			});
		}
	});
}

/**
 * エクスポート
 */
module.exports = {
	post : post
}
<|endoftext|>


<commit_before>this.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll(
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      );
    })
  );
});

this.addEventListener('fetch', function(event) {
  var cachedResponse = caches.match(event.request).catch(function() {
    return fetch(event.request).then(function(response) {
      return caches.open('v1').then(function(cache) {
        cache.put(event.request, response.clone());
        return response;
      });
    });
  }).catch(function() {
    return caches.match('/sw-test/gallery/myLittleVader.jpg');
  });

  event.respondWith(cachedResponse);
});

<commit_msg>replacing SW caching logic with a better propsal, as suggested by Ben Kelly<commit_after>this.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll(
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      );
    })
  );
});

var response;
var cachedResponse = caches.match(event.request).catch(function() {
  return fetch(event.request);
}).then(function(r) {
  response = r;
  caches.open('v1').then(function(cache) {
    cache.put(event.request, response);
  });
  return response.clone();
}).catch(function() {
  return caches.match('/sw-test/gallery/myLittleVader.jpg');
});<|endoftext|>


<commit_before>// This should be called once per download
// Each event has a dataChannel that the data will be piped throught
self.onmessage = event => {
    // Create a uniq link for the download
    let uniqLink = 'intercept-me-nr' + Math.random()

    let p = new Promise((resolve, reject) => {
        let stream = createStream(resolve, reject, event.ports[0])
        hijacke(uniqLink, stream, event.data)
    })

	// Tell the middle man to open the link to kick start the stream download
	clients.matchAll({includeUncontrolled: true, type: 'window'}).then(clients => {
		clients[0].postMessage({
	        href: uniqLink
	    })
	})

	return

    // Beginning in Chrome 51, event is an ExtendableMessageEvent, which supports
    // the waitUntil() method for extending the lifetime of the event handler
    // until the promise is resolved.
    if ('waitUntil' in event) {
        event.waitUntil(p)
    }

    // Without support for waitUntil(), there's a chance that if the promise chain
    // takes "too long" to execute, the service worker might be automatically
    // stopped before it's complete.
}

function createStream(resolve, reject, port){
    // ReadableStream is only supported by chrome 52, but can be enabled
    // with a flag chrome://flags/#enable-experimental-web-platform-features
    return new ReadableStream({
		start(controller) {
			port.postMessage("ready")
			// When we recive data on the messageChannel, we write
			port.onmessage = event => {
				// We finaly have a abortable stream =D
				if(event.data === 'end')
					return controller.close()

				controller.enqueue(event.data)
			}
		},
		cancel() {
			console.log("user aborted")
		}
	})
}

function hijacke(uniqLink, stream, filename){
	let listener

    self.addEventListener('fetch', listener = event => {
        if(!event.request.url.includes(uniqLink))
    		return

        self.removeEventListener('fetch', listener)

    	let res = new Response(stream, {
    		headers: {
                'Content-Disposition': 'attachment; filename=' + filename
    		}
    	})

    	event.respondWith(res)
    })
}
<commit_msg>broadcast<commit_after>// This should be called once per download
// Each event has a dataChannel that the data will be piped throught
self.onmessage = event => {
    // Create a uniq link for the download
    let uniqLink = 'intercept-me-nr' + Math.random()

    let p = new Promise((resolve, reject) => {
        let stream = createStream(resolve, reject, event.ports[0])
        hijacke(uniqLink, stream, event.data)
    })

	// Tell the middle man to open the link to kick start the stream download
	clients.matchAll({includeUncontrolled: true, type: 'window'}).then(clients => {
		// Would hope that we don't have to broadcast to all sites
		// just only the page that opened it would be enough?
		//
		// Had problem when only using the first in the list
		for(let client of clients){
			client.postMessage({
				href: uniqLink
			})
		}
	})

	return

    // Beginning in Chrome 51, event is an ExtendableMessageEvent, which supports
    // the waitUntil() method for extending the lifetime of the event handler
    // until the promise is resolved.
    if ('waitUntil' in event) {
        event.waitUntil(p)
    }

    // Without support for waitUntil(), there's a chance that if the promise chain
    // takes "too long" to execute, the service worker might be automatically
    // stopped before it's complete.
}

function createStream(resolve, reject, port){
    // ReadableStream is only supported by chrome 52, but can be enabled
    // with a flag chrome://flags/#enable-experimental-web-platform-features
    return new ReadableStream({
		start(controller) {
			port.postMessage("ready")
			// When we recive data on the messageChannel, we write
			port.onmessage = event => {
				// We finaly have a abortable stream =D
				if(event.data === 'end')
					return controller.close()

				controller.enqueue(event.data)
			}
		},
		cancel() {
			console.log("user aborted")
		}
	})
}

function hijacke(uniqLink, stream, filename){
	let listener

    self.addEventListener('fetch', listener = event => {
        if(!event.request.url.includes(uniqLink))
    		return

        self.removeEventListener('fetch', listener)

    	let res = new Response(stream, {
    		headers: {
                'Content-Disposition': 'attachment; filename=' + filename
    		}
    	})

    	event.respondWith(res)
    })
}
<|endoftext|>


<commit_before>self.addEventListener('install', function(event) {
    event.waitUntil(
      caches.open('v1').then(function(cache) {
        return cache.addAll([
          '/',
          '/index.html',
          '/css/style.css',
          '/css/images/',
          '/css/images/bg.jpg'
        ]);
      })
    );
  });

  <commit_msg>updated the sw<commit_after>self.addEventListener('install', function(event) {
    event.waitUntil(
      caches.open('v1').then(function(cache) {
        return cache.addAll([
          '/',
          '/index.html',
          '/css/style.css',
          '/css/images/bg.jpg'
        ]);
      })
    );
  });

<|endoftext|>