<commit_before>Facebook = {};

// Request Facebook credentials for the user
//
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
//   completion. Takes one argument, credentialToken on success, or Error on
//   error.
Facebook.requestCredential = function (options, credentialRequestCompleteCallback) {
  // support both (options, callback) and (callback).
  if (!credentialRequestCompleteCallback && typeof options === 'function') {
    credentialRequestCompleteCallback = options;
    options = {};
  }

  var config = ServiceConfiguration.configurations.findOne({service: 'facebook'});
  if (!config) {
    credentialRequestCompleteCallback && credentialRequestCompleteCallback(
      new ServiceConfiguration.ConfigError());
    return;
  }

  var credentialToken = Random.secret();
  var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent);
  var display = mobile ? 'touch' : 'popup';

  var scope = "email";
  if (options && options.requestPermissions)
    scope = options.requestPermissions.join(',');

  var loginStyle = OAuth._loginStyle('facebook', config, options);

  var loginUrl =
        'https://www.facebook.com/v2.2/dialog/oauth?client_id=' + config.appId +
        '&redirect_uri=' + OAuth._redirectUri('facebook', config) +
        '&display=' + display + '&scope=' + scope +
        '&state=' + OAuth._stateParam(loginStyle, credentialToken, options && options.redirectUrl);

  // Handle authentication type (e.g. for force login you need authType: "reauthenticate")
  if (options.authType) {
    loginUrl += "&authType=" + encodeURIComponent(options.authType);
  }

  OAuth.launchLogin({
    loginService: "facebook",
    loginStyle: loginStyle,
    loginUrl: loginUrl,
    credentialRequestCompleteCallback: credentialRequestCompleteCallback,
    credentialToken: credentialToken
  });
};
<commit_msg>Adds truthness check b4 accessing property in facebook package. Fixes #7255<commit_after>Facebook = {};

// Request Facebook credentials for the user
//
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
//   completion. Takes one argument, credentialToken on success, or Error on
//   error.
Facebook.requestCredential = function (options, credentialRequestCompleteCallback) {
  // support both (options, callback) and (callback).
  if (!credentialRequestCompleteCallback && typeof options === 'function') {
    credentialRequestCompleteCallback = options;
    options = {};
  }

  var config = ServiceConfiguration.configurations.findOne({service: 'facebook'});
  if (!config) {
    credentialRequestCompleteCallback && credentialRequestCompleteCallback(
      new ServiceConfiguration.ConfigError());
    return;
  }

  var credentialToken = Random.secret();
  var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent);
  var display = mobile ? 'touch' : 'popup';

  var scope = "email";
  if (options && options.requestPermissions)
    scope = options.requestPermissions.join(',');

  var loginStyle = OAuth._loginStyle('facebook', config, options);

  var loginUrl =
        'https://www.facebook.com/v2.2/dialog/oauth?client_id=' + config.appId +
        '&redirect_uri=' + OAuth._redirectUri('facebook', config) +
        '&display=' + display + '&scope=' + scope +
        '&state=' + OAuth._stateParam(loginStyle, credentialToken, options && options.redirectUrl);

  // Handle authentication type (e.g. for force login you need authType: "reauthenticate")
  if (options && options.authType) {
    loginUrl += "&authType=" + encodeURIComponent(options.authType);
  }

  OAuth.launchLogin({
    loginService: "facebook",
    loginStyle: loginStyle,
    loginUrl: loginUrl,
    credentialRequestCompleteCallback: credentialRequestCompleteCallback,
    credentialToken: credentialToken
  });
};
<|endoftext|>


