<commit_before>/**
 * ModulesListItem component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import classnames from 'classnames';

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Link from './Link';
import ModuleIcon from './ModuleIcon';
import ModuleSettingsWarning from './legacy-notifications/module-settings-warning';
import Data from 'googlesitekit-data';
import { CORE_MODULES } from '../googlesitekit/modules/datastore/constants';
const { useSelect } = Data;

const ModulesListItem = ( { module, handleSetupModule } ) => {
	const { slug, name, connected, active } = module;
	const setupComplete = connected && active;

	const canActivateModule = useSelect( ( select ) =>
		select( CORE_MODULES ).canActivateModule( slug )
	);

	return (
		<div
			className={ classnames(
				'googlesitekit-modules-list__module',
				`googlesitekit-modules-list__module--${ slug }`,
				{
					'googlesitekit-settings-connect-module--disabled': ! canActivateModule,
				}
			) }
		>

					<ModuleIcon slug={ slug } />

					{ name }

			<ModuleSettingsWarning slug={ slug } context="modules-list" />
			{ setupComplete && (

					{ __( 'Connected', 'google-site-kit' ) }

			) }
			{ ! setupComplete && (
				<Link
					onClick={ () => handleSetupModule( slug ) }
					arrow
					small
					inherit
					disabled={ ! canActivateModule }
				>
					{ __( 'Connect Service', 'google-site-kit' ) }
				</Link>
			) }

	);
};

export default ModulesListItem;
<commit_msg>Add a few blank lines between for readability.<commit_after>/**
 * ModulesListItem component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import classnames from 'classnames';

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Link from './Link';
import ModuleIcon from './ModuleIcon';
import ModuleSettingsWarning from './legacy-notifications/module-settings-warning';
import Data from 'googlesitekit-data';
import { CORE_MODULES } from '../googlesitekit/modules/datastore/constants';
const { useSelect } = Data;

const ModulesListItem = ( { module, handleSetupModule } ) => {
	const { slug, name, connected, active } = module;
	const setupComplete = connected && active;

	const canActivateModule = useSelect( ( select ) =>
		select( CORE_MODULES ).canActivateModule( slug )
	);

	return (
		<div
			className={ classnames(
				'googlesitekit-modules-list__module',
				`googlesitekit-modules-list__module--${ slug }`,
				{
					'googlesitekit-settings-connect-module--disabled': ! canActivateModule,
				}
			) }
		>

					<ModuleIcon slug={ slug } />

					{ name }

			<ModuleSettingsWarning slug={ slug } context="modules-list" />

			{ setupComplete && (

					{ __( 'Connected', 'google-site-kit' ) }

			) }

			{ ! setupComplete && (
				<Link
					onClick={ () => handleSetupModule( slug ) }
					arrow
					small
					inherit
					disabled={ ! canActivateModule }
				>
					{ __( 'Connect Service', 'google-site-kit' ) }
				</Link>
			) }

	);
};

export default ModulesListItem;
<|endoftext|>


<commit_before>'use strict';
var _;

var Parser = {
  getRGB: function(canvas, url){
    var img = new Image();
    var context = canvas.getContext('2d');
    var result = new Promise(function(resolve, reject){
      img.onload=function(){
        canvas.width = img.width;
        canvas.height = img.height;
        context.drawImage(img,0,0);
        resolve(context.getImageData(0,0,canvas.width,canvas.height));
      };
    });

    img.src = url;
    return result;
  }
};

var Grid = {
  generate: function(options) {
    //try an adjacency matrix for this for quick scanning
    var grid = {};
    grid.rows = [];
    grid.size = options.height*options.width;
    grid.width = options.width;
    grid.height = options.height;
    for(var i=0;i<grid.size;i++){
      grid.rows[i] = new Array(grid.size);
    }
    return grid;
  },
  findNextPoint: function(origin, grid, pixels, color, thickness){
    var next = Grid.helpers.selectNext(origin, grid, color);
    console.log("next: " + next);
    if (next === false) return Grid.helpers.getLast(origin);
    var pixelLine = Grid.helpers.getPixels(origin, next, grid, pixels, color);
    //check if it is feasible(if not, restart)
    //if restart more than 10 times, choose another path
    //else, decrement the value of all the arrays
    //return the next node
    console.log(pixelLine);
    return "nextPt"
  },
  helpers: {
    getRandom: function(grid){
      return Math.floor(Math.random()*grid.size);
    },
    checkPopulated: function (origin, target, grid, color){
      if (origin === target) return true;
      if (grid.rows[origin][target] && color in grid.rows[origin][target]) return true;
      return false;
    },
    selectNext: function (origin, grid, color, counter){
      counter = counter || 0;
      if(counter > 10) return false;
      var x = Grid.helpers.getRandom(grid);
      if(!Grid.helpers.checkPopulated(origin, x, grid, color)) return x;
      return Grid.helpers.selectNext(origin, grid, color, counter + 1);
    },
    getLast: function (origin){
      console.log("getLast triggered--Needs implementation!!!");
      return origin;
    },
    getPixels: function(origin, next, grid, pixels, color){
      var gridLength = grid.size;
      var pixelLength = pixels.data.length / 4;
      if (pixelLength % gridLength !== 0) console.log('Warning: Grid/pixel ratio off balance. Balance for better results.');
      var rcOrigin = Grid.helpers.convertToRC(origin, grid.width, grid.height);
      var rcNext = Grid.helpers.convertToRC(next, grid.width, grid.height);
      var originImg = Grid.helpers.scaleToImage(rcOrigin, grid.width, grid.height, pixels.width, pixels.height);
      var nextImg = Grid.helpers.scaleToImage(rcNext, grid.width, grid.height, pixels.width, pixels.height);
      var slope = Grid.helpers.findSlope(originImg, nextImg);
      console.log(JSON.stringify(slope));
      return "pixels";

      //console.log("origin: " + origin + "//" + JSON.stringify(rcOrigin) + "//" + JSON.stringify(originImg));
      //console.log("next: " + next + "//" + JSON.stringify(rcNext) + "//" + JSON.stringify(nextImg));
      /*console.log("grid size: " + gridLength);
      console.log("grid dimensons: " + grid.width + 'x' + grid.height);
      console.log("pixel size: " + pixelLength);
      console.log("pixel dimensions: " + pixels.width + 'x' + pixels.height);
      console.log("ratio: " + pixelLength / gridLength); */
    },
    findSlope: function(origin, next){

    },
    convertToRC: function (point, width, height){
      return {row: Math.floor(point / width), column: point % Math.floor(point / width)}
    },
    scaleToImage: function(rcPoint, width1, height1, width2, height2){
      return {row: height2/height1*rcPoint.row, column: width2/width1*rcPoint.column}
    }
  }
};

var Canvas = {
  render: function(canvas, $element){

  }
};
<commit_msg>Pass tests for getSlope<commit_after>'use strict';
var _;

var Parser = {
  getRGB: function(canvas, url){
    var img = new Image();
    var context = canvas.getContext('2d');
    var result = new Promise(function(resolve, reject){
      img.onload=function(){
        canvas.width = img.width;
        canvas.height = img.height;
        context.drawImage(img,0,0);
        resolve(context.getImageData(0,0,canvas.width,canvas.height));
      };
    });

    img.src = url;
    return result;
  }
};

var Grid = {
  generate: function(options) {
    //try an adjacency matrix for this for quick scanning
    var grid = {};
    grid.rows = [];
    grid.size = options.height*options.width;
    grid.width = options.width;
    grid.height = options.height;
    for(var i=0;i<grid.size;i++){
      grid.rows[i] = new Array(grid.size);
    }
    return grid;
  },
  findNextPoint: function(origin, grid, pixels, color, thickness){
    var next = Grid.helpers.selectNext(origin, grid, color);
    console.log("next: " + next);
    if (next === false) return Grid.helpers.getLast(origin);
    var pixelLine = Grid.helpers.getPixels(origin, next, grid, pixels, color);
    //check if it is feasible(if not, restart)
    //if restart more than 10 times, choose another path
    //else, decrement the value of all the arrays
    //return the next node
    console.log(pixelLine);
    return "nextPt";
  },
  helpers: {
    getRandom: function(grid){
      return Math.floor(Math.random()*grid.size);
    },
    checkPopulated: function (origin, target, grid, color){
      if (origin === target) return true;
      if (grid.rows[origin][target] && color in grid.rows[origin][target]) return true;
      return false;
    },
    selectNext: function (origin, grid, color, counter){
      counter = counter || 0;
      if(counter > 10) return false;
      var x = Grid.helpers.getRandom(grid);
      if(!Grid.helpers.checkPopulated(origin, x, grid, color)) return x;
      return Grid.helpers.selectNext(origin, grid, color, counter + 1);
    },
    getLast: function (origin){
      console.log("getLast triggered--Needs implementation!!!");
      return origin;
    },
    getPixels: function(origin, next, grid, pixels, color){
      var gridLength = grid.size;
      var pixelLength = pixels.data.length / 4;
      if (pixelLength % gridLength !== 0) console.log('Warning: Grid/pixel ratio off balance. Balance for better results.');
      var rcOrigin = Grid.helpers.convertToRC(origin, grid.width, grid.height);
      var rcNext = Grid.helpers.convertToRC(next, grid.width, grid.height);
      var originImg = Grid.helpers.scaleToImage(rcOrigin, grid.width, grid.height, pixels.width, pixels.height);
      var nextImg = Grid.helpers.scaleToImage(rcNext, grid.width, grid.height, pixels.width, pixels.height);
      var slope = Grid.helpers.findSlope(originImg, nextImg);
      console.log(JSON.stringify(slope));

      console.log("origin: " + origin + "//" + JSON.stringify(rcOrigin) + "//" + JSON.stringify(originImg));
      console.log("next: " + next + "//" + JSON.stringify(rcNext) + "//" + JSON.stringify(nextImg));
      return "pixels";
      /*console.log("grid size: " + gridLength);
      console.log("grid dimensons: " + grid.width + 'x' + grid.height);
      console.log("pixel size: " + pixelLength);
      console.log("pixel dimensions: " + pixels.width + 'x' + pixels.height);
      console.log("ratio: " + pixelLength / gridLength); */
    },
    findSlope: function(origin, next){
      var rowDiff = next.row - origin.row;
      var colDiff = next.column - origin.column;
      var startWith, increment, slope, count;
      if (Math.abs(rowDiff) >= Math.abs(colDiff)) {
        startWith = "rows";
        increment = rowDiff < 0 ? -1 : 1;
        slope = colDiff/rowDiff*increment;
        count = Math.abs(rowDiff);
      } else {
        startWith = "columns";
        increment = colDiff < 0 ? -1 : 1;
        slope = rowDiff/colDiff*increment;
        count = Math.abs(colDiff);
      }
      return {start_with: startWith, increment: increment, slope: slope, count: count};

    },
    convertToRC: function (point, width, height){
      return {row: Math.floor(point / width), column: point % Math.floor(point / width)};
    },
    scaleToImage: function(rcPoint, width1, height1, width2, height2){
      return {row: height2/height1*rcPoint.row, column: width2/width1*rcPoint.column};
    }
  }
};

var Canvas = {
  render: function(canvas, $element){

  }
};
<|endoftext|>


<commit_before>/**
 * @author astrodud / http://astrodud.isgreat.org/
 * @author zz85 / https://github.com/zz85
 */

THREE.LatheGeometry = function ( points, steps, angle ) {

	THREE.Geometry.call( this );

	this.steps = steps || 12;
	this.angle = angle || 2 * Math.PI;

	var stepSize = this.angle / this.steps,
	newV = [],
	matrix = new THREE.Matrix4().makeRotationZ( stepSize );

	for ( var j = 0; j < points.length; j ++ ) {

		this.vertices.push( new THREE.Vertex( points[ j ] ) );

		newV[ j ] = points[ j ].clone();

	}

	for ( var i = 0; i < this.steps; i ++ ) {

		for ( var j = 0; j < newV.length; j ++ ) {

				newV[ j ] = matrix.multiplyVector3( newV[ j ].clone() );
				this.vertices.push( new THREE.Vertex( newV[ j ] ) );

		}

		var a, b, c, d;
		var steps = this.steps;
		for ( var k = 0, kl = points.length; k < kl-1; k++) {

			a = i * kl + k;
			b = ((i + 1) % steps) * kl + k;
			c = ((i + 1) % steps) * kl + (k + 1) % kl;
			d = i * kl + (k + 1) % kl;

			this.faces.push( new THREE.Face4( a, b, c, d ) );

			this.faceVertexUvs[ 0 ].push( [

				// UV mappings which wraps around
				new THREE.UV( 1 - i / steps, k / kl ),
				new THREE.UV( 1 - (i + 1) / steps, k / kl ),
				new THREE.UV( 1 - (i + 1) / steps, ( k+ 1 ) / kl ),
				new THREE.UV( 1 - i / steps, ( k + 1 ) / kl ),

			] );

		}

	}

	this.computeCentroids();
	this.computeFaceNormals();
	this.computeVertexNormals();

};

THREE.LatheGeometry.prototype = new THREE.Geometry();
THREE.LatheGeometry.prototype.constructor = THREE.LatheGeometry;
<commit_msg>LatheGeometry code clean up. Hmm... I'll need to rewrite this one, the result seems to be wrong.<commit_after>/**
 * @author astrodud / http://astrodud.isgreat.org/
 * @author zz85 / https://github.com/zz85
 */

THREE.LatheGeometry = function ( points, steps, angle ) {

	THREE.Geometry.call( this );

	var _steps = steps || 12;
	var _angle = angle || 2 * Math.PI;

	var _newV = [];
	var _matrix = new THREE.Matrix4().makeRotationZ( _angle / _steps );

	for ( var j = 0; j < points.length; j ++ ) {

		_newV[ j ] = points[ j ].clone();
		this.vertices.push( new THREE.Vertex( _newV[ j ] ) );

	}

	for ( var i = 0; i < _steps; i ++ ) {

		for ( var j = 0; j < _newV.length; j ++ ) {

			_newV[ j ] = _matrix.multiplyVector3( _newV[ j ].clone() );
			this.vertices.push( new THREE.Vertex( _newV[ j ] ) );

		}

		for ( var k = 0, kl = points.length; k < kl - 1; k ++ ) {

			var a = i * kl + k;
			var b = ( ( i + 1 ) % _steps ) * kl + k;
			var c = ( ( i + 1 ) % _steps ) * kl + ( k + 1 ) % kl;
			var d = i * kl + ( k + 1 ) % kl;

			this.faces.push( new THREE.Face4( a, b, c, d ) );

			this.faceVertexUvs[ 0 ].push( [

				new THREE.UV( 1 - i / _steps, k / kl ),
				new THREE.UV( 1 - ( i + 1 ) / _steps, k / kl ),
				new THREE.UV( 1 - ( i + 1 ) / _steps, ( k + 1 ) / kl ),
				new THREE.UV( 1 - i / _steps, ( k + 1 ) / kl )

			] );

		}

	}

	this.computeCentroids();
	this.computeFaceNormals();
	this.computeVertexNormals();

};

THREE.LatheGeometry.prototype = new THREE.Geometry();
THREE.LatheGeometry.prototype.constructor = THREE.LatheGeometry;
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
 */

THREE.PlaneGeometry = function ( width, height, widthSegments, heightSegments ) {

	THREE.info( 'THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint.' );

	THREE.Geometry.call( this );

	this.type = 'PlaneGeometry';

	this.parameters = {
		width: width,
		height: height,
		widthSegments: widthSegments,
		heightSegments: heightSegments
	};

	this.fromBufferGeometry( new THREE.PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );

};

THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
THREE.PlaneGeometry.prototype.constructor = THREE.PlaneGeometry;
<commit_msg>There is no THREE.info<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
 */

THREE.PlaneGeometry = function ( width, height, widthSegments, heightSegments ) {

	THREE.log( 'THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint.' );

	THREE.Geometry.call( this );

	this.type = 'PlaneGeometry';

	this.parameters = {
		width: width,
		height: height,
		widthSegments: widthSegments,
		heightSegments: heightSegments
	};

	this.fromBufferGeometry( new THREE.PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );

};

THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
THREE.PlaneGeometry.prototype.constructor = THREE.PlaneGeometry;
<|endoftext|>


<commit_before>
<commit_msg>Delete test.js<commit_after><|endoftext|>


<commit_before>/**
 * clean unexpected public members, making them private.
 * after this, they could only be fetched by Neuron Loader
 */

;(function(K){

var DOM = K.DOM;

// remove public members
// delete K.DOM;
delete K.__SELECTOR;
delete K.__;
delete DOM.methods;
delete DOM.feature;

// remove Slick from window
// Slick is defined with 'this.Slick'
// so, it's removable and is not [DontDelete]

// IE6 - IE8 don't support delete a property of window, even if it's defined with this.MyNameSpace
try{
	delete window.Slick;
}catch(e){
	K.log('del Slick err');
}

})(KM);

/**
 change log:

 2011-09-08  Kael:
 - renaming the module name as dom, making it a fake package module

 */<commit_msg>neuron: no longer remove static methods of KM.DOM<commit_after>/**
 * clean unexpected public members, making them private.
 * after this, they could only be fetched by Neuron Loader
 */

;(function(K){

var DOM = K.DOM;

// remove public members
// delete K.DOM;
delete K.__SELECTOR;
delete K.__;
// delete DOM.methods;
// delete DOM.feature;

// remove Slick from window
// Slick is defined with 'this.Slick'
// so, it's removable and is not [DontDelete]

// IE6 - IE8 don't support delete a property of window, even if it's defined with this.MyNameSpace
try{
	delete window.Slick;
}catch(e){
	K.log('del Slick err');
}

})(KM);

/**
 change log:

 2011-09-08  Kael:
 - renaming the module name as dom, making it a fake package module

 */<|endoftext|>


<commit_before>"use strict";

/**

 * Module dependencies

 */