<commit_before>/*
  Diaspora* Easyshare
  Copyright (C) 2013 arlo gn

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

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

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

var easyshare = {

  prefs: {},
  youtube: {},

  $: function (id) {

    return document.getElementById(id);

  },

  /*
    Populate the panel
  */
  populate: function (data) {

    var range = document.createRange(),
        documentFragment = range.createContextualFragment(data.node),
        thumb = this.$('thumb');

    if (!thumb)
      this.$('thumbwrap').appendChild(documentFragment);
    else
      this.$('thumbwrap').replaceChild(documentFragment, thumb);

    this.$('title').value = data.title;
    this.$('url').value = data.url;
    this.$('text').value = data.text;
    this.$('tags').value = '';
    this.youtube = { video: data.video, videoUrl: data.videoUrl };
  },

  /*
    Shorten URL via bit.ly api
  */
  shortify: function () {

    var LOGIN = this.prefs.bitlyLogin || "diasporaeasyshare";
    var APIKEY = this.prefs.bitlyApikey || "R_5ab4e2e8e9ad46c746079a9933596bec";

    var url = this.$('url'),
        longURL = url.value,
        bitlyURL = "http://api.bitly.com/v3/shorten?apiKey=" + APIKEY +
                   "&login=" + LOGIN +
                   "&longUrl=" + encodeURIComponent(longURL) +
                   "&format=json";

    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          var jsObj = JSON.parse(xhr.responseText);
          if (jsObj.status_txt == "OK") {
            url.value = jsObj.data.url;
          } else {
            url.value = "(" + jsObj.status_code + ") " + jsObj.status_txt;
            setTimeout(function () {
              url.value = longURL;
            }, 2000);
          }
        } else {
          url.value = "ERROR " + xhr.status;
          setTimeout(function () {
            url.value = longURL;
          }, 2000);
        }
      }
    }

    xhr.open('GET', bitlyURL, true);
    xhr.send(null);

  },

  /*
    Add emphasis to entered text
  */
  markdownify: function () {

    var t = this.$('text'),
        s = t.value;
    if (s.length > 0 && s.indexOf('_') != 0)
      t.value = s.trim().replace(/[\\_\*]/g, '\\$&').replace(/^([\s\S]*)$/i, '_$1_');

  },

  /*
    Params (@title,@url) to share images as image/title/text/tags
  */
  image_params: function (title, text, tags) {

    var url = encodeURIComponent(this.$('url').value),
        img = "[![Image](" + encodeURIComponent(this.$('thumb')
            .getAttribute('src')) + ")](" + url + ")",
        params = { title: "?title=", url: "" };
    title.length > 0 ?
            params.title += img + "
 **" + encodeURIComponent(title) +
            "**
[" + url + "](" + url + ")" :
            params.title += img;
    if (text.length > 0) params.title += "

" + encodeURIComponent(text);
    if (tags) params.title += "

" + encodeURIComponent(tags);
    this.prefs && this.prefs.viaEasyshare ?
  	         params.url += "
&url=[via Easyshare](http://j.mp/XmyxIA)

" :
  	         params.url += "&url=

";

  	 return params;

  },

  /*
    Params (@title,@url) to share youtube videos as title/text/tags/video
  */
  video_params: function (title, text, tags) {

    var params = { title: "?title=", url: "&url=" };
    if (title.length > 0) params.title += "**" + encodeURIComponent(title) + "**";
  	 if (text.length > 0) params.title += "
" + encodeURIComponent(text);
  	 if (tags) params.title += "

" + encodeURIComponent(tags);
  	 this.prefs && this.prefs.viaEasyshare ?
            params.title += "
[via Easyshare](http://j.mp/XmyxIA)

" :
            params.title += "

";
    params.url += this.youtube.videoUrl;

  	 return params;

  },

  /*
    Send to Diaspora via publisher bookmarklet
  */
  send: function () {

    if (this.prefs.podURL == "") {
      var w = "WARNING!\nYou have not entered the URL of your Diaspora* pod.\n" +
              "Go to Firefox > Addons > Extensions > Diaspora* Easyshare > Preferences\n" +
              "and enter the URL (e.g. https://yourpod.com).";
      return alert(w);
    }

    var title  = this.$('title').value,
        text   = this.$('text').value,
        tags   = this.$('tags').value,
        params = {};

    tags.length > 0 ?
        tags = tags.replace(/\s+/g, '')
  	                .replace(/^(.+)$/g, '#$1')
  	                .replace(/,/g, ' #')
  	                .replace(/##/g, '#') :
  	     tags = null;

  	 this.youtube && this.youtube.video ? params = this.video_params(title, text, tags) :
  	 												  params = this.image_params(title, text, tags);

    var URL = this.prefs.podURL + "/bookmarklet" + params.title + "" + params.url;

    if (!window.open(URL + "&v=1&noui=1&jump=doclose", "diasporav1",
      "location=yes,links=no,scrollbars=no,toolbar=no,width=600,height=" +
      this.prefs.publisherHeight.toString()))
      location.href = URL + "jump=yes";

  },

  /*
    Initialize
  */
  init: function () {

    self.port.on('show', function (data) {
      easyshare.populate(data);
    });

    self.port.on('prefs', function (prefs) {
      easyshare.prefs = prefs;
    });

    this.$('send').addEventListener('click', function () { easyshare.send() }, false);
    this.$('shorturl').addEventListener('click', function (e) {
      easyshare.shortify();
      e.preventDefault();
    }, false);
    this.$('emphasis').addEventListener('click', function (e) {
      easyshare.markdownify();
      e.preventDefault();
    }, false);

  }

};

window.addEventListener('load', function () { easyshare.init() }, false);
<commit_msg>Share video & markdown emphasis<commit_after>/*
  Diaspora* Easyshare
  Copyright (C) 2013 arlo gn

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

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

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

var easyshare = {

  prefs: {},
  youtube: {},

  $: function (id) {

    return document.getElementById(id);

  },

  /*
    Populate the panel
  */
  populate: function (data) {

    var range = document.createRange(),
        documentFragment = range.createContextualFragment(data.node),
        thumb = this.$('thumb');

    if (!thumb)
      this.$('thumbwrap').appendChild(documentFragment);
    else
      this.$('thumbwrap').replaceChild(documentFragment, thumb);

    this.$('title').value = data.title;
    this.$('url').value = data.url;
    this.$('text').value = data.text;
    this.$('tags').value = '';
    this.youtube = { video: data.video, videoUrl: data.videoUrl };
  },

  /*
    Shorten URL via bit.ly api
  */
  shortify: function () {

    var LOGIN = this.prefs.bitlyLogin || "diasporaeasyshare";
    var APIKEY = this.prefs.bitlyApikey || "R_5ab4e2e8e9ad46c746079a9933596bec";

    var url = this.$('url'),
        longURL = url.value,
        bitlyURL = "http://api.bitly.com/v3/shorten?apiKey=" + APIKEY +
                   "&login=" + LOGIN +
                   "&longUrl=" + encodeURIComponent(longURL) +
                   "&format=json";

    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          var jsObj = JSON.parse(xhr.responseText);
          if (jsObj.status_txt == "OK") {
            url.value = jsObj.data.url;
          } else {
            url.value = "(" + jsObj.status_code + ") " + jsObj.status_txt;
            setTimeout(function () {
              url.value = longURL;
            }, 2000);
          }
        } else {
          url.value = "ERROR " + xhr.status;
          setTimeout(function () {
            url.value = longURL;
          }, 2000);
        }
      }
    }

    xhr.open('GET', bitlyURL, true);
    xhr.send(null);

  },

  /*
    Add emphasis to entered text
  */
  markdownify: function () {

    var t = this.$('text'),
        s = t.value;
    if (s.length > 0 && s.indexOf('_') != 0)
      t.value = s.trim().replace(/[\\_\*]/g, '\\$&').replace(/^([\s\S]*)$/i, '_$1_');

  },

  /*
    Params (@title,@url) to share images as image/title/text/tags
  */
  image_params: function (title, text, tags) {

    var url = encodeURIComponent(this.$('url').value),
        img = "[![Image](" + encodeURIComponent(this.$('thumb')
            .getAttribute('src')) + ")](" + url + ")",
        params = { title: "?title=", url: "" };
    title.length > 0 ?
            params.title += img + "
 **" + encodeURIComponent(title) +
            "**
[" + url + "](" + url + ")" :
            params.title += img;
    if (text.length > 0) params.title += "

" + encodeURIComponent(text);
    if (tags) params.title += "

" + encodeURIComponent(tags);
    this.prefs && this.prefs.viaEasyshare ?
  	         params.url += "
&url=[via Easyshare](http://j.mp/XmyxIA)

" :
  	         params.url += "&url=

";

    return params;

  },

  /*
    Params (@title,@url) to share youtube videos as title/text/tags/video
  */
  video_params: function (title, text, tags) {

    var params = { title: "?title=", url: "&url=" };
    if (title.length > 0) params.title += "**" + encodeURIComponent(title) + "**";
  	if (text.length > 0) params.title += "
" + encodeURIComponent(text);
  	if (tags) params.title += "

" + encodeURIComponent(tags);
  	this.prefs && this.prefs.viaEasyshare ?
            params.title += "
[via Easyshare](http://j.mp/XmyxIA)

" :
            params.title += "

";
    params.url += this.youtube.videoUrl;

  	return params;

  },

  /*
    Send to Diaspora via publisher bookmarklet
  */
  send: function () {

    if (this.prefs.podURL == "") {
      var w = "WARNING!\nYou have not entered the URL of your Diaspora* pod.\n" +
              "Go to Firefox > Addons > Extensions > Diaspora* Easyshare > Preferences\n" +
              "and enter the URL (e.g. https://yourpod.com).";
      return alert(w);
    }

    var title  = this.$('title').value,
        text   = this.$('text').value,
        tags   = this.$('tags').value,
        params = {};

    tags.length > 0 ?
        tags = tags.replace(/\s+/g, '')
  	               .replace(/^(.+)$/g, '#$1')
  	               .replace(/,/g, ' #')
  	               .replace(/##/g, '#') :
        tags = null;

  	 this.youtube && this.youtube.video ? params = this.video_params(title, text, tags) :
                                          params = this.image_params(title, text, tags);

    var URL = this.prefs.podURL + "/bookmarklet" + params.title + "" + params.url;

    if (!window.open(URL + "&v=1&noui=1&jump=doclose", "diasporav1",
      "location=yes,links=no,scrollbars=no,toolbar=no,width=600,height=" +
      this.prefs.publisherHeight.toString()))
      location.href = URL + "jump=yes";

  },

  /*
    Initialize
  */
  init: function () {

    self.port.on('show', function (data) {
      easyshare.populate(data);
    });

    self.port.on('prefs', function (prefs) {
      easyshare.prefs = prefs;
    });

    this.$('send').addEventListener('click', function () { easyshare.send() }, false);
    this.$('shorturl').addEventListener('click', function (e) {
      easyshare.shortify();
      e.preventDefault();
    }, false);
    this.$('emphasis').addEventListener('click', function (e) {
      easyshare.markdownify();
      e.preventDefault();
    }, false);

  }

};

window.addEventListener('load', function () { easyshare.init() }, false);
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com
 * @author stewdio / http://stewd.io
 */

ViveController = function ( id ) {

	THREE.Object3D.call( this );

	var scope = this;
	var gamepad;

	var axes = [ 0, 0 ];
	var thumbpadIsPressed = false;
	var triggerIsPressed = false;
	var gripsArePressed = false;
	var menuIsPressed = false;

	function findGamepad( id ) {

		// Iterate across gamepads as Vive Controllers may not be
		// in position 0 and 1.

		var gamepads = navigator.getGamepads && navigator.getGamepads();

		for ( var i = 0, j = 0; i < gamepads.length; i ++ ) {

			var gamepad = gamepads[ i ];

			if ( gamepad && ( gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || gamepad.id.startsWith( 'Spatial Controller' ) ) ) {

				if ( j === id ) return gamepad;

				j ++;

			}

		}

	}

	this.matrixAutoUpdate = false;

	this.getGamepad = function () {
		//console.log("Gamepad: " + gamepad);
		return gamepad;

	};

	this.getButtonState = function ( button ) {

		if ( button === 'thumbpad' ) return thumbpadIsPressed;
		if ( button === 'trigger' ) return triggerIsPressed;
		if ( button === 'grips' ) return gripsArePressed;
		if ( button === 'menu' ) return menuIsPressed;

	};

	this.update = function () {

		gamepad = findGamepad( id );

		if ( gamepad !== undefined && gamepad.pose !== undefined ) {

			if ( gamepad.pose === null ) return; // No user action yet

			//  Position and orientation.

			var pose = gamepad.pose;

			//adjust y position here, because controllers else are too low
			if ( pose.position !== null ) scope.position.fromArray( [pose.position[0], pose.position[1] + 0.80, pose.position[2]] );
			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
			scope.matrixWorldNeedsUpdate = true;
			scope.visible = true;

			//  Thumbpad and Buttons.

			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {

				axes[ 0 ] = gamepad.axes[ 0 ]; //  X axis: -1 = Left, +1 = Right.
				axes[ 1 ] = gamepad.axes[ 1 ]; //  Y axis: -1 = Bottom, +1 = Top.
				scope.dispatchEvent( { type: 'axischanged', axes: axes } );

			}

			if ( thumbpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {

				thumbpadIsPressed = gamepad.buttons[ 0 ].pressed;
				scope.dispatchEvent( { type: thumbpadIsPressed ? 'thumbpaddown' : 'thumbpadup', axes: axes } );

			}

			if ( triggerIsPressed !== gamepad.buttons[ 1 ].pressed ) {

				triggerIsPressed = gamepad.buttons[ 1 ].pressed;
				scope.dispatchEvent( { type: triggerIsPressed ? 'triggerdown' : 'triggerup' } );

			}

/*
			if ( gripsArePressed !== gamepad.buttons[ 2 ].pressed ) {

				gripsArePressed = gamepad.buttons[ 2 ].pressed;
				scope.dispatchEvent( { type: gripsArePressed ? 'gripsdown' : 'gripsup' } );

			}*/

			if ( menuIsPressed !== gamepad.buttons[ 3 ].pressed ) {

				menuIsPressed = gamepad.buttons[ 3 ].pressed;
				scope.dispatchEvent( { type: menuIsPressed ? 'menudown' : 'menuup' } );

			}

		} else {

			scope.visible = false;

		}

	};

};

ViveController.prototype = Object.create( THREE.Object3D.prototype );
ViveController.prototype.constructor = THREE.ViveController;
<commit_msg>Fix controller y-positions<commit_after>/**
 * @author mrdoob / http://mrdoob.com
 * @author stewdio / http://stewd.io
 */

ViveController = function ( id ) {

	THREE.Object3D.call( this );

	var scope = this;
	var gamepad;

	var axes = [ 0, 0 ];
	var thumbpadIsPressed = false;
	var triggerIsPressed = false;
	var gripsArePressed = false;
	var menuIsPressed = false;

	function findGamepad( id ) {

		// Iterate across gamepads as Vive Controllers may not be
		// in position 0 and 1.

		var gamepads = navigator.getGamepads && navigator.getGamepads();

		for ( var i = 0, j = 0; i < gamepads.length; i ++ ) {

			var gamepad = gamepads[ i ];

			if ( gamepad && ( gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || gamepad.id.startsWith( 'Spatial Controller' ) ) ) {

				if ( j === id ) return gamepad;

				j ++;

			}

		}

	}

	this.matrixAutoUpdate = false;

	this.getGamepad = function () {
		//console.log("Gamepad: " + gamepad);
		return gamepad;

	};

	this.getButtonState = function ( button ) {

		if ( button === 'thumbpad' ) return thumbpadIsPressed;
		if ( button === 'trigger' ) return triggerIsPressed;
		if ( button === 'grips' ) return gripsArePressed;
		if ( button === 'menu' ) return menuIsPressed;

	};

	this.update = function () {

		gamepad = findGamepad( id );

		if ( gamepad !== undefined && gamepad.pose !== undefined ) {

			if ( gamepad.pose === null ) return; // No user action yet

			//  Position and orientation.

			var pose = gamepad.pose;

			//adjust y position here, because controllers else are too low
			if ( pose.position !== null ) scope.position.fromArray( [pose.position[0], pose.position[1], pose.position[2]] );
			if(gamepad.id.startsWith( 'Oculus Touch' )) {
				scope.position.y += 1.61;
			} else {
				scope.position.y += 0.8;
			}
			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
			scope.matrixWorldNeedsUpdate = true;
			scope.visible = true;

			//  Thumbpad and Buttons.

			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {

				axes[ 0 ] = gamepad.axes[ 0 ]; //  X axis: -1 = Left, +1 = Right.
				axes[ 1 ] = gamepad.axes[ 1 ]; //  Y axis: -1 = Bottom, +1 = Top.
				scope.dispatchEvent( { type: 'axischanged', axes: axes } );

			}

			if ( thumbpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {

				thumbpadIsPressed = gamepad.buttons[ 0 ].pressed;
				scope.dispatchEvent( { type: thumbpadIsPressed ? 'thumbpaddown' : 'thumbpadup', axes: axes } );

			}

			if ( triggerIsPressed !== gamepad.buttons[ 1 ].pressed ) {

				triggerIsPressed = gamepad.buttons[ 1 ].pressed;
				scope.dispatchEvent( { type: triggerIsPressed ? 'triggerdown' : 'triggerup' } );

			}

/*
			if ( gripsArePressed !== gamepad.buttons[ 2 ].pressed ) {

				gripsArePressed = gamepad.buttons[ 2 ].pressed;
				scope.dispatchEvent( { type: gripsArePressed ? 'gripsdown' : 'gripsup' } );

			}*/

			if ( menuIsPressed !== gamepad.buttons[ 3 ].pressed ) {

				menuIsPressed = gamepad.buttons[ 3 ].pressed;
				scope.dispatchEvent( { type: menuIsPressed ? 'menudown' : 'menuup' } );

			}

		} else {

			scope.visible = false;

		}

	};

};

ViveController.prototype = Object.create( THREE.Object3D.prototype );
ViveController.prototype.constructor = THREE.ViveController;
<|endoftext|>


<commit_before>const { darken } = require('postcss-js-mixins/lib/colorHelpers');

let variables = {};

variables.unit = {
	default: 'rem',
	fontSize: 'rem',
	lineHeight: 'em'
};

variables.root = {
	fontSize: '62.5%'
};

variables.default = {
	radius: '3px',
	opacity: 0.2,
	duration: '0.2s',
	timing: 'ease-in-out',
	delay: '0s'
};

variables.width = {
	min: 0,
	max: '1280px'
};

variables.bumper = {
	enabled: true,
	padding: '6%'
};

variables.block = {
	margin: {
		bottom: '4rem'
	}
};

variables.grid = {
	margin: '5%',
	columns: 8,
	spaceless: false
};

variables.colors = {
	primary: '#349bb9',
	secondary: '#70c1b3',
	tertiary: '#f18f01',
	info: '#00f',
	success: '#008000',
	warning: '#f00',
	white: '#fff',
	lightestGray: darken('#fff', 4),
	lighterGray: darken('#fff', 10),
	lightGray: darken('#fff', 25),
	gray: darken('#fff', 35),
	darkGray: darken('#fff', 55),
	darkerGray: darken('#fff', 65),
	darkestGray: darken('#fff', 75),
	black: '#000'
};

variables.colors.body = {
	background: variables.colors.white
};

variables.font = {
	color: variables.colors.darkestGray,
	family: 'Arial, Helvetica, sans-serif',
	size: '1.6rem',
	weight: {
		normal: 'normal',
		bold: 'bold'
	},
	lineHeight: '1em'
};

variables.heading = {
	color: variables.font.color,
	family: 'Tahoma, Geneva, sans-serif',
	weight: variables.font.weight.bold,
	lineHeight: '1.4em',
	margin: {
		bottom: '2rem'
	}
};

variables.h1 = '3.6rem';
variables.h2 = '3.2rem';
variables.h3 = '2.8rem';
variables.h4 = '2.4rem';
variables.h5 = '2rem';
variables.h6 = '1.6rem';

variables.mark = {
	color: variables.font.color,
	background: 'yellow'
};

variables.abbr = {
	underline: 'dotted'
};

variables.border = {
	color: variables.colors.lightGray,
	style: 'solid',
	width: '1px'
};

variables.paragraph = {
	color: variables.font.color,
	weight: variables.font.weight.normal,
	lineHeight: '1.7em',
	margin: {
		bottom: '2rem'
	}
};

variables.figure = {
	border: {
		color: false,
		radius: false
	},
	padding: variables.block.margin.bottom
};

variables.figCaption = {
	color: variables.colors.darkGray,
	style: 'italic',
	lineHeight: variables.paragraph.lineHeight
};

variables.link = {
	color: variables.colors.primary,
	decoration: 'none'
};

variables.link.hover = {
	color: darken(variables.link.color, 10),
	decoration: 'none'
};

variables.link.active = {
	color: darken(variables.link.color, 20)
};

variables.selection = {
	color: variables.colors.white,
	background: variables.link.color
};

variables.small = {
	size: '0.8em'
};

variables.quote = {
	color: variables.colors.darkestGray,
	family: 'Georgia, Times, serif',
	size: '2rem',
	style: 'italic',
	weight: 'normal',
	lineHeight: '1.4em',
	padding: {
		horizontal: '2em',
		vertical: '1em'
	}
};

variables.cite = {
	color: variables.colors.gray,
	family: variables.font.family,
	size: '1.8rem',
	style: 'normal',
	weight: 'normal',
	lineHeight: '1.2em',
	margin: {
		top: '1.4rem'
	},
	indicator: "'\\2014\\00a0'"
};

variables.rule = {
	color: variables.colors.lightGray,
	height: '1px',
	style: 'solid',
	margin: {
		vertical: variables.block.margin.bottom
	}
};

variables.address = {
	color: variables.colors.darkestGray,
	family: variables.font.family,
	size: variables.font.size,
	weight: 'normal',
	style: 'normal',
	lineHeight: variables.paragraph.lineHeight
};

variables.list = {
	color: variables.paragraph.color,
	lineHeight: variables.paragraph.lineHeight,
	margin: {
		bottom: variables.paragraph.margin.bottom,
		left: false
	},
	bullet: {
		style: 'disc',
		position: 'inside'
	}
};

variables.nestedList = {
	margin: {
		left: '2rem'
	}
};

variables.li = {
	margin: {
		bottom: '0.2rem'
	}
};

variables.dl = {
	margin: {
		bottom: variables.block.margin.bottom
	}
};

variables.dt = {
	color: variables.colors.darkerGray,
	family: variables.heading.family,
	size: '2rem',
	margin: {
		bottom: '0.2rem'
	}
};

variables.dd = {
	color: variables.colors.gray,
	family: variables.font.family,
	size: variables.font.size,
	margin: {
		bottom: '1rem'
	}
};

variables.print = {
	page: {
		margin: '2cm .5cm'
	}
};

variables.button = {
	color: variables.colors.white,
	family: variables.font.family,
	size: variables.font.size,
	weight: 'normal',
	padding: {
		horizontal: '3rem',
		vertical: '1.3rem'
	},
	margin: {
		bottom: 0
	},
	transition: {
		property: 'background-color',
		duration: '0.2s'
	},
	background: variables.colors.darkGray,
	border: {
		color: false,
		radius: variables.default.radius,
		width: 0
	}
};

variables.button.hover = {
	background: darken(variables.button.background, 5)
};

variables.button.active = {
	background: darken(variables.button.background, 10),
	transition: {
		property: 'none'
	}
};

variables.coloredButton = {
	class: '.colored-button',
	color: variables.colors.white,
	background: variables.link.color,
	border: {
		color: false,
		radius: variables.button.border.radius,
		width: variables.button.border.width
	}
};

variables.coloredButton.hover = {
	background: darken(variables.coloredButton.background, 5)
};

variables.coloredButton.active = {
	background: darken(variables.coloredButton.background, 10)
};

variables.button.disabled = {
	modifier: '.-is-disabled',
	color: variables.colors.darkGray,
	background: variables.colors.lightGray,
	border: {
		color: false
	},
	cursor: 'not-allowed'
};

variables.code = {
	color: variables.colors.darkestGray,
	family: 'monospace',
	size: variables.font.size,
	lineHeight: '1.4em',
	background: variables.colors.lighterGray,
	border: {
		color: false,
		radius: false
	},
	padding: {
		horizontal: '0.5em',
		vertical: '0.2em'
	},
	rounded: false
};

variables.code.block = {
	color: variables.colors.lightestGray,
	family: variables.code.family,
	size: '1.3rem',
	lineHeight: variables.paragraph.lineHeight,
	tabSize: 4,
	wrap: false,
	margin: {
		bottom: variables.block.margin.bottom
	},
	background: variables.colors.darkestGray,
	border: {
		color: variables.code.border.color,
		radius: false
	},
	padding: {
		horizontal: '2rem',
		vertical: '1.4rem'
	},
	rounded: false
};

variables.table = {
	size: variables.font.size,
	cell: {
		borderColor: variables.color.lighterGray,
		lineHeight: variables.paragraph.lineHeight,
		padding: {
			horizontal: '1.6rem',
			vertical: '.6rem'
		}
	},
	caption: {
		background: variables.color.lightestGray,
		style: 'italic',
		padding: {
			horizontal: variables.table.cell.padding.horizontal,
			vertical: '1.2rem'
		}
	},
	striped: {
		background: variables.colors.lightestGray,
		position: 'odd'
	}
};

module.exports = variables;<commit_msg>Update table variables<commit_after>const { darken } = require('postcss-js-mixins/lib/colorHelpers');

let variables = {};

variables.unit = {
	default: 'rem',
	fontSize: 'rem',
	lineHeight: 'em'
};

variables.root = {
	fontSize: '62.5%'
};

variables.default = {
	radius: '3px',
	opacity: 0.2,
	duration: '0.2s',
	timing: 'ease-in-out',
	delay: '0s'
};

variables.width = {
	min: 0,
	max: '1280px'
};

variables.bumper = {
	enabled: true,
	padding: '6%'
};

variables.block = {
	margin: {
		bottom: '4rem'
	}
};

variables.grid = {
	margin: '5%',
	columns: 8,
	spaceless: false
};

variables.colors = {
	primary: '#349bb9',
	secondary: '#70c1b3',
	tertiary: '#f18f01',
	info: '#00f',
	success: '#008000',
	warning: '#f00',
	white: '#fff',
	lightestGray: darken('#fff', 4),
	lighterGray: darken('#fff', 10),
	lightGray: darken('#fff', 25),
	gray: darken('#fff', 35),
	darkGray: darken('#fff', 55),
	darkerGray: darken('#fff', 65),
	darkestGray: darken('#fff', 75),
	black: '#000'
};

variables.colors.body = {
	background: variables.colors.white
};

variables.font = {
	color: variables.colors.darkestGray,
	family: 'Arial, Helvetica, sans-serif',
	size: '1.6rem',
	weight: {
		normal: 'normal',
		bold: 'bold'
	},
	lineHeight: '1em'
};

variables.heading = {
	color: variables.font.color,
	family: 'Tahoma, Geneva, sans-serif',
	weight: variables.font.weight.bold,
	lineHeight: '1.4em',
	margin: {
		bottom: '2rem'
	}
};

variables.h1 = '3.6rem';
variables.h2 = '3.2rem';
variables.h3 = '2.8rem';
variables.h4 = '2.4rem';
variables.h5 = '2rem';
variables.h6 = '1.6rem';

variables.mark = {
	color: variables.font.color,
	background: 'yellow'
};

variables.abbr = {
	underline: 'dotted'
};

variables.border = {
	color: variables.colors.lightGray,
	style: 'solid',
	width: '1px'
};

variables.paragraph = {
	color: variables.font.color,
	weight: variables.font.weight.normal,
	lineHeight: '1.7em',
	margin: {
		bottom: '2rem'
	}
};

variables.figure = {
	border: {
		color: false,
		radius: false
	},
	padding: variables.block.margin.bottom
};

variables.figCaption = {
	color: variables.colors.darkGray,
	style: 'italic',
	lineHeight: variables.paragraph.lineHeight
};

variables.link = {
	color: variables.colors.primary,
	decoration: 'none'
};

variables.link.hover = {
	color: darken(variables.link.color, 10),
	decoration: 'none'
};

variables.link.active = {
	color: darken(variables.link.color, 20)
};

variables.selection = {
	color: variables.colors.white,
	background: variables.link.color
};

variables.small = {
	size: '0.8em'
};

variables.quote = {
	color: variables.colors.darkestGray,
	family: 'Georgia, Times, serif',
	size: '2rem',
	style: 'italic',
	weight: 'normal',
	lineHeight: '1.4em',
	padding: {
		horizontal: '2em',
		vertical: '1em'
	}
};

variables.cite = {
	color: variables.colors.gray,
	family: variables.font.family,
	size: '1.8rem',
	style: 'normal',
	weight: 'normal',
	lineHeight: '1.2em',
	margin: {
		top: '1.4rem'
	},
	indicator: "'\\2014\\00a0'"
};

variables.rule = {
	color: variables.colors.lightGray,
	height: '1px',
	style: 'solid',
	margin: {
		vertical: variables.block.margin.bottom
	}
};

variables.address = {
	color: variables.colors.darkestGray,
	family: variables.font.family,
	size: variables.font.size,
	weight: 'normal',
	style: 'normal',
	lineHeight: variables.paragraph.lineHeight
};

variables.list = {
	color: variables.paragraph.color,
	lineHeight: variables.paragraph.lineHeight,
	margin: {
		bottom: variables.paragraph.margin.bottom,
		left: false
	},
	bullet: {
		style: 'disc',
		position: 'inside'
	}
};

variables.nestedList = {
	margin: {
		left: '2rem'
	}
};

variables.li = {
	margin: {
		bottom: '0.2rem'
	}
};

variables.dl = {
	margin: {
		bottom: variables.block.margin.bottom
	}
};

variables.dt = {
	color: variables.colors.darkerGray,
	family: variables.heading.family,
	size: '2rem',
	margin: {
		bottom: '0.2rem'
	}
};

variables.dd = {
	color: variables.colors.gray,
	family: variables.font.family,
	size: variables.font.size,
	margin: {
		bottom: '1rem'
	}
};

variables.print = {
	page: {
		margin: '2cm .5cm'
	}
};

variables.button = {
	color: variables.colors.white,
	family: variables.font.family,
	size: variables.font.size,
	weight: 'normal',
	padding: {
		horizontal: '3rem',
		vertical: '1.3rem'
	},
	margin: {
		bottom: 0
	},
	transition: {
		property: 'background-color',
		duration: '0.2s'
	},
	background: variables.colors.darkGray,
	border: {
		color: false,
		radius: variables.default.radius,
		width: 0
	}
};

variables.button.hover = {
	background: darken(variables.button.background, 5)
};

variables.button.active = {
	background: darken(variables.button.background, 10),
	transition: {
		property: 'none'
	}
};

variables.coloredButton = {
	class: '.colored-button',
	color: variables.colors.white,
	background: variables.link.color,
	border: {
		color: false,
		radius: variables.button.border.radius,
		width: variables.button.border.width
	}
};

variables.coloredButton.hover = {
	background: darken(variables.coloredButton.background, 5)
};

variables.coloredButton.active = {
	background: darken(variables.coloredButton.background, 10)
};

variables.button.disabled = {
	modifier: '.-is-disabled',
	color: variables.colors.darkGray,
	background: variables.colors.lightGray,
	border: {
		color: false
	},
	cursor: 'not-allowed'
};

variables.code = {
	color: variables.colors.darkestGray,
	family: 'monospace',
	size: variables.font.size,
	lineHeight: '1.4em',
	background: variables.colors.lighterGray,
	border: {
		color: false,
		radius: false
	},
	padding: {
		horizontal: '0.5em',
		vertical: '0.2em'
	},
	rounded: false
};

variables.code.block = {
	color: variables.colors.lightestGray,
	family: variables.code.family,
	size: '1.3rem',
	lineHeight: variables.paragraph.lineHeight,
	tabSize: 4,
	wrap: false,
	margin: {
		bottom: variables.block.margin.bottom
	},
	background: variables.colors.darkestGray,
	border: {
		color: variables.code.border.color,
		radius: false
	},
	padding: {
		horizontal: '2rem',
		vertical: '1.4rem'
	},
	rounded: false
};

variables.table = {
	size: variables.font.size,
	cell: {
		borderColor: variables.colors.lighterGray,
		lineHeight: variables.paragraph.lineHeight,
		padding: {
			horizontal: '1.6rem',
			vertical: '.6rem'
		}
	},
	striped: {
		background: variables.colors.lightestGray,
		position: 'odd'
	}
};

variables.table.caption = {
	background: variables.colors.lightestGray,
	style: 'italic',
	padding: {
		horizontal: variables.table.cell.padding.horizontal,
		vertical: '1.2rem'
	}
};

module.exports = variables;<|endoftext|>


<commit_before>//@flow

import invariant from "invariant";
import browserslist from "browserslist";
import builtInsList from "../data/built-ins.json";
import { defaultWebIncludes } from "./default-includes";
import moduleTransformations from "./module-transformations";
import pluginsList from "../data/plugins.json";
import type { Targets, Options, ModuleOption, BuiltInsOption } from "./types";

const validIncludesAndExcludes = new Set([
  ...Object.keys(pluginsList),
  ...Object.keys(moduleTransformations).map(m => moduleTransformations[m]),
  ...Object.keys(builtInsList),
  ...defaultWebIncludes,
]);

export const validateIncludesAndExcludes = (
  opts: Array<string> = [],
  type: string,
): Array<string> => {
  invariant(
    Array.isArray(opts),
    `Invalid Option: The '${type}' option must be an Array<String> of plugins/built-ins`,
  );

  const unknownOpts = opts.filter(opt => !validIncludesAndExcludes.has(opt));

  invariant(
    unknownOpts.length === 0,
    `Invalid Option: The plugins/built-ins '${unknownOpts.join(
      ", ",
    )}' passed to the '${type}' option are not
    valid. Please check data/[plugin-features|built-in-features].js in babel-preset-env`,
  );

  return opts;
};

const validBrowserslistTargets = [
  ...Object.keys(browserslist.data),
  ...Object.keys(browserslist.aliases),
];

export const normalizePluginName = (plugin: string): string =>
  plugin.replace(/^babel-plugin-/, "");

export const normalizePluginNames = (plugins: Array<string>): Array<string> =>
  plugins.map(normalizePluginName);

export const checkDuplicateIncludeExcludes = (
  include: Array<string> = [],
  exclude: Array<string> = [],
): void => {
  const duplicates: Array<string> = include.filter(
    opt => exclude.indexOf(opt) >= 0,
  );

  invariant(
    duplicates.length === 0,
    `Invalid Option: The plugins/built-ins '${duplicates.join(
      ", ",
    )}' were found in both the "include" and
    "exclude" options.`,
  );
};

export const validateConfigPathOption = (
  configPath: string = process.cwd(),
) => {
  invariant(
    typeof configPath === "string",
    `Invalid Option: The configPath option '${configPath}' is invalid, only strings are allowed.`,
  );
  return configPath;
};

export const validateBoolOption = (
  name: string,
  value: ?boolean,
  defaultValue: boolean,
) => {
  if (typeof value === "undefined") {
    value = defaultValue;
  }

  if (typeof value !== "boolean") {
    throw new Error(`Preset env: '${name}' option must be a boolean.`);
  }

  return value;
};

export const validateIgnoreBrowserslistConfig = (
  ignoreBrowserslistConfig: boolean,
) =>
  validateBoolOption(
    "ignoreBrowserslistConfig",
    ignoreBrowserslistConfig,
    false,
  );

export const validateModulesOption = (
  modulesOpt: ModuleOption = "commonjs",
) => {
  invariant(
    modulesOpt === false ||
      Object.keys(moduleTransformations).indexOf(modulesOpt) > -1,
    `Invalid Option: The 'modules' option must be either 'false' to indicate no modules, or a
    module type which can be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'.`,
  );

  return modulesOpt;
};

export const objectToBrowserslist = (object: Targets) => {
  return Object.keys(object).reduce((list, targetName) => {
    if (validBrowserslistTargets.indexOf(targetName) >= 0) {
      const targetVersion = object[targetName];
      return list.concat(`${targetName} ${targetVersion}`);
    }
    return list;
  }, []);
};

export const validateUseBuiltInsOption = (
  builtInsOpt: BuiltInsOption = false,
): BuiltInsOption => {
  invariant(
    builtInsOpt === "usage" || builtInsOpt === false || builtInsOpt === "entry",
    `Invalid Option: The 'useBuiltIns' option must be either
    'false' (default) to indicate no polyfill,
    '"entry"' to indicate replacing the entry polyfill, or
    '"usage"' to import only used polyfills per file`,
  );

  return builtInsOpt;
};

export default function normalizeOptions(opts: Options) {
  if (opts.exclude) {
    opts.exclude = normalizePluginNames(opts.exclude);
  }

  if (opts.include) {
    opts.include = normalizePluginNames(opts.include);
  }

  checkDuplicateIncludeExcludes(opts.include, opts.exclude);

  return {
    configPath: validateConfigPathOption(opts.configPath),
    debug: opts.debug,
    exclude: validateIncludesAndExcludes(opts.exclude, "exclude"),
    forceAllTransforms: validateBoolOption(
      "forceAllTransforms",
      opts.forceAllTransforms,
      false,
    ),
    ignoreBrowserslistConfig: validateIgnoreBrowserslistConfig(
      opts.ignoreBrowserslistConfig,
    ),
    include: validateIncludesAndExcludes(opts.include, "include"),
    loose: validateBoolOption("loose", opts.loose, false),
    modules: validateModulesOption(opts.modules),
    shippedProposals: validateBoolOption(
      "shippedProposals",
      opts.shippedProposals,
      false,
    ),
    spec: validateBoolOption("loose", opts.spec, false),
    targets: opts.targets,
    useBuiltIns: validateUseBuiltInsOption(opts.useBuiltIns),
  };
}
<commit_msg>ensure targets input object is not mutated<commit_after>//@flow

import invariant from "invariant";
import browserslist from "browserslist";
import builtInsList from "../data/built-ins.json";
import { defaultWebIncludes } from "./default-includes";
import moduleTransformations from "./module-transformations";
import pluginsList from "../data/plugins.json";
import type { Targets, Options, ModuleOption, BuiltInsOption } from "./types";

const validIncludesAndExcludes = new Set([
  ...Object.keys(pluginsList),
  ...Object.keys(moduleTransformations).map(m => moduleTransformations[m]),
  ...Object.keys(builtInsList),
  ...defaultWebIncludes,
]);

export const validateIncludesAndExcludes = (
  opts: Array<string> = [],
  type: string,
): Array<string> => {
  invariant(
    Array.isArray(opts),
    `Invalid Option: The '${type}' option must be an Array<String> of plugins/built-ins`,
  );

  const unknownOpts = opts.filter(opt => !validIncludesAndExcludes.has(opt));

  invariant(
    unknownOpts.length === 0,
    `Invalid Option: The plugins/built-ins '${unknownOpts.join(
      ", ",
    )}' passed to the '${type}' option are not
    valid. Please check data/[plugin-features|built-in-features].js in babel-preset-env`,
  );

  return opts;
};

const validBrowserslistTargets = [
  ...Object.keys(browserslist.data),
  ...Object.keys(browserslist.aliases),
];

export const normalizePluginName = (plugin: string): string =>
  plugin.replace(/^babel-plugin-/, "");

export const normalizePluginNames = (plugins: Array<string>): Array<string> =>
  plugins.map(normalizePluginName);

export const checkDuplicateIncludeExcludes = (
  include: Array<string> = [],
  exclude: Array<string> = [],
): void => {
  const duplicates: Array<string> = include.filter(
    opt => exclude.indexOf(opt) >= 0,
  );

  invariant(
    duplicates.length === 0,
    `Invalid Option: The plugins/built-ins '${duplicates.join(
      ", ",
    )}' were found in both the "include" and
    "exclude" options.`,
  );
};

export const validateConfigPathOption = (
  configPath: string = process.cwd(),
) => {
  invariant(
    typeof configPath === "string",
    `Invalid Option: The configPath option '${configPath}' is invalid, only strings are allowed.`,
  );
  return configPath;
};

export const validateBoolOption = (
  name: string,
  value: ?boolean,
  defaultValue: boolean,
) => {
  if (typeof value === "undefined") {
    value = defaultValue;
  }

  if (typeof value !== "boolean") {
    throw new Error(`Preset env: '${name}' option must be a boolean.`);
  }

  return value;
};

export const validateIgnoreBrowserslistConfig = (
  ignoreBrowserslistConfig: boolean,
) =>
  validateBoolOption(
    "ignoreBrowserslistConfig",
    ignoreBrowserslistConfig,
    false,
  );

export const validateModulesOption = (
  modulesOpt: ModuleOption = "commonjs",
) => {
  invariant(
    modulesOpt === false ||
      Object.keys(moduleTransformations).indexOf(modulesOpt) > -1,
    `Invalid Option: The 'modules' option must be either 'false' to indicate no modules, or a
    module type which can be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'.`,
  );

  return modulesOpt;
};

export const objectToBrowserslist = (object: Targets) => {
  return Object.keys(object).reduce((list, targetName) => {
    if (validBrowserslistTargets.indexOf(targetName) >= 0) {
      const targetVersion = object[targetName];
      return list.concat(`${targetName} ${targetVersion}`);
    }
    return list;
  }, []);
};

export const validateUseBuiltInsOption = (
  builtInsOpt: BuiltInsOption = false,
): BuiltInsOption => {
  invariant(
    builtInsOpt === "usage" || builtInsOpt === false || builtInsOpt === "entry",
    `Invalid Option: The 'useBuiltIns' option must be either
    'false' (default) to indicate no polyfill,
    '"entry"' to indicate replacing the entry polyfill, or
    '"usage"' to import only used polyfills per file`,
  );

  return builtInsOpt;
};

export default function normalizeOptions(opts: Options) {
  if (opts.exclude) {
    opts.exclude = normalizePluginNames(opts.exclude);
  }

  if (opts.include) {
    opts.include = normalizePluginNames(opts.include);
  }

  checkDuplicateIncludeExcludes(opts.include, opts.exclude);

  return {
    configPath: validateConfigPathOption(opts.configPath),
    debug: opts.debug,
    exclude: validateIncludesAndExcludes(opts.exclude, "exclude"),
    forceAllTransforms: validateBoolOption(
      "forceAllTransforms",
      opts.forceAllTransforms,
      false,
    ),
    ignoreBrowserslistConfig: validateIgnoreBrowserslistConfig(
      opts.ignoreBrowserslistConfig,
    ),
    include: validateIncludesAndExcludes(opts.include, "include"),
    loose: validateBoolOption("loose", opts.loose, false),
    modules: validateModulesOption(opts.modules),
    shippedProposals: validateBoolOption(
      "shippedProposals",
      opts.shippedProposals,
      false,
    ),
    spec: validateBoolOption("loose", opts.spec, false),
    targets: Object.assign({}, opts.targets),
    useBuiltIns: validateUseBuiltInsOption(opts.useBuiltIns),
  };
}
<|endoftext|>


<commit_before>define([
  'jquery',
  'underscore',
  'backbone',
], function($, _, Backbone) {
  var HistogramView = Backbone.View.extend({
    className: 'histogram',

    initialize: function(options){
      this.aspectRatio = options.aspectRatio || 7/1;
      this.height = 100;
      this.width = this.height * this.aspectRatio;

      this.selected_value = options.selected_value || null;
      this.gradients = options.gradients;
      this.colorScale = options.colorScale;
      this.filterRange = options.filterRange;
      this.fieldName = options.fieldName;
      this.slices = options.slices; // Not sure why we have slices, when that value can be extrapulated from this.gradients

      this.chart = d3.select(this.el).append('svg')
        .style({ width: '100%', height: '100%' })
        .attr('viewBox', '0 0 ' + this.width + ' ' + this.height)
        .attr('preserveAspectRatio', 'none')
        .style('background', 'transparent');

      this.g = this.chart.append('g');
    },

    update: function(options) {
      Object.keys(options).forEach(k => {
        if (this.hasOwnProperty(k)) {
          this[k] = options[k];
        }
      });
    },

    findQuantileIndexForValue: function(val, quantiles) {
      if (!quantiles) {
        quantiles = this.colorScale.quantiles ?
                        [...this.colorScale.quantiles()] :
                        [...this.colorScale.domain()];
      }

      const len = quantiles.length - 1;

      return _.reduce(quantiles, function(prev, curr, i){
        // bail if we found an index
        if (prev > -1) return prev;

        // special case first index
        if (i === 0 && val < quantiles[0]) return i;

        // check if val is within range
        if (val >= quantiles[i-1] && val < quantiles[i]) return i;

        // if no match yet, return index for the last bar
        if (i === len) return i + 1;

        // return current index
        return prev;
      }, -1);
    },

    updateHighlight: function(val) {
      if (!this.chart || this.selected_value === val) return;
      this.selected_value = val;
      this.chart.selectAll('rect').call(this.highlightBar, this);
    },

    highlightBar: function(bars, context) {
      const ctxValue = context.selected_value;

      const quantiles = context.colorScale.quantiles ?
                [...context.colorScale.quantiles()] :
                [...context.colorScale.domain()];

      const highlightIndex = (ctxValue !== null)
          ? context.findQuantileIndexForValue(ctxValue, quantiles) :
            null;

      bars.classed('highlight', function(d, i) {
        return i === highlightIndex;
      });
    },

    render: function(){
      const colorScale = this.colorScale;
      const isThreshold = colorScale.quantiles ? false : true;

      const gradients = this.gradients;
      const counts = _.pluck(gradients, 'count');
      const height = this.height;

      const yScale = d3.scale.linear()
                     .domain([0, d3.max(counts)])
                     .range([0, this.height]);

      const xScale = d3.scale.ordinal()
                     .domain(d3.range(0, this.slices))
                     .rangeBands([0, this.width], 0.2, 0);

      // threshold types use rounded bands for convienence
      if (isThreshold) {
        xScale.rangeRoundBands([0, this.width], 0.1, 0);
      }

      const bardata = xScale.domain().map((d, i) => {
        return {
          ...gradients[i],
          idx: i,
          data: d,
          xpos: xScale(d)
        };
      });

      const filterValueForXpos = d3.scale.linear()
        .range(this.filterRange)
        .domain([0, this.width]);

      // make scale available to caller
      this.xScale = xScale;

      // draw
      const bars = this.g.selectAll('rect')
          .data(bardata, function(d) { return d.color; });

      bars.enter().append('rect');

      bars
      .style('fill', (d, i) => {
        // not on a continous scale
        // so just need the color from data
        if (isThreshold) return d.color;

        // mapping the color continously
        // so need to calculate the color for
        // this xpos
        //
        return colorScale(filterValueForXpos(d.xpos));
      })
      .attr({
        'width': () => {
          return xScale.rangeBand();
        },
        'stroke-width': 0,
        'height': d => yScale(d.count),
        'x': (d, i) => xScale(d.data),
        'y': d => (height - yScale(d.count))
      });

      bars.exit().remove();

      bars.call(this.highlightBar, this);

      this.g.selectAll('rect')
                .filter((bucket, index) => { return bucket.current === index; })
                .classed('current', true);

      return this.el;
    }
  });

  return HistogramView;
});
<commit_msg>Center histogram colors within the range band<commit_after>define([
  'jquery',
  'underscore',
  'backbone',
], function($, _, Backbone) {
  var HistogramView = Backbone.View.extend({
    className: 'histogram',

    initialize: function(options){
      this.aspectRatio = options.aspectRatio || 7/1;
      this.height = 100;
      this.width = this.height * this.aspectRatio;

      this.selected_value = options.selected_value || null;
      this.gradients = options.gradients;
      this.colorScale = options.colorScale;
      this.filterRange = options.filterRange;
      this.fieldName = options.fieldName;
      this.slices = options.slices; // Not sure why we have slices, when that value can be extrapulated from this.gradients

      this.chart = d3.select(this.el).append('svg')
        .style({ width: '100%', height: '100%' })
        .attr('viewBox', '0 0 ' + this.width + ' ' + this.height)
        .attr('preserveAspectRatio', 'none')
        .style('background', 'transparent');

      this.g = this.chart.append('g');
    },

    update: function(options) {
      Object.keys(options).forEach(k => {
        if (this.hasOwnProperty(k)) {
          this[k] = options[k];
        }
      });
    },

    findQuantileIndexForValue: function(val, quantiles) {
      if (!quantiles) {
        quantiles = this.colorScale.quantiles ?
                        [...this.colorScale.quantiles()] :
                        [...this.colorScale.domain()];
      }

      const len = quantiles.length - 1;

      return _.reduce(quantiles, function(prev, curr, i){
        // bail if we found an index
        if (prev > -1) return prev;

        // special case first index
        if (i === 0 && val < quantiles[0]) return i;

        // check if val is within range
        if (val >= quantiles[i-1] && val < quantiles[i]) return i;

        // if no match yet, return index for the last bar
        if (i === len) return i + 1;

        // return current index
        return prev;
      }, -1);
    },

    updateHighlight: function(val) {
      if (!this.chart || this.selected_value === val) return;
      this.selected_value = val;
      this.chart.selectAll('rect').call(this.highlightBar, this);
    },

    highlightBar: function(bars, context) {
      const ctxValue = context.selected_value;

      const quantiles = context.colorScale.quantiles ?
                [...context.colorScale.quantiles()] :
                [...context.colorScale.domain()];

      const highlightIndex = (ctxValue !== null)
          ? context.findQuantileIndexForValue(ctxValue, quantiles) :
            null;

      bars.classed('highlight', function(d, i) {
        return i === highlightIndex;
      });
    },

    render: function(){
      const colorScale = this.colorScale;
      const isThreshold = colorScale.quantiles ? false : true;

      const gradients = this.gradients;
      const counts = _.pluck(gradients, 'count');
      const height = this.height;

      const yScale = d3.scale.linear()
                     .domain([0, d3.max(counts)])
                     .range([0, this.height]);

      const xScale = d3.scale.ordinal()
                     .domain(d3.range(0, this.slices))
                     .rangeBands([0, this.width], 0.2, 0);

      // threshold types use rounded bands for convienence
      if (isThreshold) {
        xScale.rangeRoundBands([0, this.width], 0.1, 0);
      }

      const bardata = xScale.domain().map((d, i) => {
        return {
          ...gradients[i],
          idx: i,
          data: d,
          xpos: xScale(d) + (xScale.rangeBand() / 2)
        };
      });

      const filterValueForXpos = d3.scale.linear()
        .range(this.filterRange)
        .domain([0, this.width]);

      // make scale available to caller
      this.xScale = xScale;

      // draw
      const bars = this.g.selectAll('rect')
          .data(bardata, function(d) { return d.color; });

      bars.enter().append('rect');

      bars
      .style('fill', (d, i) => {
        // not on a continous scale
        // so just need the color from data
        if (isThreshold) return d.color;

        // mapping the color continously
        // so need to calculate the color for
        // this xpos
        //
        return colorScale(filterValueForXpos(d.xpos));
      })
      .attr({
        'width': () => {
          return xScale.rangeBand();
        },
        'stroke-width': 0,
        'height': d => yScale(d.count),
        'x': (d, i) => xScale(d.data),
        'y': d => (height - yScale(d.count))
      });

      bars.exit().remove();

      bars.call(this.highlightBar, this);

      this.g.selectAll('rect')
                .filter((bucket, index) => { return bucket.current === index; })
                .classed('current', true);

      return this.el;
    }
  });

  return HistogramView;
});
<|endoftext|>


<commit_before>"use strict";
const path = require("path");
const whatwgURL = require("whatwg-url");
const { domSymbolTree } = require("./living/helpers/internal-constants");
const SYMBOL_TREE_POSITION = require("symbol-tree").TreePosition;
const { parseURLToResultingURLRecord } = require("./living/helpers/document-base-url");

exports.toFileUrl = function (fileName) {
  // Beyond just the `path.resolve`, this is mostly for the benefit of Windows,
  // where we need to convert "\" to "/" and add an extra "/" prefix before the
  // drive letter.
  let pathname = path.resolve(process.cwd(), fileName).replace(/\\/g, "/");
  if (pathname[0] !== "/") {
    pathname = "/" + pathname;
  }

  // path might contain spaces, so convert those to %20
  return "file://" + encodeURI(pathname);
};

/**
 * Define a set of properties on an object, by copying the property descriptors
 * from the original object.
 *
 * - `object` {Object} the target object
 * - `properties` {Object} the source from which to copy property descriptors
 */
exports.define = function define(object, properties) {
  for (const name of Object.getOwnPropertyNames(properties)) {
    const propDesc = Object.getOwnPropertyDescriptor(properties, name);
    Object.defineProperty(object, name, propDesc);
  }
};

/**
 * Define a list of constants on a constructor and its .prototype
 *
 * - `Constructor` {Function} the constructor to define the constants on
 * - `propertyMap` {Object}  key/value map of properties to define
 */
exports.addConstants = function addConstants(Constructor, propertyMap) {
  for (const property in propertyMap) {
    const value = propertyMap[property];
    addConstant(Constructor, property, value);
    addConstant(Constructor.prototype, property, value);
  }
};

function addConstant(object, property, value) {
  Object.defineProperty(object, property, {
    configurable: false,
    enumerable: true,
    writable: false,
    value
  });
}

exports.mixin = (target, source) => {
  const keys = Reflect.ownKeys(source);
  for (let i = 0; i < keys.length; ++i) {
    if (keys[i] in target) {
      continue;
    }

    Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
  }
};

let memoizeQueryTypeCounter = 0;

/**
 * Returns a version of a method that memoizes specific types of calls on the object
 *
 * - `fn` {Function} the method to be memozied
 */
exports.memoizeQuery = function memoizeQuery(fn) {
  // Only memoize query functions with arity <= 2
  if (fn.length > 2) {
    return fn;
  }

  const type = memoizeQueryTypeCounter++;

  return function () {
    if (!this._memoizedQueries) {
      return fn.apply(this, arguments);
    }

    if (!this._memoizedQueries[type]) {
      this._memoizedQueries[type] = Object.create(null);
    }

    let key;
    if (arguments.length === 1 && typeof arguments[0] === "string") {
      key = arguments[0];
    } else if (arguments.length === 2 && typeof arguments[0] === "string" && typeof arguments[1] === "string") {
      key = arguments[0] + "::" + arguments[1];
    } else {
      return fn.apply(this, arguments);
    }

    if (!(key in this._memoizedQueries[type])) {
      this._memoizedQueries[type][key] = fn.apply(this, arguments);
    }
    return this._memoizedQueries[type][key];
  };
};

exports.reflectURLAttribute = (elementImpl, contentAttributeName) => {
  const attributeValue = elementImpl.getAttribute(contentAttributeName);
  if (attributeValue === null || attributeValue === "") {
    return "";
  }

  const urlRecord = parseURLToResultingURLRecord(attributeValue, elementImpl._ownerDocument);
  if (urlRecord === null) {
    return attributeValue;
  }
  return whatwgURL.serializeURL(urlRecord);
};

function isValidAbsoluteURL(str) {
  return whatwgURL.parseURL(str) !== null;
}

exports.isValidTargetOrigin = function (str) {
  return str === "*" || str === "/" || isValidAbsoluteURL(str);
};

exports.simultaneousIterators = function* (first, second) {
  for (;;) {
    const firstResult = first.next();
    const secondResult = second.next();

    if (firstResult.done && secondResult.done) {
      return;
    }

    yield [
      firstResult.done ? null : firstResult.value,
      secondResult.done ? null : secondResult.value
    ];
  }
};

exports.treeOrderSorter = function (a, b) {
  const compare = domSymbolTree.compareTreePosition(a, b);

  if (compare & SYMBOL_TREE_POSITION.PRECEDING) { // b is preceding a
    return 1;
  }

  if (compare & SYMBOL_TREE_POSITION.FOLLOWING) {
    return -1;
  }

  // disconnected or equal:
  return 0;
};

/* eslint-disable global-require */

exports.Canvas = null;
["canvas", "canvas-prebuilt"].some(moduleName => {
  try {
    require.resolve(moduleName);
  } catch (e) {
    // ${moduleName} is not installed
    return false;
  }
  exports.Canvas = require(moduleName);
  if (typeof exports.Canvas.createCanvas !== "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = null;
  }
  return exports.Canvas !== null;
});
<commit_msg>Don't attempt to load canvas-prebuilt<commit_after>"use strict";
const path = require("path");
const whatwgURL = require("whatwg-url");
const { domSymbolTree } = require("./living/helpers/internal-constants");
const SYMBOL_TREE_POSITION = require("symbol-tree").TreePosition;
const { parseURLToResultingURLRecord } = require("./living/helpers/document-base-url");

exports.toFileUrl = function (fileName) {
  // Beyond just the `path.resolve`, this is mostly for the benefit of Windows,
  // where we need to convert "\" to "/" and add an extra "/" prefix before the
  // drive letter.
  let pathname = path.resolve(process.cwd(), fileName).replace(/\\/g, "/");
  if (pathname[0] !== "/") {
    pathname = "/" + pathname;
  }

  // path might contain spaces, so convert those to %20
  return "file://" + encodeURI(pathname);
};

/**
 * Define a set of properties on an object, by copying the property descriptors
 * from the original object.
 *
 * - `object` {Object} the target object
 * - `properties` {Object} the source from which to copy property descriptors
 */
exports.define = function define(object, properties) {
  for (const name of Object.getOwnPropertyNames(properties)) {
    const propDesc = Object.getOwnPropertyDescriptor(properties, name);
    Object.defineProperty(object, name, propDesc);
  }
};

/**
 * Define a list of constants on a constructor and its .prototype
 *
 * - `Constructor` {Function} the constructor to define the constants on
 * - `propertyMap` {Object}  key/value map of properties to define
 */
exports.addConstants = function addConstants(Constructor, propertyMap) {
  for (const property in propertyMap) {
    const value = propertyMap[property];
    addConstant(Constructor, property, value);
    addConstant(Constructor.prototype, property, value);
  }
};

function addConstant(object, property, value) {
  Object.defineProperty(object, property, {
    configurable: false,
    enumerable: true,
    writable: false,
    value
  });
}

exports.mixin = (target, source) => {
  const keys = Reflect.ownKeys(source);
  for (let i = 0; i < keys.length; ++i) {
    if (keys[i] in target) {
      continue;
    }

    Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
  }
};

let memoizeQueryTypeCounter = 0;

/**
 * Returns a version of a method that memoizes specific types of calls on the object
 *
 * - `fn` {Function} the method to be memozied
 */
exports.memoizeQuery = function memoizeQuery(fn) {
  // Only memoize query functions with arity <= 2
  if (fn.length > 2) {
    return fn;
  }

  const type = memoizeQueryTypeCounter++;

  return function () {
    if (!this._memoizedQueries) {
      return fn.apply(this, arguments);
    }

    if (!this._memoizedQueries[type]) {
      this._memoizedQueries[type] = Object.create(null);
    }

    let key;
    if (arguments.length === 1 && typeof arguments[0] === "string") {
      key = arguments[0];
    } else if (arguments.length === 2 && typeof arguments[0] === "string" && typeof arguments[1] === "string") {
      key = arguments[0] + "::" + arguments[1];
    } else {
      return fn.apply(this, arguments);
    }

    if (!(key in this._memoizedQueries[type])) {
      this._memoizedQueries[type][key] = fn.apply(this, arguments);
    }
    return this._memoizedQueries[type][key];
  };
};

exports.reflectURLAttribute = (elementImpl, contentAttributeName) => {
  const attributeValue = elementImpl.getAttribute(contentAttributeName);
  if (attributeValue === null || attributeValue === "") {
    return "";
  }

  const urlRecord = parseURLToResultingURLRecord(attributeValue, elementImpl._ownerDocument);
  if (urlRecord === null) {
    return attributeValue;
  }
  return whatwgURL.serializeURL(urlRecord);
};

function isValidAbsoluteURL(str) {
  return whatwgURL.parseURL(str) !== null;
}

exports.isValidTargetOrigin = function (str) {
  return str === "*" || str === "/" || isValidAbsoluteURL(str);
};

exports.simultaneousIterators = function* (first, second) {
  for (;;) {
    const firstResult = first.next();
    const secondResult = second.next();

    if (firstResult.done && secondResult.done) {
      return;
    }

    yield [
      firstResult.done ? null : firstResult.value,
      secondResult.done ? null : secondResult.value
    ];
  }
};

exports.treeOrderSorter = function (a, b) {
  const compare = domSymbolTree.compareTreePosition(a, b);

  if (compare & SYMBOL_TREE_POSITION.PRECEDING) { // b is preceding a
    return 1;
  }

  if (compare & SYMBOL_TREE_POSITION.FOLLOWING) {
    return -1;
  }

  // disconnected or equal:
  return 0;
};

/* eslint-disable global-require */

exports.Canvas = null;
let canvasInstalled = false;
try {
  require.resolve("canvas");
  canvasInstalled = true;
} catch (e) {
  // canvas is not installed
}
if (canvasInstalled) {
  const Canvas = require("canvas");
  if (typeof Canvas.createCanvas === "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = Canvas;
  }
}
<|endoftext|>


<commit_before>/**
 * @author Ayman Habib
 */
THREE.SkinnedMuscle = function(geom, points, material) {
    // Create bones for uuids in geometryPath
    this.pathpoints = points;
    this.pathpointObjects = [];
    geom.bones = [];

    for (var i=0; i< 2*points.length-2; i++) {
        var bone = new THREE.Bone();
        bone.pos = [0, 0, 0];
        bone.rotq = [0, 0, 0, 1];
        bone.ppt = this.pathpoints[Math.floor(i/2)];
        geom.bones.push(bone);
    }

    var numVerticesPerLevel = geom.vertices.length / (2*points.length-2);

    for ( var i = 0; i < geom.vertices.length; i++ ) {
        var skinIndex = Math.floor(i / numVerticesPerLevel);
        geom.skinIndices.push(new THREE.Vector4(skinIndex, skinIndex+1, skinIndex-1, 0));
        geom.skinWeights.push( new THREE.Vector4( 0.8, 0.1, 0.1, 0 ) );
    }
    geom.dynamic = true;
    THREE.SkinnedMesh.call( this, geom );
    this.material = material;
    this.material.skinning = true;
};

THREE.SkinnedMuscle.prototype = Object.create( THREE.SkinnedMesh.prototype );
THREE.SkinnedMuscle.prototype.constructor = THREE.SkinnedMuscle;

THREE.SkinnedMuscle.prototype.updateMatrixWorld = function( force ) {
// if has pathpoints attribute then it's a muscle
// Cycle through pathpoints, update their matrixworld
// then set the position of the Bones from that
    if (this.skeleton === undefined)
        return;
    var bones = this.skeleton.bones;
    //console.warn("Num bones in updateMatrixWorld: " + bones.length);

    if (this.pathpointObjects.length != this.pathpoints.length){
        var b = 0;
        for ( var p=0; p < this.pathpoints.length; p++) {
            var pptObject1 = editor.objectByUuid(this.pathpoints[p]);
            var pptObject2 = editor.objectByUuid(this.pathpoints[p+1]);

            if (pptObject1 !== undefined) {
               // add every pathpoint to the list of PathPoint objects
                this.pathpointObjects.push(pptObject1);

                if (pptObject2 !== undefined) {
                // define the two bones of a segement of the path together
                    bones[b].geometry = pptObject1.geometry;
                    bones[++b].geometry = pptObject2.geometry;
                }
                b++;
            }
        }
    }
    // Compute reverse transform from Ground to Scene (usually this's inverse translation)
    // This is necessary since the blending to compute vertices adds offset twice
    var mat = new THREE.Matrix4().getInverse(this.parent.matrixWorld);
    var vec = new THREE.Vector3().setFromMatrixPosition(mat);

    // Variables for the two points of a given path segement, the axis to
    // be rotated (from) and the vector between them (to)
    var pt1 = new THREE.Vector3();
    var pt2 = new THREE.Vector3();
    var vFrom = new THREE.Vector3(0, -1, 0);
    var vTo = new THREE.Vector3();

    // cycle through each segement defined by two PathPoints, pt1 and pt2
    // and alignge the bones (caps of each segment) to be alinged with
    // the vector connecting them.
    var b = 0; // bone (of SkinnedMuscle) index
    for (var p = 0; p < this.pathpoints.length-1; p++) {
        var thisPathpointObject = this.pathpointObjects[p];
        var nextPathpointObject = this.pathpointObjects[p+1];

        if(thisPathpointObject !== undefined) {
            pt1.setFromMatrixPosition(thisPathpointObject.matrixWorld);
            pt2.setFromMatrixPosition(nextPathpointObject.matrixWorld);

            vTo = pt2.clone();
            vTo.sub(pt1).normalize();

            // bones are positioned on the pathpoints
            bones[b].position.setFromMatrixPosition(thisPathpointObject.matrixWorld);
            bones[b].position.add(vec);
            // the orientation of the bone is updated to have its Y-axis pointed
            // back along the vector from pt1 to pt2
            bones[b].quaternion.setFromUnitVectors(vFrom, vTo);

            bones[++b].position.setFromMatrixPosition(nextPathpointObject.matrixWorld);
            // the orientation of the bone is updated to have its Y-axis pointed
            // back along the vector from pt1 to pt2
            bones[b].position.add(vec);
            bones[b++].quaternion.setFromUnitVectors(vFrom, vTo);
        }
    }
    this.skeleton.update();
    THREE.SkinnedMesh.prototype.updateMatrixWorld.call( this, true );
};
<commit_msg>Fixes shortened, gouged and edgy muscles by forcing vertices on end point bones but enabling smoothing on all other bone vertices.<commit_after>/**
 * @author Ayman Habib
 */
THREE.SkinnedMuscle = function(geom, points, material) {
    // Create bones for uuids in geometryPath
    this.pathpoints = points;
    this.pathpointObjects = [];
    geom.bones = [];

    for (var i=0; i< 2*points.length-2; i++) {
        var bone = new THREE.Bone();
        bone.pos = [0, 0, 0];
        bone.rotq = [0, 0, 0, 1];
        bone.ppt = this.pathpoints[Math.floor(i/2)];
        geom.bones.push(bone);
    }

    var numVerticesPerLevel = geom.vertices.length / (2*points.length-2);

    for ( var i = 0; i < geom.vertices.length; i++ ) {
        var skinIndex = Math.floor(i / numVerticesPerLevel);
        geom.skinIndices.push(new THREE.Vector4(skinIndex, skinIndex+1, skinIndex-1, 0));
        if(skinIndex > 0 && skinIndex < geom.bones.length-1) {
           // blend next and previous bone vertices to smoothen transitions
            geom.skinWeights.push( new THREE.Vector4( 0.8, 0.1, 0.1, 0 ) );
        }
        else { //but, strictly enforce the reaching of the end points
            geom.skinWeights.push( new THREE.Vector4( 1.0, 0, 0, 0 ) );
        }
    }
    geom.dynamic = true;
    THREE.SkinnedMesh.call( this, geom );
    this.material = material;
    this.material.skinning = true;
};

THREE.SkinnedMuscle.prototype = Object.create( THREE.SkinnedMesh.prototype );
THREE.SkinnedMuscle.prototype.constructor = THREE.SkinnedMuscle;

THREE.SkinnedMuscle.prototype.updateMatrixWorld = function( force ) {
// if has pathpoints attribute then it's a muscle
// Cycle through pathpoints, update their matrixworld
// then set the position of the Bones from that
    if (this.skeleton === undefined)
        return;
    var bones = this.skeleton.bones;
    //console.warn("Num bones in updateMatrixWorld: " + bones.length);

    if (this.pathpointObjects.length != this.pathpoints.length){
        var b = 0;
        for ( var p=0; p < this.pathpoints.length; p++) {
            var pptObject1 = editor.objectByUuid(this.pathpoints[p]);
            var pptObject2 = editor.objectByUuid(this.pathpoints[p+1]);

            if (pptObject1 !== undefined) {
               // add every pathpoint to the list of PathPoint objects
                this.pathpointObjects.push(pptObject1);

                if (pptObject2 !== undefined) {
                // define the two bones of a segement of the path together
                    bones[b].geometry = pptObject1.geometry;
                    bones[++b].geometry = pptObject2.geometry;
                }
                b++;
            }
        }
    }
    // Compute reverse transform from Ground to Scene (usually this's inverse translation)
    // This is necessary since the blending to compute vertices adds offset twice
    var mat = new THREE.Matrix4().getInverse(this.parent.matrixWorld);
    var vec = new THREE.Vector3().setFromMatrixPosition(mat);

    // Variables for the two points of a given path segement, the axis to
    // be rotated (from) and the vector between them (to)
    var pt1 = new THREE.Vector3();
    var pt2 = new THREE.Vector3();
    var vFrom = new THREE.Vector3(0, -1, 0);
    var vTo = new THREE.Vector3();

    // cycle through each segement defined by two PathPoints, pt1 and pt2
    // and alignge the bones (caps of each segment) to be alinged with
    // the vector connecting them.
    var b = 0; // bone (of SkinnedMuscle) index
    for (var p = 0; p < this.pathpoints.length-1; p++) {
        var thisPathpointObject = this.pathpointObjects[p];
        var nextPathpointObject = this.pathpointObjects[p+1];

        if(thisPathpointObject !== undefined) {
            pt1.setFromMatrixPosition(thisPathpointObject.matrixWorld);
            pt2.setFromMatrixPosition(nextPathpointObject.matrixWorld);

            vTo = pt2.clone();
            vTo.sub(pt1).normalize();

            // bones are positioned on the pathpoints
            bones[b].position.setFromMatrixPosition(thisPathpointObject.matrixWorld);
            bones[b].position.add(vec);
            // the orientation of the bone is updated to have its Y-axis pointed
            // back along the vector from pt1 to pt2
            bones[b].quaternion.setFromUnitVectors(vFrom, vTo);

            bones[++b].position.setFromMatrixPosition(nextPathpointObject.matrixWorld);
            // the orientation of the bone is updated to have its Y-axis pointed
            // back along the vector from pt1 to pt2
            bones[b].position.add(vec);
            bones[b++].quaternion.setFromUnitVectors(vFrom, vTo);
        }
    }
    this.skeleton.update();
    THREE.SkinnedMesh.prototype.updateMatrixWorld.call( this, true );
};
<|endoftext|>


<commit_before>// Import React
import React from "react";

// Import Spectacle Core tags
import {
  Appear,
  // BlockQuote,
  // Cite,
  CodePane,
  Deck,
  Fill,
  Heading,
  Image,
  Layout,
  // Link,
  ListItem,
  List,
  Markdown,
  // Quote,
  Slide,
  Spectacle,
  Text
  // Table,
  // TableRow,
  // TableHeaderItem,
  // TableItem
} from "spectacle";

// Import image preloader util
import preloader from "spectacle/lib/utils/preloader";

// Import theme
import createTheme from "spectacle/lib/themes/default";

import CodeSplit from "./codesplit";
import Code from "./code";
// Import Examples
import Example from './Example';
// Require CSS
require("normalize.css");
require("spectacle/lib/themes/default/index.css");

const images = {
  coding: require("../assets/coding.jpg"),
  control: require("../assets/control.jpg"),
  website: require("../assets/website.jpg"),
};

preloader(images);

const theme = createTheme({
  primary: "#3b5998"
});
const grey = "rgba(125, 125, 125, 0.8)";
theme.screen.progress.bar.bar.background = grey;
theme.screen.controls.nextIcon.fill = grey;
theme.screen.controls.prevIcon.fill = grey;

export default class Presentation extends React.Component {
  render() {
    return (
      <Spectacle theme={theme}>
        <Deck transition={["fade", "slide"]} transitionDuration={500} progress="bar">

          <Slide bgColor="primary">
            <Heading size={1} caps textColor="tertiary">
              JSX
            </Heading>
            <Text textSize="1.5em" margin="100px 0px 0px 0px" textColor="tertiary">
              Fabian Beliza & Jonas Faber
            </Text>
          </Slide>

          <Slide bgColor="tertiary">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Inhalt
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem>Was ist JSX?</ListItem></Appear>
              <Appear><ListItem>Bezug zu XML</ListItem></Appear>
              <Appear><ListItem>Beispiele</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary" notes="Type-Safe, Errors werden während compilierung erkannt.">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Was ist JSX?
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem>XML-ähnliche Syntax-Erweiterung zu ECMAScript</ListItem></Appear>
              <Appear><ListItem>Wird von Preprozessoren transformiert</ListItem></Appear>
              <Appear><ListItem>Optimierungen während Kompilierung in JS</ListItem></Appear>
              <Appear><ListItem>Type-Safe</ListItem></Appear>
              <Appear><ListItem>Vereinfacht Templating (HTML-Syntax)</ListItem></Appear>
              <Appear><ListItem>Besonders im Zusammenhang mit React zu finden</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Bezug zu XML
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem><Markdown source="`< JSXElementName JSXAttributes(optional) / >`" /></ListItem></Appear>
              <Appear><ListItem>Strukturierung mit child-Elementen</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary">

          </Slide>

        </Deck>
      </Spectacle>
    );
  }
}
<commit_msg>Small change<commit_after>// Import React
import React from "react";

// Import Spectacle Core tags
import {
  Appear,
  // BlockQuote,
  // Cite,
  CodePane,
  Deck,
  Fill,
  Heading,
  Image,
  Layout,
  // Link,
  ListItem,
  List,
  Markdown,
  // Quote,
  Slide,
  Spectacle,
  Text
  // Table,
  // TableRow,
  // TableHeaderItem,
  // TableItem
} from "spectacle";

// Import image preloader util
import preloader from "spectacle/lib/utils/preloader";

// Import theme
import createTheme from "spectacle/lib/themes/default";

import CodeSplit from "./codesplit";
import Code from "./code";
// Import Examples
import Example from './Example';
// Require CSS
require("normalize.css");
require("spectacle/lib/themes/default/index.css");

const images = {
  coding: require("../assets/coding.jpg"),
  control: require("../assets/control.jpg"),
  website: require("../assets/website.jpg"),
};

preloader(images);

const theme = createTheme({
  primary: "#3b5998"
});
const grey = "rgba(125, 125, 125, 0.8)";
theme.screen.progress.bar.bar.background = grey;
theme.screen.controls.nextIcon.fill = grey;
theme.screen.controls.prevIcon.fill = grey;

export default class Presentation extends React.Component {
  render() {
    return (
      <Spectacle theme={theme}>
        <Deck transition={["fade", "slide"]} transitionDuration={500} progress="bar">

          <Slide bgColor="primary">
            <Heading size={1} caps textColor="tertiary">
              JSX
            </Heading>
            <Text textSize="1.5em" margin="100px 0px 0px 0px" textColor="tertiary">
              Fabian Beliza & Jonas Faber
            </Text>
          </Slide>

          <Slide bgColor="tertiary">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Inhalt
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem>Was ist JSX?</ListItem></Appear>
              <Appear><ListItem>Bezug zu XML</ListItem></Appear>
              <Appear><ListItem>Beispiele</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary" notes="Type-Safe, Errors werden während compilierung erkannt.">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Was ist JSX?
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem>XML-ähnliche Syntax-Erweiterung zu ECMAScript</ListItem></Appear>
              <Appear><ListItem>Wird von Preprozessoren transformiert</ListItem></Appear>
              <Appear><ListItem>Optimierungen während Kompilierung in JS</ListItem></Appear>
              <Appear><ListItem>Type-Safe</ListItem></Appear>
              <Appear><ListItem>Vereinfacht Templating (HTML-Syntax)</ListItem></Appear>
              <Appear><ListItem>Besonders im Zusammenhang mit React zu finden</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary">
            <Heading size={4} caps lineHeight={1.5} textColor="primary">
            Bezug zu XML
            </Heading>
            <List textColor="secondary" textAlign="left">
              <Appear><ListItem><Markdown source="`< JSXElementName JSXAttributes(optional) / >`" /></ListItem></Appear>
              <Appear><ListItem>Strukturierung mit child-Elementen</ListItem></Appear>
              <Appear><ListItem>Baumstruktur</ListItem></Appear>
            </List>
          </Slide>

          <Slide bgColor="tertiary">

          </Slide>

        </Deck>
      </Spectacle>
    );
  }
}
<|endoftext|>


<commit_before>var SuperPacksPage = (function () {
    var _this;

    var $chooseProjectSelect;  //选择打包项目
    var $superPackItem;        //超级打包按钮

    function SuperPacksPage() {
        _this = this;
    }

    SuperPacksPage.prototype = new AppPage();

    SuperPacksPage.prototype.select_pack_project = '';//选中要打包的应用
    SuperPacksPage.prototype.select_pack_project_label = '';//选中要打包的应用
    SuperPacksPage.prototype.select_pack_flavor = '';//选中要打包的应用的flavor

    /**
     * 页面元素初始化
     */
    SuperPacksPage.prototype.onCreate = function () {
        $superPackItem = $("#super-pack-item");
        $chooseProjectSelect = $("#choose-project-select");
    };

    /**
     * 初始化数据
     */
    SuperPacksPage.prototype.onInitData = function () {

    };

    /**
     * 页面元素的事件绑定开始了
     */
    SuperPacksPage.prototype.onBindEvent = function () {
        $superPackItem.unbind().click(function () {
            $chooseProjectSelect.miSelect('show', 'ad_market');
        });
        $chooseProjectSelect.bind('confirmed', function (event, data) {
            _this.select_pack_project = data.value;
            _this.select_pack_project_label = data.extra;
            _this.actionGetFlavors(data.value);
        });
    };

    /**
     * 页面获取焦点
     */
    SuperPacksPage.prototype.onResume = function () {

    };

    /**
     * 初始化flavor选择器
     * @param html
     */
    SuperPacksPage.prototype.actionInitFlavorSelect = function (html) {
        $("#choose-flavors-select").remove();
        $("body").append(html);
        var $select = $("#choose-flavors-select");
        $select.miSelect();
        $select.unbind().bind('confirmed', function (event, data) {
            _this.select_pack_flavor = data.value;
            $.miConfirm({
                title: '确定要启动打包吗?',
                body: "启动后项目将被暂时锁定，直至打包结束！{0}-{1}".format(_this.select_pack_project_label, _this.select_pack_flavor)
            }, function () {
                _this.actionCreateSuperPack();
            });

        });
    };

    /**
     * 创建超级打包任务
     */
    SuperPacksPage.prototype.actionCreateSuperPack = function () {
        $.miLoading('show');
        $.ajax({
            url: "/super_packs",
            method: 'post',
            data: {
                project: _this.select_pack_project,
                flavor: _this.select_pack_flavor,
                utf8: "√",
                authenticity_token: _this.getAuthenticityToken()
            },
            success: function (data) {
                $.miLoading('hide');
                $.miToast("启动打包成功");
            }, error: function (data) {
                $.miLoading('hide');
                $.miToast("启动失败：" + data.responseJSON.error);
            }

        });
    };

    /**
     * 获取项目的flavor
     */
    SuperPacksPage.prototype.actionGetFlavors = function (project_name) {
        $.miLoading('show');
        $.ajax({
            url: "/super_packs/flavors?project={0}".format(project_name),
            method: 'get',
            success: function (data) {
                $.miLoading('hide');
                _this.actionInitFlavorSelect(data);
            }, error: function (data) {
                $.miLoading('hide');
                $.miToast("获取flavor列表失败");
            }

        });
    };

    return SuperPacksPage;
})();
<commit_msg>no message<commit_after>var SuperPacksPage = (function () {
    var _this;

    var $chooseProjectSelect;  //选择打包项目
    var $superPackItem;        //超级打包按钮

    function SuperPacksPage() {
        _this = this;
    }

    SuperPacksPage.prototype = new AppPage();

    SuperPacksPage.prototype.select_pack_project = '';//选中要打包的应用
    SuperPacksPage.prototype.select_pack_project_label = '';//选中要打包的应用
    SuperPacksPage.prototype.select_pack_flavor = '';//选中要打包的应用的flavor

    /**
     * 页面元素初始化
     */
    SuperPacksPage.prototype.onCreate = function () {
        $superPackItem = $("#super-pack-item");
        $chooseProjectSelect = $("#choose-project-select");
    };

    /**
     * 初始化数据
     */
    SuperPacksPage.prototype.onInitData = function () {

    };

    /**
     * 页面元素的事件绑定开始了
     */
    SuperPacksPage.prototype.onBindEvent = function () {
        $superPackItem.unbind().click(function () {
            $chooseProjectSelect.miSelect('show', 'ad_market');
        });
        $chooseProjectSelect.bind('confirmed', function (event, data) {
            _this.select_pack_project = data.value;
            _this.select_pack_project_label = data.extra;
            _this.actionGetFlavors(data.value);
        });
    };

    /**
     * 页面获取焦点
     */
    SuperPacksPage.prototype.onResume = function () {

    };

    /**
     * 初始化flavor选择器
     * @param html
     */
    SuperPacksPage.prototype.actionInitFlavorSelect = function (html) {
        $("#choose-flavors-select").remove();
        $("body").append(html);
        var $select = $("#choose-flavors-select");
        $select.miSelect();
        $select.unbind().bind('confirmed', function (event, data) {
            _this.select_pack_flavor = data.value;
            $.miConfirm({
                title: '确定要启动打包吗?',
                body: "启动后项目将被暂时锁定，直至打包结束！{0}-{1}".format(_this.select_pack_project_label, _this.select_pack_flavor)
            }, function () {
                _this.actionCreateSuperPack();
            });

        });
    };

    /**
     * 创建超级打包任务
     */
    SuperPacksPage.prototype.actionCreateSuperPack = function () {
        $.miLoading('show');
        $.ajax({
            url: "/super_packs",
            method: 'post',
            data: {
                project: _this.select_pack_project,
                flavor: _this.select_pack_flavor,
                utf8: "√",
                authenticity_token: _this.getAuthenticityToken()
            },
            success: function (data) {
                $.miLoading('hide');
                $.miToast("启动打包成功", function () {
                    window.location.reload();
                });
            }, error: function (data) {
                $.miLoading('hide');
                $.miToast("启动失败：" + data.responseJSON.error);
            }

        });
    };

    /**
     * 获取项目的flavor
     */
    SuperPacksPage.prototype.actionGetFlavors = function (project_name) {
        $.miLoading('show');
        $.ajax({
            url: "/super_packs/flavors?project={0}".format(project_name),
            method: 'get',
            success: function (data) {
                $.miLoading('hide');
                _this.actionInitFlavorSelect(data);
            }, error: function (data) {
                $.miLoading('hide');
                $.miToast("获取flavor列表失败");
            }

        });
    };

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


<commit_before>lichess.widget('watchers', {
  _create: function() {
    this.list = this.element.find(".list");
    this.number = this.element.find(".number");
    lichess.pubsub.on('socket.in.crowd', data => this.set(data.watchers || data));
    lichess.watchersData && this.set(lichess.watchersData);
  },
  set: function(data) {
    lichess.watchersData = data;
    if (!data || !data.nb) return this.element.addClass('none');
    if (this.number.length) this.number.text(data.nb);
    if (data.users) {
      const tags = data.users.map(u => {
        u ? `<a class="user-link ulpt" href="/@/${u.includes(' ') ? u.split(' ')[1] : u}">${u}</a>` : 'Anonymous';
      });
      if (data.anons === 1) tags.push('Anonymous');
      else if (data.anons) tags.push('Anonymous (' + data.anons + ')');
      this.list.html(tags.join(', '));
    } else if (!this.number.length) this.list.html(data.nb + ' players in the chat');
    this.element.removeClass('none');
  }
});
<commit_msg>fix watchers JS again<commit_after>lichess.widget('watchers', {
  _create: function() {
    this.list = this.element.find(".list");
    this.number = this.element.find(".number");
    lichess.pubsub.on('socket.in.crowd', data => this.set(data.watchers || data));
    lichess.watchersData && this.set(lichess.watchersData);
  },
  set: function(data) {
    lichess.watchersData = data;
    if (!data || !data.nb) return this.element.addClass('none');
    if (this.number.length) this.number.text(data.nb);
    if (data.users) {
      const tags = data.users.map(u =>
        u ? `<a class="user-link ulpt" href="/@/${u.includes(' ') ? u.split(' ')[1] : u}">${u}</a>` : 'Anonymous'
      );
      if (data.anons === 1) tags.push('Anonymous');
      else if (data.anons) tags.push('Anonymous (' + data.anons + ')');
      this.list.html(tags.join(', '));
    } else if (!this.number.length) this.list.html(data.nb + ' players in the chat');
    this.element.removeClass('none');
  }
});
<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

var d3 = require("d3");

/*
 Provides some functions which can be applied to an HTML element.
 */
module.exports = function(el) {
    var openButtons,
	currentOpenButton,
	closeButton,
	content = el.append("div")
	    .classed("content", true);

    var visibility = function(show, targetButton) {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);

	    if (show && targetButton !== undefined) {
		currentOpenButton = targetButton;
		targetButton.classed("element-visible", true);
	    }
	}
	el.style("visibility", show ? "visible" : "hidden");
    };

    var disable = function() {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);
	}

	el.style("visibility", "hidden");
    };

    var toggle = function(button) {
	// if it's not visible, open it with the button
	var wasVisible = (el.style("visibility") === "visible");

	visibility(
	    !(wasVisible && button.node() === currentOpenButton.node()),
	    button
	);
    };

    el
	.style("overflow", "hidden");

    var m = {
	drag: function() {
	    el
		.style("cursor", "move")
		.style("position", "absolute");

	    if(el.style("left") === "auto") {
		el.style("left", 0);
	    }
	    if(el.style("top") === "auto") {
		el.style("top", 0);
	    }

	    el.call(
		d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("left")),
			    "y" : parseInt(el.style("top"))
			};
		    })
		    .on("drag", function(d){
			d3.event.sourceEvent.preventDefault();
			el
			    .style("top", d3.event.y + "px")
			    .style("left", d3.event.x + "px");
		    })
	    );

	    return m;
	},

	open: function(buttons) {
	    if (buttons.empty()) {
		buttons = undefined;
		currentOpenButton = undefined;
		m.hide();
		return m;
	    } else {
		// If the current open button isn't in the selection, clear it.
		if (currentOpenButton && buttons.filter(function(d, i) {
		    return this === currentOpenButton.node();
		}.empty())) {
		    currentOpenButton = undefined;
		}

		buttons
		    .classed("open-button", true)
		    .classed("element-visible", function(d, i) {
			if (el.attr("visibility") !== "hidden") {
			    if (currentOpenButton && this === currentOpenButton.node()) {
				return true;
			    } else if (currentOpenButton === undefined) {
				currentOpenButton = d3.select(this);
				return true;
			    }
			}
			return false;
		    })
		    .on("click", function(d, i) {
			d3.event.preventDefault();
			toggle(d3.select(this));
		    });

		openButtons = buttons;

		return m;
	    }
	},

	close: function() {
	    var closeButton = el
	    // This padding provides space for the button.
		    .style("padding-right", "1.5em")
		    .append("span")
		    .classed("close-button", true)
		    .style("font-size", "x-large")
		    .style("font-family", "monospace")
		    .style("position", "absolute")
		    .style("top", "0")
		    .style("right", "5px")
		    .style("opacity", "0.6")
		    .style("cursor", "pointer")
		    .html("X");

	    closeButton.on("click", disable);

	    return m;
	},

	resize: function() {
	    var dragHandle = d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("width")),
			    "y" : parseInt(el.style("height"))
			};
		    })
		    .on("dragstart", function(d){
			d3.event.sourceEvent.stopPropagation();
		    })
		    .on("drag", function(d){
			el.style("height", d3.event.y + "px");
			el.style("width", d3.event.x + "px");
		    });

	    el
	    // This padding prevents us from make the box too small to resize.
		.style("padding-bottom", "3em")
	    // This padding provides space for the button.
		.style("padding-right", "1.5em")
		.append("span")
		.style("font-size", "xx-large")
		.style("font-family", "monospace")
		.style("position", "absolute")
		.style("bottom", "0")
		.style("right", "5px")
		.style("opacity", "0.6")
		.html("⇘")
		.call(dragHandle);

	    return m;
	},

	hide: function() {
	    visibility(false);
	    return m;
	},

	show: function() {
	    visibility(true);
	    return m;
	},

	content: function() {
	    return content;
	},

	currentOpenButton: function() {
	    return currentOpenButton;
	}
    };
    return m;
};
<commit_msg>Cleaned up some code which was a bit too dense.<commit_after>"use strict";