module.exports = function(sequelize, DataTypes) {
  var Channel = sequelize.define("Channel", {
    // id autogenerated by sequelize
    name: { type: DataTypes.STRING(50) },
    type: { type: DataTypes.ENUM('S', 'P'), defaultValue: 'S' }, //S stands for 'Shared'; P stands for 'Private'
    description: { type: DataTypes.STRING(500) },
    state: { type: DataTypes.ENUM('O', 'B', 'C'), defaultValue: 'O' },
    closedAt: { type: DataTypes.DATE, allowNull: true },
    deletedBy: { type: DataTypes.INTEGER, allowNull: true },
    closedBy: { type: DataTypes.INTEGER, allowNull: true },
    severedAt:  {type: DataTypes.DATE, allowNull: true },
  }, {
    instanceMethods: {
      close: function(user_id)
      {
        this.state = 'C';
        this.closedAt = new Date();
        this.deletedBy = user_id;
      },
      block: function(user_id)
      {
        this.state = 'B';
        this.severedAt = new Date();
        this.deletedBy = user_id;
      }
    },
      classMethods:{
        associate: function(models) {
          Channel.belongsTo(models.Project);
          Channel.belongsToMany(models.User, { through: models.ChannelUser });
        }
      }
    }
  );

  return Channel;
};
<commit_msg>*fix: al cerrar un canal se actualiza closedBy en lugar de deletedBy<commit_after>"use strict";

/**

 * Module dependencies

 */

module.exports = function(sequelize, DataTypes) {
  var Channel = sequelize.define("Channel", {
    // id autogenerated by sequelize
    name: { type: DataTypes.STRING(50) },
    type: { type: DataTypes.ENUM('S', 'P'), defaultValue: 'S' }, //S stands for 'Shared'; P stands for 'Private'
    description: { type: DataTypes.STRING(500) },
    state: { type: DataTypes.ENUM('O', 'B', 'C'), defaultValue: 'O' },
    closedAt: { type: DataTypes.DATE, allowNull: true },
    deletedBy: { type: DataTypes.INTEGER, allowNull: true },
    closedBy: { type: DataTypes.INTEGER, allowNull: true },
    severedAt:  {type: DataTypes.DATE, allowNull: true },
  }, {
    instanceMethods: {
      close: function(user_id)
      {
        this.state = 'C';
        this.closedAt = new Date();
        this.closedBy = user_id;
      },
      block: function(user_id)
      {
        this.state = 'B';
        this.severedAt = new Date();
        this.deletedBy = user_id;
      }
    },
      classMethods:{
        associate: function(models) {
          Channel.belongsTo(models.Project);
          Channel.belongsToMany(models.User, { through: models.ChannelUser });
        }
      }
    }
  );

  return Channel;
};
<|endoftext|>


<commit_before>module.exports = package

var LRU = require("lru-cache")
, regData = new LRU(10000)
, marked = require("marked")
, gravatar = require('gravatar').url
, npm = require("npm")
, moment = require('moment')

function package (params, cb) {
  var name, version

  if (typeof params === 'object') {
    name = params.name
    version = params.version
  } else {
    var p = params.split('@')
    name = p.shift()
    version = p.join('@')
  }
  // version = version || 'latest'
  version = version || ''

  var k = name + '/' + version
  , data = regData.get(k)

  // remove excessively stale data
  // ignore anything over 10 minutes old
  if (data && !params.nocache) {
    var age = Date.now() - data._time
    if (age > 10 * 60 * 1000) {
      regData.del(k)
      data = null
    }
  }

  if (data) return cb(null, data)

  var uri = name
  if (version) uri += '/' + version
  npm.registry.get(uri, 600, false, true, function (er, data) {
    if (er) return cb(er)
    data.starredBy = Object.keys(data.users || {}).sort()
    var len = data.starredBy.length

    if (data.time && data['dist-tags']) {
      var v = data['dist-tags'].latest
      var t = data.time[v]
      data.version = v
      data.readme = data.versions[v].readme
      data.readmeSrc = null
      data.fromNow = moment(t).fromNow()
    }

    data._time = Date.now()
    if (data.readme && !data.readmeSrc) {
      data.readmeSrc = data.readme
      data.readme = parseReadme(data.readme)
    }
    gravatarPeople(data)
    regData.set(k, data)
    return cb(null, data)
  })
}

function parseReadme (readme) {
  // allow <url>, but not arbitrary html tags.
  // any < must be the start of a <url> or <email@address>
  var e = /^<(?![^ >]+(@|:\/)[^ >]+>)/g
  readme = readme.replace(e, '<')
  return marked.parse(readme)
}

function gravatarPeople (data) {
  gravatarPerson(data.author)
  if (data.maintainers) data.maintainers.forEach(function (m) {
    gravatarPerson(m)
  })
  if (data.contributors) data.contributors.forEach(function (m) {
    gravatarPerson(m)
  })
}

function gravatarPerson (p) {
  if (!p || typeof p !== 'object') {
    return
  }
  p.avatar = gravatar(p.email || '', {s:50, d:'retro'}, true)
}
<commit_msg>Use the root readme if no readme on the latest version<commit_after>module.exports = package

var LRU = require("lru-cache")
, regData = new LRU(10000)
, marked = require("marked")
, gravatar = require('gravatar').url
, npm = require("npm")
, moment = require('moment')

function package (params, cb) {
  var name, version

  if (typeof params === 'object') {
    name = params.name
    version = params.version
  } else {
    var p = params.split('@')
    name = p.shift()
    version = p.join('@')
  }
  // version = version || 'latest'
  version = version || ''

  var k = name + '/' + version
  , data = regData.get(k)

  // remove excessively stale data
  // ignore anything over 10 minutes old
  if (data && !params.nocache) {
    var age = Date.now() - data._time
    if (age > 10 * 60 * 1000) {
      regData.del(k)
      data = null
    }
  }

  if (data) return cb(null, data)

  var uri = name
  if (version) uri += '/' + version
  npm.registry.get(uri, 600, false, true, function (er, data) {
    if (er) return cb(er)
    data.starredBy = Object.keys(data.users || {}).sort()
    var len = data.starredBy.length

    if (data.time && data['dist-tags']) {
      var v = data['dist-tags'].latest
      var t = data.time[v]
      data.version = v
      if (data.versions[v].readme) {
        data.readme = data.versions[v].readme
        data.readmeSrc = null
      }
      data.fromNow = moment(t).fromNow()
    }

    data._time = Date.now()
    if (data.readme && !data.readmeSrc) {
      data.readmeSrc = data.readme
      data.readme = parseReadme(data.readme)
    }
    gravatarPeople(data)
    regData.set(k, data)
    return cb(null, data)
  })
}

function parseReadme (readme) {
  // allow <url>, but not arbitrary html tags.
  // any < must be the start of a <url> or <email@address>
  var e = /^<(?![^ >]+(@|:\/)[^ >]+>)/g
  readme = readme.replace(e, '<')
  return marked.parse(readme)
}

function gravatarPeople (data) {
  gravatarPerson(data.author)
  if (data.maintainers) data.maintainers.forEach(function (m) {
    gravatarPerson(m)
  })
  if (data.contributors) data.contributors.forEach(function (m) {
    gravatarPerson(m)
  })
}

function gravatarPerson (p) {
  if (!p || typeof p !== 'object') {
    return
  }
  p.avatar = gravatar(p.email || '', {s:50, d:'retro'}, true)
}
<|endoftext|>


<commit_before>var ranker = require("./ranker");
module.exports = {

    VERSION: "Objects in mirror are closer than they appear",

    bet_request: function (game_state, bet) {
        //max and min for random bet
        var max = 1000;
        var min = 300;
        try {
            var sb = game_state.small_blind;
            var orbits = game_state.orbits;
            var cc = game_state.community_cards;
            var cb = game_state.current_buy_in;
            var pot = game_state.pot;
            var we;

            //Assign variable for our player
            game_state.players.forEach(function (player) {
                if (player.name == 'All In') {
                    we = player;
                    //console.log(we);
                }
            });

            var hc = we.hole_cards;
            var call = cb - we.bet; //buyin - our bet

            //Print community cards in loop
            /*
            cc.forEach(function (card) {
                console.log("Cards");
                console.log(card);
            });
*/
            var rank = ranker.rank_hand(hc);
            if (rank <= 3) {
                bet(we.stack);
            }
            else if(rank >= 4 && rank <= 6){
                bet(call);
            }
            else if (rank >= 7) {
                bet(0);
            }
            else {
                // Bet min buy_in to cb + 200
                bet(Math.floor(Math.random() * (call + 200 - call + 1) + call));
            }

            //bet(Math.floor(Math.random() * (max - min + 1) + min));
        } catch (e) {
            bet(4000);
            console.log(e);
        }

    },

    showdown: function (game_state) {
        console.log(game_state);
    }
};<commit_msg>repair<commit_after>var ranker = require("./ranker");
module.exports = {

    VERSION: "Objects in mirror are closer than they appear",

    bet_request: function (game_state, bet) {
        //max and min for random bet
        var max = 1000;
        var min = 300;
        try {
            var sb = game_state.small_blind;
            var orbits = game_state.orbits;
            var cc = game_state.community_cards;
            var cb = game_state.current_buy_in;
            var pot = game_state.pot;
            var we;

            //Assign variable for our player
            game_state.players.forEach(function (player) {
                if (player.name == 'All In') {
                    we = player;
                    //console.log(we);
                }
            });

            var hc = we.hole_cards;
            var call = cb - we.bet; //buyin - our bet

            //Print community cards in loop
            /*
            cc.forEach(function (card) {
                console.log("Cards");
                console.log(card);
            });
*/
            var rank = ranker.rank_hand(hc);
            if (rank <= 3) {
                //raise 200
                bet(call + 200);
            }
            else if(rank >= 4 && rank <= 6){
                bet(call);
            }
            else if (rank >= 7) {
                bet(0);
            }
            else {
                // Bet min call to cb + 200
                bet(Math.floor(Math.random() * (call + 200 - call + 1) + call));
            }

            //bet(Math.floor(Math.random() * (max - min + 1) + min));
        } catch (e) {
            bet(4000);
            console.log(e);
        }

    },

    showdown: function (game_state) {
        console.log(game_state);
    }
};<|endoftext|>


<commit_before>module.exports = {
  encode: require('./nsnjson.encoder').encode,
  decode: require('./nsnjson.decoder').decode
};<commit_msg>Add important documentation to { nsnjson.driver }<commit_after>var Encoder = require('./nsnjson.encoder');

var Decoder = require('./nsnjson.decoder');
/**
 * @module Driver
 */
module.exports = {
  /**
   * @param {JSON} data any JSON data
   * @param {Object} options Encoder options
   */
  encode: function(data, options) {
    return Encoder.encode(data, options);
  },

  /**
   * @param {JSON} presentation NSNJSON presentation of JSON
   * @param {Object} options Decoder options
   */
  decode: function(presentation, options) {
    return Decoder.decode(presentation, options);
  }
};<|endoftext|>


<commit_before>
module.exports = {

  VERSION: "Crazy Bot",

  bet_request: function(game_state) {
    return 0;
  },

  showdown: function(game_state) {

  }
};
<commit_msg>all in bot<commit_after>
module.exports = {

  VERSION: "Crazy Bot",

  bet_request: function(game_state) {
    return 100000;
  },

  showdown: function(game_state) {

  }
};
<|endoftext|>


<commit_before>//[pwa]
const response_bodies = $WPT_BODIES;
const requests = $WPT_REQUESTS;
const serviceWorkerRegistrationPattern = /navigator\.serviceWorker\.register\(['"]([^"']+)/m;

const serviceWorkerURLs = response_bodies.filter(har => {
  return serviceWorkerRegistrationPattern.test(har.response_body);
}).map(har => {
  const base = new URL(har.url).origin;
  const serviceWorkerPath = har.response_body.match(serviceWorkerRegistrationPattern)[1];
  return new URL(serviceWorkerPath, base).href;
}).reduce((set, url) => {
  set.add(url);
  return set;
}, new Set());

const manifestURLs = new Set(Array.from(document.querySelectorAll('link[rel=manifest]')).map(link => {
  const base = new URL(location.href).origin;
  const href = link.getAttribute('href');
  return new URL(href, base).href;
}));

const initiatorMap = requests.reduce((map, request) => {
  const url = request.url;
  let initiator = request.initiator.url;
  if (!initiator) {
    initiator = request.initiator?.stack?.callFrames?.[0]?.url
  }
  map[initiator] = map[initiator] || [];
  map[initiator].push(url);
  return map;
}, {});

function getURLsInitiatedBy(initialURL) {
  let initiatorChain = [initialURL];
  for (let i = 0; i < initiatorChain.length; i++) {
    const url = initiatorChain[i];
    if (url in initiatorMap) {
      initiatorChain = initiatorChain.concat(initiatorMap[url].filter(url => {
        return !initiatorChain.includes(url);
      }));
    }
  }
  return initiatorChain;
}

function getEntriesForURLs(urlSet) {
  return response_bodies.filter(har => {
    return urlSet.has(har.url);
  }).map(har => {
    return [har.url, har.response_body];
  });
}

const serviceWorkers = getEntriesForURLs(serviceWorkerURLs);
const manifests = getEntriesForURLs(manifestURLs).map(([url, body]) => {
  let manifest;
  try {
    manifest = JSON.parse(body);
  } catch (e) {
    manifest = body;
  }
  return [url, manifest];
});

const serviceWorkerInitiatedURLs = new Set(Array.from(serviceWorkerURLs).flatMap(getURLsInitiatedBy));
const serviceWorkerInitiated = getEntriesForURLs(serviceWorkerInitiatedURLs);

const workboxPattern = /(?:workbox:[a-z\-]+:[\d.]+|workbox\.[a-zA-Z]+\.?[a-zA-Z]*)/g;
// We should use serviceWorkerInitiatedURLs here, but SW detection has some false negatives.
const workboxInfo = response_bodies.filter(har => {
  return workboxPattern.test(har.response_body);
}).map(har => {
  return [har.url, Array.from(har.response_body.matchAll(workboxPattern)).map(m => m[0])];
});

return {
  serviceWorkers: Object.fromEntries(serviceWorkers),
  manifests: Object.fromEntries(manifests),
  serviceWorkerInitiated: Object.keys(Object.fromEntries(serviceWorkerInitiated)),
  workboxInfo: Object.fromEntries(workboxInfo)
};
<commit_msg>New script to detect importScripts(), service worker events and service worker properties (#204)<commit_after>//[pwa]
const response_bodies = $WPT_BODIES;
const requests = $WPT_REQUESTS;
const serviceWorkerRegistrationPattern = /navigator\.serviceWorker\.register\(['"]([^"']+)/m;

const serviceWorkerURLs = response_bodies.filter(har => {
  return serviceWorkerRegistrationPattern.test(har.response_body);
}).map(har => {
  const base = new URL(har.url).origin;
  const serviceWorkerPath = har.response_body.match(serviceWorkerRegistrationPattern)[1];
  return new URL(serviceWorkerPath, base).href;
}).reduce((set, url) => {
  set.add(url);
  return set;
}, new Set());

const manifestURLs = new Set(Array.from(document.querySelectorAll('link[rel=manifest]')).map(link => {
  const base = new URL(location.href).origin;
  const href = link.getAttribute('href');
  return new URL(href, base).href;
}));

const initiatorMap = requests.reduce((map, request) => {
  const url = request.url;
  let initiator = request.initiator.url;
  if (!initiator) {
    initiator = request.initiator?.stack?.callFrames?.[0]?.url
  }
  map[initiator] = map[initiator] || [];
  map[initiator].push(url);
  return map;
}, {});

function getURLsInitiatedBy(initialURL) {
  let initiatorChain = [initialURL];
  for (let i = 0; i < initiatorChain.length; i++) {
    const url = initiatorChain[i];
    if (url in initiatorMap) {
      initiatorChain = initiatorChain.concat(initiatorMap[url].filter(url => {
        return !initiatorChain.includes(url);
      }));
    }
  }
  return initiatorChain;
}

function getEntriesForURLs(urlSet) {
  return response_bodies.filter(har => {
    return urlSet.has(har.url);
  }).map(har => {
    return [har.url, har.response_body];
  });
}

const serviceWorkers = getEntriesForURLs(serviceWorkerURLs);
const manifests = getEntriesForURLs(manifestURLs).map(([url, body]) => {
  let manifest;
  try {
    manifest = JSON.parse(body);
  } catch (e) {
    manifest = body;
  }
  return [url, manifest];
});

const serviceWorkerInitiatedURLs = new Set(Array.from(serviceWorkerURLs).flatMap(getURLsInitiatedBy));
const serviceWorkerInitiated = getEntriesForURLs(serviceWorkerInitiatedURLs);

// We should use serviceWorkerInitiatedURLs here, but SW detection has some false negatives.
function getInfoForPattern(regexPattern, extractMatchingGroupOnly) {
  return response_bodies.filter(har => {
    return regexPattern.test(har.response_body);
  }).map(har => {
    return [har.url, Array.from(har.response_body.matchAll(regexPattern)).map(m => {
      return (extractMatchingGroupOnly && m.length > 0) ? m[1] : m[0]
    })];
  });
}

const workboxPattern = /(?:workbox:[a-z\-]+:[\d.]+|workbox\.[a-zA-Z]+\.?[a-zA-Z]*)/g;
const workboxInfo = getInfoForPattern(workboxPattern);

const importScriptsPattern = /importScripts\(([^)]*)\)/g;
const importScriptsInfo = getInfoForPattern(importScriptsPattern, true);