/*global module, require*/

var d3 = require("d3");

/*
 Provides some functions which can be applied to an HTML element.
 */
module.exports = function(el) {
    var openButtons,
	currentOpenButton,
	closeButton,
	content = el.append("div")
	    .classed("content", true);

    var visibility = function(show, targetButton) {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);

	    if (show && targetButton !== undefined) {
		currentOpenButton = targetButton;
		targetButton.classed("element-visible", true);
	    }
	}
	el.style("visibility", show ? "visible" : "hidden");
    };

    var disable = function() {
	if (openButtons !== undefined) {
	    openButtons.classed("element-visible", false);
	}

	el.style("visibility", "hidden");
    };

    var toggle = function(button) {
	// if it's not visible, open it with the button
	var wasVisible = (el.style("visibility") === "visible");

	visibility(
	    !(wasVisible && button.node() === currentOpenButton.node()),
	    button
	);
    };

    el
	.style("overflow", "hidden");

    var m = {
	drag: function() {
	    el
		.style("cursor", "move")
		.style("position", "absolute");

	    if(el.style("left") === "auto") {
		el.style("left", 0);
	    }
	    if(el.style("top") === "auto") {
		el.style("top", 0);
	    }

	    el.call(
		d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("left")),
			    "y" : parseInt(el.style("top"))
			};
		    })
		    .on("drag", function(d){
			d3.event.sourceEvent.preventDefault();
			el
			    .style("top", d3.event.y + "px")
			    .style("left", d3.event.x + "px");
		    })
	    );

	    return m;
	},

	open: function(buttons) {
	    if (buttons.empty()) {
		buttons = undefined;
		currentOpenButton = undefined;
		m.hide();
		return m;
	    } else {
		// If the current open button isn't in the selection, clear it.
		if (currentOpenButton) {
		    var current = buttons.filter(function(d, i) {
			return this === currentOpenButton.node();
		    });

		    if (current.empty()) {
			currentOpenButton = undefined;
		    }
		}

		buttons
		    .classed("open-button", true)
		    .classed("element-visible", function(d, i) {
			if (el.attr("visibility") !== "hidden") {
			    if (currentOpenButton && this === currentOpenButton.node()) {
				return true;
			    } else if (currentOpenButton === undefined) {
				currentOpenButton = d3.select(this);
				return true;
			    }
			}
			return false;
		    })
		    .on("click", function(d, i) {
			d3.event.preventDefault();
			toggle(d3.select(this));
		    });

		openButtons = buttons;

		return m;
	    }
	},

	close: function() {
	    var closeButton = el
	    // This padding provides space for the button.
		    .style("padding-right", "1.5em")
		    .append("span")
		    .classed("close-button", true)
		    .style("font-size", "x-large")
		    .style("font-family", "monospace")
		    .style("position", "absolute")
		    .style("top", "0")
		    .style("right", "5px")
		    .style("opacity", "0.6")
		    .style("cursor", "pointer")
		    .html("X");

	    closeButton.on("click", disable);

	    return m;
	},

	resize: function() {
	    var dragHandle = d3.behavior.drag()
		    .origin(function(d){
			return {
			    "x" : parseInt(el.style("width")),
			    "y" : parseInt(el.style("height"))
			};
		    })
		    .on("dragstart", function(d){
			d3.event.sourceEvent.stopPropagation();
		    })
		    .on("drag", function(d){
			el.style("height", d3.event.y + "px");
			el.style("width", d3.event.x + "px");
		    });

	    el
	    // This padding prevents us from make the box too small to resize.
		.style("padding-bottom", "3em")
	    // This padding provides space for the button.
		.style("padding-right", "1.5em")
		.append("span")
		.style("font-size", "xx-large")
		.style("font-family", "monospace")
		.style("position", "absolute")
		.style("bottom", "0")
		.style("right", "5px")
		.style("opacity", "0.6")
		.html("⇘")
		.call(dragHandle);

	    return m;
	},

	hide: function() {
	    visibility(false);
	    return m;
	},

	show: function() {
	    visibility(true);
	    return m;
	},

	content: function() {
	    return content;
	},

	currentOpenButton: function() {
	    return currentOpenButton;
	}
    };
    return m;
};
<|endoftext|>