const swEventListenersPattern = /addEventListener\(\s*[\'"](install|activate|push|notificationclick|notificationclose|sync|canmakepayment|paymentrequest|periodicsync|backgroundfetchsuccess|backgroundfetchfailure|backgroundfetchabort|backgroundfetchclick)[\'"]/g;
const swEventListenersInfo = getInfoForPattern(swEventListenersPattern, true);

const swPropertiesPattern = /\.on(install|activate|push|notificationclick|notificationclose|sync|canmakepayment|paymentrequest|periodicsync|backgroundfetchsuccess|backgroundfetchfailure|backgroundfetchabort|backgroundfetchclick)\s*=/g;
const swPropertiesInfo = getInfoForPattern(swPropertiesPattern, true);

const swMethodsPattern = /skipWaiting\(\)/g;
const swMethodsInfo = getInfoForPattern(swMethodsPattern);

const swObjectsPattern = /clients\.(get|matchAll|openWindow|claim)|client\.(postMessage|id|type|url)|caches\.(match|has|open|delete|keys)|cache\.(match|matchAll|add|addAll|put|keys)/g;
const swObjectsInfo = getInfoForPattern(swObjectsPattern);

const swRegistrationPropertiesPattern = /navigationPreload\.(enable|disable|setHeaderValue|getState)|pushManager\.(getSubscription|permissionState|subscribe)|sync\.(register|getTags)/g;
const swRegistrationPropertiesInfo = getInfoForPattern(swRegistrationPropertiesPattern);

const windowEventListenersPattern = /addEventListener\(\s*[\'"](appinstalled|beforeinstallprompt)[\'"]/g;
const windowEventListenersInfo = getInfoForPattern(windowEventListenersPattern, true);

const windowPropertiesPattern = /\.on(appinstalled|beforeinstallprompt)\s*=/g;
const windowPropertiesInfo = getInfoForPattern(windowPropertiesPattern, true);

function isObjectKeyEmpty(field) {
  return field == null || field.length == 0;
}

return {
  serviceWorkers: Object.fromEntries(serviceWorkers),
  manifests: Object.fromEntries(manifests),
  serviceWorkerInitiated: Object.keys(Object.fromEntries(serviceWorkerInitiated)),
  workboxInfo: Object.fromEntries(workboxInfo),
  importScriptsInfo: Object.fromEntries(importScriptsInfo),
  swEventListenersInfo: Object.fromEntries(swEventListenersInfo),
  swPropertiesInfo: Object.fromEntries(swPropertiesInfo),
  swMethodsInfo: Object.fromEntries(swMethodsInfo),
  swObjectsInfo: Object.fromEntries(swObjectsInfo),
  swRegistrationPropertiesInfo: Object.fromEntries(swRegistrationPropertiesInfo),
  windowEventListenersInfo: Object.fromEntries(windowEventListenersInfo),
  windowPropertiesInfo: Object.fromEntries(windowPropertiesInfo),
  //Experimental field: Heuristic to detect if a site has a service worker even if the 'serviceWorkers' field is empty (false positives).
  serviceWorkerHeuristic: !isObjectKeyEmpty(serviceWorkers) || !isObjectKeyEmpty(workboxInfo) || !isObjectKeyEmpty(swEventListenersInfo) || !isObjectKeyEmpty(swMethodsInfo)
};
<|endoftext|>


<commit_before>var html5Player = function() {
    var video;

    function init(videoUrl, containerId) {
        video = document.createElement("video");
        video.setAttribute("src", videoUrl);
        video.setAttribute("width", 512);
        video.setAttribute('controls', true);
        document.getElementById(containerId).appendChild(video);
    }

    function play() {
        video.play();
    }

    function pause() {
        video.pause();
    }

    function destroy() {
        video.remove();
    }

    function paused() {
        return video.paused;
    }

    function duration() {
        return video.duration;
    }

    function currentTime() {
        return video.currentTime;
    }

    function setCurrentTime(time) {
        video.currentTime = time;
    }

    function ended() {
        return video.ended;
    }

    function volume() {
        return video.volume;
    }

    function setVolume(volume) {
        video.volume = volume;
    }

    function muted() {
        return video.muted;
    }

    function mute() {
        video.muted = true;
    }

    function unmute() {
        video.muted = false;
    }

    function onDurationAvailable(callback) {
        var onLoadedMetadata = function() {callback(duration());};
        video.addEventListener('loadedmetadata', onLoadedMetadata);
    }

    function onPlay(callback) {
        video.addEventListener('playing', callback);
    }

    function onPause(callback) {
        video.addEventListener('pause', callback);
    }

    function onPlayTimeChange(callback) {
        var onPlayTimeChangeCb = function() {callback(currentTime());};
        video.addEventListener('timeupdate', onPlayTimeChangeCb);
    }

    function onEnded(callback) {
        video.addEventListener('ended', callback);
    }

    return {
        init: init,
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}

var vimeoPlayer = function() {
    var video,
        divWrapper;

    function init(videoUrl, containerId) {
        var vimeoApi = (function(){
            function Froogaloop(iframe) {
                return new Froogaloop.fn.init(iframe);
            }

            var eventCallbacks = {},
                hasWindowEvent = false,
                isReady = false,
                slice = Array.prototype.slice,
                playerOrigin = '*';

            Froogaloop.fn = Froogaloop.prototype = {
                element: null,

                init: function(iframe) {
                    if (typeof iframe === "string") {
                        iframe = document.getElementById(iframe);
                    }

                    this.element = iframe;

                    return this;
                },

                api: function(method, valueOrCallback) {
                    if (!this.element || !method) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null,
                        params = !isFunction(valueOrCallback) ? valueOrCallback : null,
                        callback = isFunction(valueOrCallback) ? valueOrCallback : null;

                    if (callback) {
                        storeCallback(method, callback, target_id);
                    }

                    postMessage(method, params, element);
                    return self;
                },

                addEvent: function(eventName, callback) {
                    if (!this.element) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null;

                    storeCallback(eventName, callback, target_id);

                    if (eventName != 'ready') {
                        postMessage('addEventListener', eventName, element);
                    }
                    else if (eventName == 'ready' && isReady) {
                        callback.call(null, target_id);
                    }

                    return self;
                },

                removeEvent: function(eventName) {
                    if (!this.element) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null,
                        removed = removeCallbacks(eventName, target_id);

                    if (eventName != 'ready' && removed) {
                        postMessage('removeEventListener', eventName, element);
                    }
                }
            };

            function postMessage(method, params, target) {
                if (!target.contentWindow.postMessage) {
                    return false;
                }

                var data = JSON.stringify({
                    method: method,
                    value: params
                });

                target.contentWindow.postMessage(data, playerOrigin);
            }

            function onMessageReceived(event) {
                var data, method;

                try {
                    data = JSON.parse(event.data);
                    method = data.event || data.method;
                }
                catch(e) {
                }

                if (method == 'ready' && !isReady) {
                    isReady = true;
                }

                if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {
                    return false;
                }

                if (playerOrigin === '*') {
                    playerOrigin = event.origin;
                }

                var value = data.value,
                    eventData = data.data,
                    target_id = target_id === '' ? null : data.player_id,

                    callbacks = getCallbacks(method, target_id),
                    params = [];

                if (!callbacks) {
                    return false;
                }

                if (value !== undefined) {
                    params.push(value);
                }

                if (eventData) {
                    params.push(eventData);
                }

                if (target_id) {
                    params.push(target_id);
                }

                callbacks.forEach(function(callback) {
                    params.length > 0 ? callback.apply(null, params) : callback.call();
                });
            }

            function storeCallback(eventName, callback, target_id) {
                if (target_id) {
                    if (!eventCallbacks[target_id]) {
                        eventCallbacks[target_id] = {};
                    }
                    if (!eventCallbacks[target_id][eventName]) {
                        eventCallbacks[target_id][eventName] = [];
                    }
                    eventCallbacks[target_id][eventName].push(callback);
                }
                else {
                    if (!eventCallbacks[eventName]) {
                        eventCallbacks[eventName] = [];
                    }
                    eventCallbacks[eventName].push(callback);
                }
            }

            function getCallbacks(eventName, target_id) {
                if (target_id) {
                    return eventCallbacks[target_id][eventName];
                }
                else {
                    return eventCallbacks[eventName];
                }
            }

            function removeCallbacks(eventName, target_id) {
                if (target_id && eventCallbacks[target_id]) {
                    if (!eventCallbacks[target_id][eventName]) {
                        return false;
                    }
                    eventCallbacks[target_id][eventName] = null;
                }
                else {
                    if (!eventCallbacks[eventName]) {
                        return false;
                    }
                    eventCallbacks[eventName] = null;
                }

                return true;
            }

            function isFunction(obj) {
                return !!(obj && obj.constructor && obj.call && obj.apply);
            }

            function isArray(obj) {
                return toString.call(obj) === '[object Array]';
            }

            Froogaloop.fn.init.prototype = Froogaloop.fn;

            if (window.addEventListener) {
                window.addEventListener('message', onMessageReceived, false);
            }
            else {
                window.attachEvent('onmessage', onMessageReceived);
            }

            return Froogaloop;

        })();

        this.baseUrl = 'https://player.vimeo.com/video/';
        this.videoId = videoUrl.split('//player.vimeo.com/video/')[1];

        this.iframe = document.createElement('iframe');
        this.iframe.setAttribute('title', 'Vimeo Video Player');
        this.iframe.setAttribute('class', 'vimeoplayer');
        this.iframe.setAttribute('src', this.baseUrl + this.videoId + '?api=1');
        this.iframe.setAttribute('frameborder', '0');
        this.iframe.setAttribute('scrolling', 'no');
        this.iframe.setAttribute('marginWidth', '0');
        this.iframe.setAttribute('marginHeight', '0');
        this.iframe.setAttribute('webkitAllowFullScreen', '0');
        this.iframe.setAttribute('mozallowfullscreen', '0');
        this.iframe.setAttribute('allowFullScreen', '0');

        video = vimeoApi(this.iframe);

        divWrapper = document.createElement('div');
        divWrapper.setAttribute('style', 'margin:0 auto;padding-bottom:56.25%;width:100%;height:0;position:relative;overflow:hidden;');
        divWrapper.setAttribute('class', 'vimeoFrame');
        divWrapper.appendChild(this.iframe);
        document.getElementById(containerId).appendChild(divWrapper);
        video.addEvent('ready', setPlayerInformationCallbacks);
    }

    var _volume = 1.0,
        _duration = 0,
        _currentTime = 0,
        _paused = true,
        _mutedPreviousVolume = 1.0;

    function setPlayerInformationCallbacks() {
        video.addEvent('pause', function() {_paused = true;});
        video.addEvent('play', function() {_paused = false;});
        video.addEvent('playProgress', function(value) {_currentTime = value.seconds;});
        video.addEvent('loadProgress', function(value) {_duration = value.duration;});
        video.api('getVolume', function(value) {_volume = value;});
        video.api('getDuration', function(value) {_duration = value;});
    }

    function play() {
        video.api('play');
    }

    function pause() {
        video.api('pause');
    }

    function destroy() {
        divWrapper.remove();
    }
    function paused() {
        return _paused;
    }

    function duration() {
        return _duration;
    }

    function currentTime() {
        return _currentTime;
    }

    function setCurrentTime(time) {
        var wasPaused = _paused;
        video.api('seekTo', time);
        if (wasPaused) player.pause();
    }

    function ended() {
        return currentTime() === duration();
    }

    function volume() {
        return _volume;
    }

    function setVolume(vol) {
        video.api('setVolume', vol);
        _volume = vol;
    }

    function muted() {
        return volume() === 0;
    }

    function mute() {
        _mutedPreviousVolume = volume();
        setVolume(0);
    }

    function unmute() {
        video.api('setVolume', _mutedPreviousVolume);
        _volume = _mutedPreviousVolume;
    }

    function onDurationAvailable(callback) {
        video.api('ready', function() {
            video.api('getDuration', function(duration) {
                callback(duration);
            })
        });
    }

    function onPlay(callback) {
        video.api('ready', function() {
            video.addEvent('play', function() {
                callback();
            })
        });
    }

    function onPause(callback) {
        video.api('ready', function() {
            video.addEvent('pause', function() {
                callback();
            })
        });
    }

    function onPlayTimeChange(callback) {
        video.api('ready', function() {
            video.addEvent('playProgress', function(data) {
                callback(data.seconds);
            })
        });
    }

    function onEnded(callback) {
        video.api('ready', function() {
            video.addEvent('finish', function() {
                callback();
            })
        });
    }

    return {
        init: init,
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}

var pybossaPlayer = function(videoUrl, containerId) {
    var player;

    if (videoUrl.split('.').indexOf('vimeo') !== -1) {
        player = vimeoPlayer();
    }
    else {
        player = html5Player();
    }

    player.init(videoUrl, containerId);

    function play() {
        player.play();
    }

    function pause() {
        player.pause();
    }

    function destroy() {
        player.destroy();
    }

    function paused() {
        return player.paused();
    }

    function duration() {
        return player.duration();
    }

    function currentTime() {
        return player.currentTime();
    }

    function setCurrentTime(time) {
        player.setCurrentTime(time);
    }

    function ended() {
        return player.ended();
    }

    function volume() {
        return player.volume();
    }

    function setVolume(volume) {
        player.setVolume(volume);
    }

    function muted() {
        return player.muted();
    }

    function mute() {
        player.mute();
    }

    function unmute() {
        player.unmute();
    }

    function onDurationAvailable(callback) {
        player.onDurationAvailable(callback);
    }

    function onPlay(callback) {
        player.onPlay(callback);
    }

    function onPause(callback) {
        player.onPause(callback);
    }

    function onPlayTimeChange(callback) {
        player.onPlayTimeChange(callback);
    }

    function onEnded(callback) {
        player.onEnded(callback);
    }

    return {
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}
<commit_msg>Add youtube player w/ basic controls<commit_after>var html5Player = function() {
    var video;

    function init(videoUrl, containerId) {
        video = document.createElement("video");
        video.setAttribute("src", videoUrl);
        video.setAttribute("width", 512);
        video.setAttribute('controls', true);
        document.getElementById(containerId).appendChild(video);
    }

    function play() {
        video.play();
    }

    function pause() {
        video.pause();
    }

    function destroy() {
        video.remove();
    }

    function paused() {
        return video.paused;
    }

    function duration() {
        return video.duration;
    }

    function currentTime() {
        return video.currentTime;
    }

    function setCurrentTime(time) {
        video.currentTime = time;
    }

    function ended() {
        return video.ended;
    }

    function volume() {
        return video.volume;
    }

    function setVolume(volume) {
        video.volume = volume;
    }

    function muted() {
        return video.muted;
    }

    function mute() {
        video.muted = true;
    }

    function unmute() {
        video.muted = false;
    }

    function onDurationAvailable(callback) {
        var onLoadedMetadata = function() {callback(duration());};
        video.addEventListener('loadedmetadata', onLoadedMetadata);
    }

    function onPlay(callback) {
        video.addEventListener('playing', callback);
    }

    function onPause(callback) {
        video.addEventListener('pause', callback);
    }

    function onPlayTimeChange(callback) {
        var onPlayTimeChangeCb = function() {callback(currentTime());};
        video.addEventListener('timeupdate', onPlayTimeChangeCb);
    }

    function onEnded(callback) {
        video.addEventListener('ended', callback);
    }

    return {
        init: init,
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}

var vimeoPlayer = function() {
    var video,
        divWrapper;

    function init(videoUrl, containerId) {
        var vimeoApi = (function(){
            function Froogaloop(iframe) {
                return new Froogaloop.fn.init(iframe);
            }

            var eventCallbacks = {},
                hasWindowEvent = false,
                isReady = false,
                slice = Array.prototype.slice,
                playerOrigin = '*';

            Froogaloop.fn = Froogaloop.prototype = {
                element: null,

                init: function(iframe) {
                    if (typeof iframe === "string") {
                        iframe = document.getElementById(iframe);
                    }

                    this.element = iframe;

                    return this;
                },

                api: function(method, valueOrCallback) {
                    if (!this.element || !method) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null,
                        params = !isFunction(valueOrCallback) ? valueOrCallback : null,
                        callback = isFunction(valueOrCallback) ? valueOrCallback : null;

                    if (callback) {
                        storeCallback(method, callback, target_id);
                    }

                    postMessage(method, params, element);
                    return self;
                },

                addEvent: function(eventName, callback) {
                    if (!this.element) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null;

                    storeCallback(eventName, callback, target_id);

                    if (eventName != 'ready') {
                        postMessage('addEventListener', eventName, element);
                    }
                    else if (eventName == 'ready' && isReady) {
                        callback.call(null, target_id);
                    }

                    return self;
                },

                removeEvent: function(eventName) {
                    if (!this.element) {
                        return false;
                    }

                    var self = this,
                        element = self.element,
                        target_id = element.id !== '' ? element.id : null,
                        removed = removeCallbacks(eventName, target_id);

                    if (eventName != 'ready' && removed) {
                        postMessage('removeEventListener', eventName, element);
                    }
                }
            };

            function postMessage(method, params, target) {
                if (!target.contentWindow.postMessage) {
                    return false;
                }

                var data = JSON.stringify({
                    method: method,
                    value: params
                });

                target.contentWindow.postMessage(data, playerOrigin);
            }

            function onMessageReceived(event) {
                var data, method;

                try {
                    data = JSON.parse(event.data);
                    method = data.event || data.method;
                }
                catch(e) {
                }

                if (method == 'ready' && !isReady) {
                    isReady = true;
                }

                if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {
                    return false;
                }

                if (playerOrigin === '*') {
                    playerOrigin = event.origin;
                }

                var value = data.value,
                    eventData = data.data,
                    target_id = target_id === '' ? null : data.player_id,

                    callbacks = getCallbacks(method, target_id),
                    params = [];

                if (!callbacks) {
                    return false;
                }

                if (value !== undefined) {
                    params.push(value);
                }

                if (eventData) {
                    params.push(eventData);
                }

                if (target_id) {
                    params.push(target_id);
                }

                callbacks.forEach(function(callback) {
                    params.length > 0 ? callback.apply(null, params) : callback.call();
                });
            }

            function storeCallback(eventName, callback, target_id) {
                if (target_id) {
                    if (!eventCallbacks[target_id]) {
                        eventCallbacks[target_id] = {};
                    }
                    if (!eventCallbacks[target_id][eventName]) {
                        eventCallbacks[target_id][eventName] = [];
                    }
                    eventCallbacks[target_id][eventName].push(callback);
                }
                else {
                    if (!eventCallbacks[eventName]) {
                        eventCallbacks[eventName] = [];
                    }
                    eventCallbacks[eventName].push(callback);
                }
            }

            function getCallbacks(eventName, target_id) {
                if (target_id) {
                    return eventCallbacks[target_id][eventName];
                }
                else {
                    return eventCallbacks[eventName];
                }
            }

            function removeCallbacks(eventName, target_id) {
                if (target_id && eventCallbacks[target_id]) {
                    if (!eventCallbacks[target_id][eventName]) {
                        return false;
                    }
                    eventCallbacks[target_id][eventName] = null;
                }
                else {
                    if (!eventCallbacks[eventName]) {
                        return false;
                    }
                    eventCallbacks[eventName] = null;
                }

                return true;
            }

            function isFunction(obj) {
                return !!(obj && obj.constructor && obj.call && obj.apply);
            }

            function isArray(obj) {
                return toString.call(obj) === '[object Array]';
            }

            Froogaloop.fn.init.prototype = Froogaloop.fn;

            if (window.addEventListener) {
                window.addEventListener('message', onMessageReceived, false);
            }
            else {
                window.attachEvent('onmessage', onMessageReceived);
            }

            return Froogaloop;

        })();

        this.baseUrl = 'https://player.vimeo.com/video/';
        this.videoId = videoUrl.split('//player.vimeo.com/video/')[1];

        this.iframe = document.createElement('iframe');
        this.iframe.setAttribute('title', 'Vimeo Video Player');
        this.iframe.setAttribute('class', 'vimeoplayer');
        this.iframe.setAttribute('src', this.baseUrl + this.videoId + '?api=1');
        this.iframe.setAttribute('frameborder', '0');
        this.iframe.setAttribute('scrolling', 'no');
        this.iframe.setAttribute('marginWidth', '0');
        this.iframe.setAttribute('marginHeight', '0');
        this.iframe.setAttribute('webkitAllowFullScreen', '0');
        this.iframe.setAttribute('mozallowfullscreen', '0');
        this.iframe.setAttribute('allowFullScreen', '0');

        video = vimeoApi(this.iframe);

        divWrapper = document.createElement('div');
        divWrapper.setAttribute('style', 'margin:0 auto;padding-bottom:56.25%;width:100%;height:0;position:relative;overflow:hidden;');
        divWrapper.setAttribute('class', 'vimeoFrame');
        divWrapper.appendChild(this.iframe);
        document.getElementById(containerId).appendChild(divWrapper);
        video.addEvent('ready', setPlayerInformationCallbacks);
    }

    var _volume = 1.0,
        _duration = 0,
        _currentTime = 0,
        _paused = true,
        _mutedPreviousVolume = 1.0;

    function setPlayerInformationCallbacks() {
        video.addEvent('pause', function() {_paused = true;});
        video.addEvent('play', function() {_paused = false;});
        video.addEvent('playProgress', function(value) {_currentTime = value.seconds;});
        video.addEvent('loadProgress', function(value) {_duration = value.duration;});
        video.api('getVolume', function(value) {_volume = value;});
        video.api('getDuration', function(value) {_duration = value;});
    }

    function play() {
        video.api('play');
    }

    function pause() {
        video.api('pause');
    }

    function destroy() {
        divWrapper.remove();
    }
    function paused() {
        return _paused;
    }

    function duration() {
        return _duration;
    }

    function currentTime() {
        return _currentTime;
    }

    function setCurrentTime(time) {
        var wasPaused = _paused;
        video.api('seekTo', time);
        if (wasPaused) player.pause();
    }

    function ended() {
        return currentTime() === duration();
    }

    function volume() {
        return _volume;
    }

    function setVolume(vol) {
        video.api('setVolume', vol);
        _volume = vol;
    }

    function muted() {
        return volume() === 0;
    }

    function mute() {
        _mutedPreviousVolume = volume();
        setVolume(0);
    }

    function unmute() {
        video.api('setVolume', _mutedPreviousVolume);
        _volume = _mutedPreviousVolume;
    }

    function onDurationAvailable(callback) {
        video.api('ready', function() {
            video.api('getDuration', function(duration) {
                callback(duration);
            })
        });
    }

    function onPlay(callback) {
        video.api('ready', function() {
            video.addEvent('play', function() {
                callback();
            })
        });
    }

    function onPause(callback) {
        video.api('ready', function() {
            video.addEvent('pause', function() {
                callback();
            })
        });
    }

    function onPlayTimeChange(callback) {
        video.api('ready', function() {
            video.addEvent('playProgress', function(data) {
                callback(data.seconds);
            })
        });
    }

    function onEnded(callback) {
        video.api('ready', function() {
            video.addEvent('finish', function() {
                callback();
            })
        });
    }

    return {
        init: init,
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}

var youtubePlayer = function() {
    var player;

    function init(videoUrl, containerId) {
        var div = document.createElement('div');
        div.setAttribute('id', containerId);
        div.setAttribute('style', 'width:100%;height:100%;top:0;left:0;position:absolute');

        var divWrapper = document.createElement('div');
        divWrapper.appendChild(div);

        document.getElementById(containerId).appendChild(divWrapper);
        window.onYouTubeIframeAPIReady = function() {createPlayer(videoUrl, containerId);}
        loadApi();
    }

    function createPlayer(videoUrl, containerId) {
        var videoId = extractVideoId(videoUrl);
        player = new YT.Player(containerId, {
            height: '390',
            width: '640',
            videoId: videoId,
            events: {}
        });
    }

    function extractVideoId(videoUrl) {
        var rx = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/;
        var r = videoUrl.match(rx);
        return r[1];
    }

    function loadApi() {
        var tag = document.createElement('script');
        tag.src = 'https://www.youtube.com/iframe_api';
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }

    function play() {
        player.playVideo();
    }

    function pause() {
        player.pauseVideo();
    }

    function destroy() {
        player.destroy();
    }

    function paused() {
        return player.getPlayerState() !== 1;
    }

    function duration() {
        return player.getDuration();
    }

    function currentTime() {
        return player.getCurrentTime();
    }

    function setCurrentTime(time) {
        var wasPaused = paused();
        player.seekTo(time);
        if (wasPaused) pause();
    }

    function ended() {
        return player.getPlayerState() === 0;
    }

    function volume() {
        return player.getVolume() / 100.0;
    }

    function setVolume(volume) {
        player.setVolume(volume * 100);
    }

    function muted() {
        return player.isMuted();
    }

    function mute() {
        player.mute();
    }

    function unmute() {
        player.unMute();
    }

    function onDurationAvailable(callback) {
    }

    function onPlay(callback) {
    }

    function onPause(callback) {
    }

    function onPlayTimeChange(callback) {
    }

    function onEnded(callback) {
    }

    return {
        init: init,
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}

var pybossaPlayer = function(videoUrl, containerId) {
    var player;

    if (videoUrl.split('.').indexOf('vimeo') !== -1) {
        player = vimeoPlayer();
    }
    else if (isYoutubeLink(videoUrl)){
        player = youtubePlayer();
    }
    else {
        player = html5Player();
    }

    function isYoutubeLink(link) {
        var rx = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/;
        var r = link.match(rx);
        return r !== null;
    }

    player.init(videoUrl, containerId);

    function play() {
        player.play();
    }

    function pause() {
        player.pause();
    }

    function destroy() {
        player.destroy();
    }

    function paused() {
        return player.paused();
    }

    function duration() {
        return player.duration();
    }

    function currentTime() {
        return player.currentTime();
    }

    function setCurrentTime(time) {
        player.setCurrentTime(time);
    }

    function ended() {
        return player.ended();
    }

    function volume() {
        return player.volume();
    }

    function setVolume(volume) {
        player.setVolume(volume);
    }

    function muted() {
        return player.muted();
    }

    function mute() {
        player.mute();
    }

    function unmute() {
        player.unmute();
    }

    function onDurationAvailable(callback) {
        player.onDurationAvailable(callback);
    }

    function onPlay(callback) {
        player.onPlay(callback);
    }

    function onPause(callback) {
        player.onPause(callback);
    }

    function onPlayTimeChange(callback) {
        player.onPlayTimeChange(callback);
    }

    function onEnded(callback) {
        player.onEnded(callback);
    }

    return {
        play: play,
        pause: pause,
        destroy: destroy,
        paused: paused,
        duration: duration,
        currentTime: currentTime,
        setCurrentTime: setCurrentTime,
        ended: ended,
        volume: volume,
        setVolume: setVolume,
        muted: muted,
        mute: mute,
        unmute: unmute,
        onDurationAvailable: onDurationAvailable,
        onPlay: onPlay,
        onPause: onPause,
        onPlayTimeChange: onPlayTimeChange,
        onEnded: onEnded
    };
}
<|endoftext|>


<commit_before>import { ASSETS, COLLISION_GROUPS } from 'constants';
import { getCollisionGroup } from 'lib/utils';

import Bullet from 'objects/bullet';

export default class Player extends Phaser.Sprite {
  constructor(game, x, y) {
    const { world } = game;

    super(game, x, y, ASSETS.PLAYER, 1);

    game.physics.p2.enable(this);

    this.body.setRectangle(44, 60);
    this.body.static = true;
    game.debug.body(this);

    this.fired = false;

    this.spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

    this.bullet = new Bullet(game, x + 28 , y);
    game.add.existing(this.bullet);

     // Collision Group
    const bulletGroup = getCollisionGroup(game, COLLISION_GROUPS.BULLET);
    const playerGroup = getCollisionGroup(game, COLLISION_GROUPS.PLAYER);

    this.body.setCollisionGroup(playerGroup);
    this.body.collides(bulletGroup);
  }

  update() {
    if (this.spaceKey.isDown && !this.fired) {
      this.fired = true;
      this.fireBullet();
    }
  }

  fireBullet() {
    this.game.sound.play(ASSETS.SFX_FIRE);
    this.bullet.body.velocity.x = 500;
    // this.bullet.body.velocity.y = 200;
  }
}

<commit_msg>Increase bullet velocity<commit_after>import { ASSETS, COLLISION_GROUPS } from 'constants';
import { getCollisionGroup } from 'lib/utils';

import Bullet from 'objects/bullet';

export default class Player extends Phaser.Sprite {
  constructor(game, x, y) {
    const { world } = game;

    super(game, x, y, ASSETS.PLAYER, 1);

    game.physics.p2.enable(this);

    this.body.setRectangle(44, 60);
    this.body.static = true;
    game.debug.body(this);

    this.fired = false;

    this.spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

    this.bullet = new Bullet(game, x + 28 , y);
    game.add.existing(this.bullet);

     // Collision Group
    const bulletGroup = getCollisionGroup(game, COLLISION_GROUPS.BULLET);
    const playerGroup = getCollisionGroup(game, COLLISION_GROUPS.PLAYER);

    this.body.setCollisionGroup(playerGroup);
    this.body.collides(bulletGroup);
  }

  update() {
    if (this.spaceKey.isDown && !this.fired) {
      this.fired = true;
      this.fireBullet();
    }
  }

  fireBullet() {
    this.game.sound.play(ASSETS.SFX_FIRE);
    this.bullet.body.velocity.x = 600;
  }
}

<|endoftext|>


<commit_before>  /*
     $$$$$$\   $$$$$$\  $$\   $$\ $$$$$$$$\ $$$$$$\  $$$$$$\
    $$  __$$\ $$  __$$\ $$$\  $$ |$$  _____|\_$$  _|$$  __$$\
    $$ /  \__|$$ /  $$ |$$$$\ $$ |$$ |        $$ |  $$ /  \__|
    $$ |      $$ |  $$ |$$ $$\$$ |$$$$$\      $$ |  $$ |$$$$\
    $$ |      $$ |  $$ |$$ \$$$$ |$$  __|     $$ |  $$ |\_$$ |
    $$ |  $$\ $$ |  $$ |$$ |\$$$ |$$ |        $$ |  $$ |  $$ |
    \$$$$$$  | $$$$$$  |$$ | \$$ |$$ |      $$$$$$\ \$$$$$$  |
     \______/  \______/ \__|  \__|\__|      \______| \______/
  */

  var DEFAULT_OPTIONS = {
      target_wpm: 400,
      scale: 1,
      dark: false,
      modifiers: {
        normal: 1,
        start_clause: 1,
        end_clause: 1.8,
        start_sentence: 1.3,
        end_sentence: 2.2,
        start_paragraph: 2.0,
        end_paragraph: 2.8,
        short_space: 1.5,
        long_space: 2.2
      },
	  view : {
	  	selection_color : "red"
	  }
      // keybindings and so forth soon
  };

  var options = recursiveExtend({}, DEFAULT_OPTIONS);

  // placeholder config backend for when there is no real backend.
  var configBackend = {
    get: function (cb) {
      cb(options);
    },
    set: function (opts) {}
  };

  /**
   * jetzt.setConfigBackend
   * Set the config 'backend' store. Should be an object with methods
   * void get(cb(opts))
   * void set(opts)
   */
  function setConfigBackend (backend) {
    configBackend = backend;
    backend.get(function (opts) {
      if (realTypeOf(opts) === 'Object') {
        options = recursiveExtend({}, options, opts);
      } else {
        throw new Error("bad config backend");
      }
    });
  };

  // recursive lookup
  function lookup (map, keyPath) {
    if (keyPath.length === 0) throw new Error("this should never happen");

    var key = keyPath[0];
    if (keyPath.length === 1) {
      if (!map.hasOwnProperty(key)) {
        console.warn("config lookup: no key '"+key+"'");
      }
      return map[key];
    } else {
      var submap = map[key];
      if (realTypeOf(submap) !== 'Object') {
        console.warn("config lookup: no key '"+key+"'");
        return;
      } else {
        return lookup(submap, keyPath.slice(1));
      }
    }
  }

  function put (map, keyPath, val) {
    if (keyPath.length === 0) throw new Error("this should never happen");

    var key = keyPath[0];
    if (keyPath.length === 1) {
      map[key] = val;
    } else {
      var submap = map[key];
      if (realTypeOf(submap) !== 'Object') {
        submap = {};
        map[key] = submap;
      }
      _put(submap, keyPath.slice(1), val);
    }
  }

  /**
   * jetzt.config
   * get and set config variables.
   *
   * e.g.
   *      jetzt.config("cheese", "Edam")
   *
   * sets the "cheese" option to the string "Edam"
   *
   *      jetzt.config("cheese")
   *
   *      => "edam"
   *
   * It also has support for key paths
   *
   *      jetzt.config(["cheese", "color"], "blue")
   *      jetzt.config(["cheese", "name"], "Stilton")
   *
   *      jetzt.config(["cheese", "name"])
   *
   *      => "Stilton"
   *
   *      jetzt.config("cheese")
   *
   *      => {color: "blue", name: "Stilton"}
   */
  function config (keyPath, val) {
    if (typeof keyPath === 'string') keyPath = [keyPath];

    if (typeof val === 'undefined') {
      return lookup(options, keyPath);
    } else {
      put(options, keyPath, val);
      configBackend.set(options);
    }
  }

  function modifier(mod) {
    return config(["modifiers", mod]) || 1;
  }

  function maxModifier(a, b) {
    if ((modifier(a) || 1) > (modifier(b) || 1)) {
      return a;
    } else {
      return b;
    }
  }
<commit_msg>Add `font_family` option in .view<commit_after>  /*
     $$$$$$\   $$$$$$\  $$\   $$\ $$$$$$$$\ $$$$$$\  $$$$$$\
    $$  __$$\ $$  __$$\ $$$\  $$ |$$  _____|\_$$  _|$$  __$$\
    $$ /  \__|$$ /  $$ |$$$$\ $$ |$$ |        $$ |  $$ /  \__|
    $$ |      $$ |  $$ |$$ $$\$$ |$$$$$\      $$ |  $$ |$$$$\
    $$ |      $$ |  $$ |$$ \$$$$ |$$  __|     $$ |  $$ |\_$$ |
    $$ |  $$\ $$ |  $$ |$$ |\$$$ |$$ |        $$ |  $$ |  $$ |
    \$$$$$$  | $$$$$$  |$$ | \$$ |$$ |      $$$$$$\ \$$$$$$  |
     \______/  \______/ \__|  \__|\__|      \______| \______/
  */

  var DEFAULT_OPTIONS = {
      target_wpm: 400,
      scale: 1,
      dark: false,
      modifiers: {
        normal: 1,
        start_clause: 1,
        end_clause: 1.8,
        start_sentence: 1.3,
        end_sentence: 2.2,
        start_paragraph: 2.0,
        end_paragraph: 2.8,
        short_space: 1.5,
        long_space: 2.2
      },
	  view : {
	  	selection_color : "red",
	  	font_family: "Georgia"
	  }
      // keybindings and so forth soon
  };

  var options = recursiveExtend({}, DEFAULT_OPTIONS);

  // placeholder config backend for when there is no real backend.
  var configBackend = {
    get: function (cb) {
      cb(options);
    },
    set: function (opts) {}
  };

  /**
   * jetzt.setConfigBackend
   * Set the config 'backend' store. Should be an object with methods
   * void get(cb(opts))
   * void set(opts)
   */
  function setConfigBackend (backend) {
    configBackend = backend;
    backend.get(function (opts) {
      if (realTypeOf(opts) === 'Object') {
        options = recursiveExtend({}, options, opts);
      } else {
        throw new Error("bad config backend");
      }
    });
  };

  // recursive lookup
  function lookup (map, keyPath) {
    if (keyPath.length === 0) throw new Error("this should never happen");

    var key = keyPath[0];
    if (keyPath.length === 1) {
      if (!map.hasOwnProperty(key)) {
        console.warn("config lookup: no key '"+key+"'");
      }
      return map[key];
    } else {
      var submap = map[key];
      if (realTypeOf(submap) !== 'Object') {
        console.warn("config lookup: no key '"+key+"'");
        return;
      } else {
        return lookup(submap, keyPath.slice(1));
      }
    }
  }

  function put (map, keyPath, val) {
    if (keyPath.length === 0) throw new Error("this should never happen");

    var key = keyPath[0];
    if (keyPath.length === 1) {
      map[key] = val;
    } else {
      var submap = map[key];
      if (realTypeOf(submap) !== 'Object') {
        submap = {};
        map[key] = submap;
      }
      _put(submap, keyPath.slice(1), val);
    }
  }

  /**
   * jetzt.config
   * get and set config variables.
   *
   * e.g.
   *      jetzt.config("cheese", "Edam")
   *
   * sets the "cheese" option to the string "Edam"
   *
   *      jetzt.config("cheese")
   *
   *      => "edam"
   *
   * It also has support for key paths
   *
   *      jetzt.config(["cheese", "color"], "blue")
   *      jetzt.config(["cheese", "name"], "Stilton")
   *
   *      jetzt.config(["cheese", "name"])
   *
   *      => "Stilton"
   *
   *      jetzt.config("cheese")
   *
   *      => {color: "blue", name: "Stilton"}
   */
  function config (keyPath, val) {
    if (typeof keyPath === 'string') keyPath = [keyPath];

    if (typeof val === 'undefined') {
      return lookup(options, keyPath);
    } else {
      put(options, keyPath, val);
      configBackend.set(options);
    }
  }

  function modifier(mod) {
    return config(["modifiers", mod]) || 1;
  }

  function maxModifier(a, b) {
    if ((modifier(a) || 1) > (modifier(b) || 1)) {
      return a;
    } else {
      return b;
    }
  }
<|endoftext|>