<commit_before>import React, { Component, PropTypes } from "react";
import _ from "lodash";

let groups = {};
let userAddedComponents = {};

let Groupings = {
  checkGroup: (groupName) => {
    let valid = true;
    let validityRes = {
      isValid: true,
      validCompponents: [],
      inValidComponents: []
    };
    let allCompsInGroup = groups[groupName];
    if (allCompsInGroup === undefined) {
      valid = true;
    } else {
      allCompsInGroup.forEach((v) => {
        if (v.isValid === false){
          valid = false;
          validityRes.inValidComponents.push(v.props.children);
        } else {
          validityRes.validCompponents.push(v.props.children);
        }
      });
    }
    validityRes.isValid = valid;
    return validityRes;
  }
};

let internalSupportedComponents = {
  TextField: {
    getValueFromChangeEvent: (args)=>{
      return args[0].target.value;
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    },
    errorPropName: "errorText"
  },
  SelectField: {
    getValueFromChangeEvent: (args)=>{
      return args[1];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0], args[1], args[2]);
    },
    errorPropName: "errorText"
  },
  DateRangePicker: {
    getValueFromChangeEvent: (args)=>{
      return args[0];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    },
    errorPropName: "errorText"
  },
  DatePicker: {
    getValueFromChangeEvent: (args)=>{
      return args[1];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[1]);
    }
  },
  Select: {
    getValueFromChangeEvent: (args)=>{
      return args[0];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    }
  }
};

function getAllSupportedComponent(){
  return Object.assign({}, internalSupportedComponents, userAddedComponents);
}

let SupportedComponentByFieldValidator = {
  addSupport: (name, getValueFromChangeEvent, changeCallBackCaller, errorPropName) => {
    userAddedComponents[name] = {
      getValueFromChangeEvent: getValueFromChangeEvent,
      changeCallBackCaller: changeCallBackCaller,
      errorPropName: errorPropName
    };
  },
  removeSupport: (name) => {
    if (userAddedComponents[name] !== undefined){
      delete userAddedComponents.name;
    } else {
      console.info("Field-Validator", "removeComponent: didn't find the component");
    }
  },
  getAllCurrentlySupported: ()=>{
    return getAllSupportedComponent();
  }
};

class Validation extends Component {

  constructor(props) {
    super(props);

    this.state = {
      childCompoentToRender: null,
      unControlledChild: true,
      isValid: true
    };
    this.testValidity = this.testValidity.bind(this);
  }

  get isValid() {
    return this.testValidity(this.currentChildValue);
  }

  componentWillReceiveProps(props){
    if (this.state.unsupported !== true){
      if (this.state.unControlledChild === false){
        let isDerivedValueComing = false;
        if (!(_.isEqual(this.originalVal, props.children.props[this.props.valueProp]))){
          isDerivedValueComing = true;
        }
        if (this.childModified === true || isDerivedValueComing){
          if (!(_.isEqual(this.currentChildValue, props.children.props[this.props.valueProp]))){
            this.baseProps[this.props.valueProp] = props.children.props[this.props.valueProp];
            this.testValidity(props.children.props.value);
          }
        }
      }
    }
  }

  componentWillMount() {
    this.typeOfCompnent = this.props.children.type.displayName ? this.props.children.type.displayName : this.props.children.type.name;
    if (userAddedComponents[this.typeOfCompnent] !== undefined){
      this.mountingSetup(userAddedComponents[this.typeOfCompnent].getValueFromChangeEvent, userAddedComponents[this.typeOfCompnent].changeCallBackCaller);
    } else {
      if (internalSupportedComponents[this.typeOfCompnent] !== undefined){
        this.mountingSetup(internalSupportedComponents[this.typeOfCompnent].getValueFromChangeEvent, internalSupportedComponents[this.typeOfCompnent].changeCallBackCaller);
      } else {
        console.error("Field-Validator",
          `${this.typeOfCompnent} is currently not supported by field-validator,
          Please use SupportedComponentByFieldValidator to add support for the component, For more information please refer to docs`);
        console.info("Field-Validator", `Ignoring ${this.typeOfCompnent}, and it will work as if it was not wraped with Validation tag`);
        this.mountingSetup(null, null, true);
      }
    }
  }

  componentDidMount(){
    if (this.props.group && this.state.unsupported !== true){
      if (groups[this.props.group] === undefined){
        groups[this.props.group] = [];
      }
      groups[this.props.group].push(this);
    }
  }

  mountingSetup(valueFromArgs, argsToPassToActualHandler, unsupportedFlag){
    if (unsupportedFlag === true){
      this.setState({
        childCompoentToRender: this.props.children,
        unsupported: unsupportedFlag
      });
    } else {
      this.baseProps = _.cloneDeep(this.props.children.props);
      let isUncontrolled = true;
      if (this.baseProps[this.props.valueProp] !== undefined){
        isUncontrolled = false;
        this.originalVal = this.baseProps[this.props.valueProp];
        this.currentChildValue = this.baseProps[this.props.valueProp];
      } else {
        //try with default prop
        if (this.baseProps[this.props.defaultValueProp] !== undefined){
          this.originalVal = this.baseProps[this.props.defaultValueProp];
          this.currentChildValue = this.baseProps[this.props.defaultValueProp];
        }
      }

      let oldOnChange = this.baseProps[this.props.onChangeCallback];
      this.baseProps[this.props.onChangeCallback] = (...args)=>{
        let rArgs = valueFromArgs(args);
        this.childModified = true;
        if (!this.absorbing){
          this.absorbing = true;
          this.baseProps[this.props.valueProp] = rArgs;
          this.currentChildValue = rArgs;
          this.testValidity(rArgs);
          if (oldOnChange) {
            argsToPassToActualHandler(oldOnChange, args);
          }
          this.absorbing = false;
        }
      };
      let theComponent = React.cloneElement(this.props.children, this.baseProps);
      this.setState({
        childCompoentToRender: theComponent,
        unControlledChild: isUncontrolled
      });
    }
  }

  testValidity(val){
    let res = {
      isValid: true,
      errorMessage: null
    };
    try {
      this.props.validators.every((v)=>{
        if (v.validator(val) === false){
          res.isValid = false;
          res.errorMessage = v.errorMessage;
          return false;
        } else {
          return true;
        }
      });
    } catch (err) {
      console.error(err);
    }
    if (res.isValid === false){
      if (getAllSupportedComponent()[this.typeOfCompnent].errorPropName){
        this.baseProps[getAllSupportedComponent()[this.typeOfCompnent].errorPropName] = res.errorMessage;
      }
      this.setState({
        childCompoentToRender: React.cloneElement(this.props.children, this.baseProps),
        isValid: false,
        errorText: res.errorMessage
      });
    } else {
      if (getAllSupportedComponent()[this.typeOfCompnent].errorPropName){
        this.baseProps[getAllSupportedComponent()[this.typeOfCompnent].errorPropName] = null;
      }
      this.setState({
        childCompoentToRender: React.cloneElement(this.props.children, this.baseProps),
        isValid: true,
        errorText: null
      });
    }
    return res.isValid;
  }

  render() {
    if (this.state.unsupported === true){
      return this.props.children;
    } else {
      return (

        {
          this.state.childCompoentToRender ? this.state.childCompoentToRender : ""
        }{
          (!(getAllSupportedComponent()[this.typeOfCompnent].errorPropName)) && this.state.isValid === false ?

            {
              this.state.errorText
            }

 : ""
        }

      );
    }
  }
}

Validation.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.element
  ]),
  validators: PropTypes.array.isRequired,
  onChangeCallback: PropTypes.string,
  group: PropTypes.string,
  valueProp: PropTypes.string,
  defaultValueProp: PropTypes.string
};

Validation.defaultProps = {
  onChangeCallback: "onChange",
  valueProp: "value",
  defaultValueProp: "defaultValue"
};

export {Validation, Groupings, SupportedComponentByFieldValidator};
<commit_msg>added autor info<commit_after>/*
* author Vishal Daga
* Email: vishaldaga10@gmail.com
* */

import React, { Component, PropTypes } from "react";
import _ from "lodash";

let groups = {};
let userAddedComponents = {};

let Groupings = {
  checkGroup: (groupName) => {
    let valid = true;
    let validityRes = {
      isValid: true,
      validCompponents: [],
      inValidComponents: []
    };
    let allCompsInGroup = groups[groupName];
    if (allCompsInGroup === undefined) {
      valid = true;
    } else {
      allCompsInGroup.forEach((v) => {
        if (v.isValid === false){
          valid = false;
          validityRes.inValidComponents.push(v.props.children);
        } else {
          validityRes.validCompponents.push(v.props.children);
        }
      });
    }
    validityRes.isValid = valid;
    return validityRes;
  }
};

let internalSupportedComponents = {
  TextField: {
    getValueFromChangeEvent: (args)=>{
      return args[0].target.value;
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    },
    errorPropName: "errorText"
  },
  SelectField: {
    getValueFromChangeEvent: (args)=>{
      return args[1];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0], args[1], args[2]);
    },
    errorPropName: "errorText"
  },
  DateRangePicker: {
    getValueFromChangeEvent: (args)=>{
      return args[0];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    },
    errorPropName: "errorText"
  },
  DatePicker: {
    getValueFromChangeEvent: (args)=>{
      return args[1];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[1]);
    }
  },
  Select: {
    getValueFromChangeEvent: (args)=>{
      return args[0];
    },
    changeCallBackCaller: (callback, args)=>{
      callback(args[0]);
    }
  }
};

function getAllSupportedComponent(){
  return Object.assign({}, internalSupportedComponents, userAddedComponents);
}

let SupportedComponentByFieldValidator = {
  addSupport: (name, getValueFromChangeEvent, changeCallBackCaller, errorPropName) => {
    userAddedComponents[name] = {
      getValueFromChangeEvent: getValueFromChangeEvent,
      changeCallBackCaller: changeCallBackCaller,
      errorPropName: errorPropName
    };
  },
  removeSupport: (name) => {
    if (userAddedComponents[name] !== undefined){
      delete userAddedComponents.name;
    } else {
      console.info("Field-Validator", "removeComponent: didn't find the component");
    }
  },
  getAllCurrentlySupported: ()=>{
    return getAllSupportedComponent();
  }
};

class Validation extends Component {

  constructor(props) {
    super(props);

    this.state = {
      childCompoentToRender: null,
      unControlledChild: true,
      isValid: true
    };
    this.testValidity = this.testValidity.bind(this);
  }

  get isValid() {
    return this.testValidity(this.currentChildValue);
  }

  componentWillReceiveProps(props){
    if (this.state.unsupported !== true){
      if (this.state.unControlledChild === false){
        let isDerivedValueComing = false;
        if (!(_.isEqual(this.originalVal, props.children.props[this.props.valueProp]))){
          isDerivedValueComing = true;
        }
        if (this.childModified === true || isDerivedValueComing){
          if (!(_.isEqual(this.currentChildValue, props.children.props[this.props.valueProp]))){
            this.baseProps[this.props.valueProp] = props.children.props[this.props.valueProp];
            this.testValidity(props.children.props.value);
          }
        }
      }
    }
  }

  componentWillMount() {
    this.typeOfCompnent = this.props.children.type.displayName ? this.props.children.type.displayName : this.props.children.type.name;
    if (userAddedComponents[this.typeOfCompnent] !== undefined){
      this.mountingSetup(userAddedComponents[this.typeOfCompnent].getValueFromChangeEvent, userAddedComponents[this.typeOfCompnent].changeCallBackCaller);
    } else {
      if (internalSupportedComponents[this.typeOfCompnent] !== undefined){
        this.mountingSetup(internalSupportedComponents[this.typeOfCompnent].getValueFromChangeEvent, internalSupportedComponents[this.typeOfCompnent].changeCallBackCaller);
      } else {
        console.error("Field-Validator",
          `${this.typeOfCompnent} is currently not supported by field-validator,
          Please use SupportedComponentByFieldValidator to add support for the component, For more information please refer to docs`);
        console.info("Field-Validator", `Ignoring ${this.typeOfCompnent}, and it will work as if it was not wraped with Validation tag`);
        this.mountingSetup(null, null, true);
      }
    }
  }

  componentDidMount(){
    if (this.props.group && this.state.unsupported !== true){
      if (groups[this.props.group] === undefined){
        groups[this.props.group] = [];
      }
      groups[this.props.group].push(this);
    }
  }

  mountingSetup(valueFromArgs, argsToPassToActualHandler, unsupportedFlag){
    if (unsupportedFlag === true){
      this.setState({
        childCompoentToRender: this.props.children,
        unsupported: unsupportedFlag
      });
    } else {
      this.baseProps = _.cloneDeep(this.props.children.props);
      let isUncontrolled = true;
      if (this.baseProps[this.props.valueProp] !== undefined){
        isUncontrolled = false;
        this.originalVal = this.baseProps[this.props.valueProp];
        this.currentChildValue = this.baseProps[this.props.valueProp];
      } else {
        //try with default prop
        if (this.baseProps[this.props.defaultValueProp] !== undefined){
          this.originalVal = this.baseProps[this.props.defaultValueProp];
          this.currentChildValue = this.baseProps[this.props.defaultValueProp];
        }
      }

      let oldOnChange = this.baseProps[this.props.onChangeCallback];
      this.baseProps[this.props.onChangeCallback] = (...args)=>{
        let rArgs = valueFromArgs(args);
        this.childModified = true;
        if (!this.absorbing){
          this.absorbing = true;
          this.baseProps[this.props.valueProp] = rArgs;
          this.currentChildValue = rArgs;
          this.testValidity(rArgs);
          if (oldOnChange) {
            argsToPassToActualHandler(oldOnChange, args);
          }
          this.absorbing = false;
        }
      };
      let theComponent = React.cloneElement(this.props.children, this.baseProps);
      this.setState({
        childCompoentToRender: theComponent,
        unControlledChild: isUncontrolled
      });
    }
  }

  testValidity(val){
    let res = {
      isValid: true,
      errorMessage: null
    };
    try {
      this.props.validators.every((v)=>{
        if (v.validator(val) === false){
          res.isValid = false;
          res.errorMessage = v.errorMessage;
          return false;
        } else {
          return true;
        }
      });
    } catch (err) {
      console.error(err);
    }
    if (res.isValid === false){
      if (getAllSupportedComponent()[this.typeOfCompnent].errorPropName){
        this.baseProps[getAllSupportedComponent()[this.typeOfCompnent].errorPropName] = res.errorMessage;
      }
      this.setState({
        childCompoentToRender: React.cloneElement(this.props.children, this.baseProps),
        isValid: false,
        errorText: res.errorMessage
      });
    } else {
      if (getAllSupportedComponent()[this.typeOfCompnent].errorPropName){
        this.baseProps[getAllSupportedComponent()[this.typeOfCompnent].errorPropName] = null;
      }
      this.setState({
        childCompoentToRender: React.cloneElement(this.props.children, this.baseProps),
        isValid: true,
        errorText: null
      });
    }
    return res.isValid;
  }

  render() {
    if (this.state.unsupported === true){
      return this.props.children;
    } else {
      return (

        {
          this.state.childCompoentToRender ? this.state.childCompoentToRender : ""
        }{
          (!(getAllSupportedComponent()[this.typeOfCompnent].errorPropName)) && this.state.isValid === false ?

            {
              this.state.errorText
            }

 : ""
        }

      );
    }
  }
}

Validation.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.element
  ]),
  validators: PropTypes.array.isRequired,
  onChangeCallback: PropTypes.string,
  group: PropTypes.string,
  valueProp: PropTypes.string,
  defaultValueProp: PropTypes.string
};

Validation.defaultProps = {
  onChangeCallback: "onChange",
  valueProp: "value",
  defaultValueProp: "defaultValue"
};

export {Validation, Groupings, SupportedComponentByFieldValidator};
<|endoftext|>


<commit_before>/**
# importing from the future

Methods in here workaround circular references.
~~~~
const {playSavedMessages} = await import('./b8r.future.js')

const div = b8r.create('div');
div.dataset.event = 'click:future-test.click';
document.body.appendChild(div);
b8r.trigger('click', div);
Test(() => b8r.get('future-test.clickCount')).shouldBe(null)
b8r.register('future-test', {
  click () {
    b8r.increment('future-test.clickCount')
  }
})
await b8r.forceUpdate()
Test(() => b8r.get('future-test.clickCount')).shouldBe(1)
~~~~
*/

export let playSavedMessages = () => {
  throw new Error('playSavedMessages is not ready yet')
}

export const setPlaySavedMessages = (fn) => {
  playSavedMessages = fn
}
<commit_msg>fix — b8r.future.js fails subsequent tests.<commit_after>/**
# importing from the future

Methods in here workaround circular references.
~~~~
const {playSavedMessages} = await import('./b8r.future.js')

const div = b8r.create('div');
div.dataset.event = 'click:future-test.click';
document.body.appendChild(div);
b8r.trigger('click', div);
Test(() => b8r.get('future-test.clickCount')).shouldBe(null)
b8r.register('future-test', {
  click () {
    b8r.increment('future-test.clickCount')
  }
})
await b8r.forceUpdate()
Test(() => b8r.get('future-test.clickCount')).shouldBe(1)
b8r.deregister('future-test')
~~~~
*/

export let playSavedMessages = () => {
  throw new Error('playSavedMessages is not ready yet')
}

export const setPlaySavedMessages = (fn) => {
  playSavedMessages = fn
}
<|endoftext|>


<commit_before>const https = require('https');

const options = {
	hostname: process.argv[2],
	path: '/',
	method: 'GET',
	headers:{
		'Accept': '*/*'
	}
};

let count = 0;
const limit = parseInt(process.argv[3]);
const intervalTime = Number(process.argv[4]) ? parseInt(process.argv[4]) : 	Math.ceil((Math.random() * 100)) ;

function loop(){
	setTimeout(() => {
		let randNumber = parseInt(Math.random() * 10000000 + 10000);
		options.path = `/?bid=test${randNumber}&pid=test${randNumber}`;
		let request = https.request( options , (res) => {
			console.log(`Status: ${res.statusCode} , Count: ${++count}`);
			console.log(options.path);
			if(count < limit){
				loop();
			}
		});

		request.on('error', (e) => {
			console.log(`Error: ${e.message}`);
		})

		request.end();

	}, intervalTime);
}

loop();

<commit_msg>Add random variable to get-request.js in order to account for variables<commit_after>const https = require('https');

const options = {
	hostname: process.argv[2],
	path: '/',
	method: 'GET',
	headers:{
		'Accept': '*/*'
	}
};

let count = 0;
const limit = parseInt(process.argv[3]);
const intervalTime = Number(process.argv[4]) ? parseInt(process.argv[4]) : 	Math.ceil(Math.random() * 100);

function loop(){
	setTimeout(() => {
		let randNumber = parseInt(Math.random() * 10000000 + 10000);
		options.path = `/?bid=test${randNumber}&pid=test${randNumber}`;
		let request = https.request( options , (res) => {
			console.log(`Status: ${res.statusCode} , Count: ${++count}`);
			console.log(options.path);
			if(count < limit){
				loop();
			}
		});

		request.on('error', (e) => {
			console.log(`Error: ${e.message}`);
		})

		request.end();

	}, intervalTime);
}

loop();

<|endoftext|>


<commit_before>

export default class Slug
{
    /**
     * Constructs a new instance
     *
     * @param {Array.<Array.<*>>} transforms
     * @param {?RegExp} sanitize
     */
    constructor (transforms = [], sanitize = null)
    {
        /**
         * @private
         * @type {Array.<Array.<RegExp, string>>}
         */
        this.transforms = [];

        /**
         * The sanitizing regexp, that removes all unwanted characters
         *
         * @private
         * @type {RegExp}
         */
        this.sanitize = null !== sanitize
            ? sanitize
            : /[^a-z0-9\-._~(),;!]/g;

        transforms = transforms.concat([
            [/ä/, "ae"],
            [/[áâà]/, "a"],
            [/ö/, "oe"],
            [/[óôò]/, "o"],
            [/ü/, "ue"],
            [/[úûù]/, "u"],
            [/ß/, "ss"],
        ]);

        // automatically add the g (for "global") modifier to all regexes
        for (let i = 0; i < transforms.length; i++)
        {
            let from = transforms[i][0];

            if (-1 === from.flags.indexOf("g"))
            {
                from = new RegExp(from.source, `${from.flags}g`);
            }

            this.transforms.push([
                from,
                transforms[i][1],
            ]);
        }
    }

    /**
     * Transforms a raw slug to a prepared slug
     *
     * @param {string} raw
     * @return {string}
     */
    transform (raw)
    {
        // transform to string
        raw = ("" + raw).toLowerCase(); // eslint-disable-line prefer-template

        for (let i = 0; i < this.transforms.length; i++)
        {
            raw = raw.replace(this.transforms[i][0], this.transforms[i][1]);
        }

        return raw
            .replace(this.sanitize, "-")
            .replace(/-+/g, "-")
            .replace(/^-+/, "");
    }
}
<commit_msg>`regex.flags` is not always defined<commit_after>

export default class Slug
{
    /**
     * Constructs a new instance
     *
     * @param {Array.<Array.<*>>} transforms
     * @param {?RegExp} sanitize
     */
    constructor (transforms = [], sanitize = null)
    {
        /**
         * @private
         * @type {Array.<Array.<RegExp, string>>}
         */
        this.transforms = [];

        /**
         * The sanitizing regexp, that removes all unwanted characters
         *
         * @private
         * @type {RegExp}
         */
        this.sanitize = null !== sanitize
            ? sanitize
            : /[^a-z0-9\-._~(),;!]/g;

        transforms = transforms.concat([
            [/ä/, "ae"],
            [/[áâà]/, "a"],
            [/ö/, "oe"],
            [/[óôò]/, "o"],
            [/ü/, "ue"],
            [/[úûù]/, "u"],
            [/ß/, "ss"],
        ]);

        // automatically add the g (for "global") modifier to all regexes
        for (let i = 0; i < transforms.length; i++)
        {
            let from = transforms[i][0];
            const flags = typeof flags === "string"
                ? flags
                : "";

            if (-1 === flags.indexOf("g"))
            {
                from = new RegExp(from.source, `${flags}g`);
            }

            this.transforms.push([
                from,
                transforms[i][1],
            ]);
        }
    }

    /**
     * Transforms a raw slug to a prepared slug
     *
     * @param {string} raw
     * @return {string}
     */
    transform (raw)
    {
        // transform to string
        raw = ("" + raw).toLowerCase(); // eslint-disable-line prefer-template

        for (let i = 0; i < this.transforms.length; i++)
        {
            raw = raw.replace(this.transforms[i][0], this.transforms[i][1]);
        }

        return raw
            .replace(this.sanitize, "-")
            .replace(/-+/g, "-")
            .replace(/^-+/, "");
    }
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

const SprkFlag = (props) => {
  const {
    additionalBodyClasses,
    additionalMediaClasses,
    children,
    media,
    isReversed,
    isStacked,
    verticalAlignment,
    idString,
    additionalClasses,
    spacing,
    ...other
  } = props;

  const flagClassNames = classnames(
    'sprk-o-Flag',
    additionalClasses,
    {
      'sprk-o-Flag--stacked': isStacked,
      'sprk-o-Flag--rev': isReversed,
      'sprk-o-Flag--middle': verticalAlignment === 'middle',
      'sprk-o-Flag--bottom': verticalAlignment === 'bottom',
      'sprk-o-Flag--tiny': spacing === 'tiny',
      'sprk-o-Flag--small': spacing === 'small',
      'sprk-o-Flag--large': spacing === 'large',
      'sprk-o-Flag--huge': spacing === 'huge',
    },
  );

  return (

        {media}

        {children}

  );
};

SprkFlag.propTypes = {
  /**
   * Recieves a component that will render media into the Flag component. Required.
   */
  media: PropTypes.element.isRequired,
  /**
   * Reverses the order of the figure and body.
   */
  isReversed: PropTypes.bool,
  /**
   * Stacks elements at `$sprk-flag-stacked-breakpoint`
   */
  isStacked: PropTypes.bool,
  /**
   * Determines how much space between the figure and the body.
   */
  spacing: PropTypes.oneOf(['tiny', 'small','medium', 'large', 'huge']),
  /**
   * Determines the vertical alignment of content.
   */
  verticalAlignment: PropTypes.oneOf(['top', 'middle', 'bottom']),
  /**
   * Assigned to the `data-id` attribute serving as a unique selector for automated tools.
   */
  idString: PropTypes.string,
  /**
   * A space-separated string of classes to add to the media container of the component.
   */
  additionalMediaClasses: PropTypes.string,
  /**
   * A space-separated string of classes to add to the body container of the component.
   */
  additionalBodyClasses: PropTypes.string,
  /**
   * A space-separated string of classes to add to the outermost container of the component.
   */
  additionalClasses: PropTypes.string,
};

export default SprkFlag;
<commit_msg>Remove extra line<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

const SprkFlag = (props) => {
  const {
    additionalBodyClasses,
    additionalMediaClasses,
    children,
    media,
    isReversed,
    isStacked,
    verticalAlignment,
    idString,
    additionalClasses,
    spacing,
    ...other
  } = props;

  const flagClassNames = classnames(
    'sprk-o-Flag',
    additionalClasses,
    {
      'sprk-o-Flag--stacked': isStacked,
      'sprk-o-Flag--rev': isReversed,
      'sprk-o-Flag--middle': verticalAlignment === 'middle',
      'sprk-o-Flag--bottom': verticalAlignment === 'bottom',
      'sprk-o-Flag--tiny': spacing === 'tiny',
      'sprk-o-Flag--small': spacing === 'small',
      'sprk-o-Flag--large': spacing === 'large',
      'sprk-o-Flag--huge': spacing === 'huge',
    },
  );

  return (

        {media}

        {children}

  );
};

SprkFlag.propTypes = {
  /**
   * Recieves a component that will render media into the Flag component. Required.
   */
  media: PropTypes.element.isRequired,
  /**
   * Reverses the order of the figure and body.
   */
  isReversed: PropTypes.bool,
  /**
   * Stacks elements at `$sprk-flag-stacked-breakpoint`
   */
  isStacked: PropTypes.bool,
  /**
   * Determines how much space between the figure and the body.
   */
  spacing: PropTypes.oneOf(['tiny', 'small','medium', 'large', 'huge']),
  /**
   * Determines the vertical alignment of content.
   */
  verticalAlignment: PropTypes.oneOf(['top', 'middle', 'bottom']),
  /**
   * Assigned to the `data-id` attribute serving as a unique selector for automated tools.
   */
  idString: PropTypes.string,
  /**
   * A space-separated string of classes to add to the media container of the component.
   */
  additionalMediaClasses: PropTypes.string,
  /**
   * A space-separated string of classes to add to the body container of the component.
   */
  additionalBodyClasses: PropTypes.string,
  /**
   * A space-separated string of classes to add to the outermost container of the component.
   */
  additionalClasses: PropTypes.string,
};

export default SprkFlag;
<|endoftext|>


<commit_before>/**
 * Created by thomasjeanneau on 09/04/2017.
 */

import Promise from 'bluebird'

import {
  getSlackUser,
  getMemberBySlackHandler,
  checkIfBuilder,
  updateMember
} from '../methods'
import { controller } from './config'
import { validateAddress } from '../gmaps'

require('dotenv').config()

const {NODE_ENV} = process.env

if (!NODE_ENV) {
  console.log('Error: Specify NODE_ENV in a .env file')
  process.exit(1)
}

// Helper Methods
const giveHelp = function() {
  return `'!newloc <city or country>' for me to update your location,
  '!myloc' if you want to know where I think you are,
  '!map' for a link to Mangrove Members map!`
};

const handleError = function(e, bot) {
  console.log(e)
  bot.reply(message, `Oops..! :sweat_smile: A little error occur: \`${e.message || e.error || e}\``)
}

// User Commands
controller.hears(['^Hello', '^Yo', '^Hey', '^Hi', '^Ouch'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    bot.startConversation(message, function (err, convo) {
      if (err) return console.log(err)
      convo.say(`Hey ${name}!`)
      convo.say(`I'm Marco Polo! I'm taking care of keeping everyone's location up to date :boat:`)
      convo.say(`Here are the few commands you can use with me :ok_woman:`)
      convo.say(giveHelp())
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^help', '^options$'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    const botReply = Promise.promisify(bot.reply)
    await botReply(message, `Hi ${name}! What can I do for you ? :slightly_smiling_face:`)
    await botReply(message, {
      attachments: [{
        pretext: 'This is what you can ask me:',
        text: giveHelp(),
        mrkdwn_in: ['text', 'pretext']
      }]
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^!myloc'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const slackUser = await getSlackUser(bot, message.user)
    const user = await getMemberBySlackHandler(slackUser.name)
    const botReply = Promise.promisify(bot.reply)
    await botReply(message, {
      attachments: [{
        pretext: 'Your location seems to be:',
        text: user.fields['Postal Adress'],
        mrkdwn_in: ['text', 'pretext']
      }]
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^!newloc'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const botReply = Promise.promisify(bot.reply)

    const slackUser = await getSlackUser(bot, message.user)
    const user = await getMemberBySlackHandler(slackUser.name)

    const address = message.text.replace('!newloc', '')
    if (address.length === 0) {
      await botReply(message, {
        attachments: [{
          pretext: `It seems like you didn't give me any address... Please send me something like the following example:`,
          text: `!newloc 123 5th av., New York NY`
        }]
      })
      return
    }

    const validatedLocs = await validateAddress(address)
    if (validatedLocs.length === 1) {
      await botReply(message, {
        attachments: [{
          callback_id: '1',
          attachment_type: 'default',
          pretext: `I found a matching address, is it correct?`,
          title: validatedLocs[0].formatted_address,
          actions: [
            {
              'name': 'addressConfirmed',
              'text': 'Yes',
              'type': 'button',
              'value': validatedLocs[0].formatted_address,
              'style': 'primary'
            },
            {
              'name': 'addressConfirmed',
              'text': 'No',
              'type': 'button',
              'value': false,
              'style': 'danger'
            }
          ]
        }]
      })
    } else {
      const actions = [];
      for (loc of validatedLocs) {
        actions.push({
          name: 'addressSelect',
          text: loc.formatted_address,
          'type': 'button',
          'value': loc.formatted_address
        })
      }
      await botReply(message, {
        attachments: [{
          callback_id: '2',
          attachment_type: 'default',
          pretext: `I found multiple matching addresses, please select the correct one!`,
          actions: actions
        }]
      })
    }

    // TODO: ask user to confirm they want to change their location to validated address
    // const updatedMember = await updateMember(user.id, {
    //   'Postal Adress': validatedLocs[0].formatted_address
    // })

    // await botReply(message, {
    //   attachments: [{
    //     pretext: 'Ok, I updated your location to:',
    //     text: updatedMember.fields['Postal Adress'],
    //     mrkdwn_in: ['text', 'pretext']
    //   }]
    // })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears('[^\n]+', ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    bot.startConversation(message, function (err, convo) {
      if (err) return console.log(err)
      convo.say(`Sorry ${name}, but I'm too young to understand what you mean :flushed:`)
      convo.say(`If you need help, just tell me \`help\` :wink:`)
    })
  } catch (e) {
    handleError(e, bot)
  }
})

// receive an interactive message, and reply with a message that will replace the original
controller.on('interactive_message_callback', function(bot, message) {
  console.log(message)
  switch (message.callback_id) {
    // address confirmation
    case '1':
      handleAddressConfirmation(bot, message)
      break
    // address selection
    case '2':
      handleAddressSelect(bot, message)
      break
  }
})

const handleAddressConfirmation = function(bot, message) {
  let text;
  if (message.actions[0].value) {
    updateMember(message.user.id, {
    'Postal Adress': message.actions[0].value
    })
    text = `:white_check_mark: ${message.actions[0].value}`
  } else {
    text = ':x:'
  }

  bot.replyInteractive(message, {
    attachments: [{
      callback_id: '1',
      attachment_type: 'default',
      pretext: `I found a matching address, is it correct?`,
      title: validatedLocs[0].formatted_address,
      actions: [
        {
          'text': text
        }
      ]
    }]
  })
}

const handleAddressSelect = function(bot, message) {
  updateMember(message.user.id, {
    'Postal Adress': message.actions[0].value
  })
  bot.replyInteractive(message, {
    attachments: [{
      callback_id: '2',
      attachment_type: 'default',
      pretext: `I found multiple matching addresses, please select the correct one!`,
      actions: [
        {
          'text': `:white_check_mark:`
        }
      ]
    }]
  })
}
<commit_msg>fix validation<commit_after>/**
 * Created by thomasjeanneau on 09/04/2017.
 */

import Promise from 'bluebird'

import {
  getSlackUser,
  getMemberBySlackHandler,
  checkIfBuilder,
  updateMember
} from '../methods'
import { controller } from './config'
import { validateAddress } from '../gmaps'

require('dotenv').config()

const {NODE_ENV} = process.env

if (!NODE_ENV) {
  console.log('Error: Specify NODE_ENV in a .env file')
  process.exit(1)
}

// Helper Methods
const giveHelp = function() {
  return `'!newloc <city or country>' for me to update your location,
  '!myloc' if you want to know where I think you are,
  '!map' for a link to Mangrove Members map!`
};

const handleError = function(e, bot) {
  console.log(e)
  bot.reply(message, `Oops..! :sweat_smile: A little error occur: \`${e.message || e.error || e}\``)
}

// User Commands
controller.hears(['^Hello', '^Yo', '^Hey', '^Hi', '^Ouch'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    bot.startConversation(message, function (err, convo) {
      if (err) return console.log(err)
      convo.say(`Hey ${name}!`)
      convo.say(`I'm Marco Polo! I'm taking care of keeping everyone's location up to date :boat:`)
      convo.say(`Here are the few commands you can use with me :ok_woman:`)
      convo.say(giveHelp())
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^help', '^options$'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    const botReply = Promise.promisify(bot.reply)
    await botReply(message, `Hi ${name}! What can I do for you ? :slightly_smiling_face:`)
    await botReply(message, {
      attachments: [{
        pretext: 'This is what you can ask me:',
        text: giveHelp(),
        mrkdwn_in: ['text', 'pretext']
      }]
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^!myloc'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const slackUser = await getSlackUser(bot, message.user)
    const user = await getMemberBySlackHandler(slackUser.name)
    const botReply = Promise.promisify(bot.reply)
    await botReply(message, {
      attachments: [{
        pretext: 'Your location seems to be:',
        text: user.fields['Postal Adress'],
        mrkdwn_in: ['text', 'pretext']
      }]
    })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears(['^!newloc'], ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const botReply = Promise.promisify(bot.reply)

    const slackUser = await getSlackUser(bot, message.user)
    const user = await getMemberBySlackHandler(slackUser.name)

    const address = message.text.replace('!newloc', '')
    if (address.length === 0) {
      await botReply(message, {
        attachments: [{
          pretext: `It seems like you didn't give me any address... Please send me something like the following example:`,
          text: `!newloc 123 5th av., New York NY`
        }]
      })
      return
    }

    const validatedLocs = await validateAddress(address)
    if (validatedLocs.length === 1) {
      await botReply(message, {
        attachments: [{
          callback_id: '1',
          attachment_type: 'default',
          pretext: `I found a matching address, is it correct?`,
          title: validatedLocs[0].formatted_address,
          actions: [
            {
              'name': 'addressConfirmed',
              'text': 'Yes',
              'type': 'button',
              'value': validatedLocs[0].formatted_address,
              'style': 'primary'
            },
            {
              'name': 'addressConfirmed',
              'text': 'No',
              'type': 'button',
              'value': false,
              'style': 'danger'
            }
          ]
        }]
      })
    } else {
      const actions = [];
      for (loc of validatedLocs) {
        actions.push({
          name: 'addressSelect',
          text: loc.formatted_address,
          'type': 'button',
          'value': loc.formatted_address
        })
      }
      await botReply(message, {
        attachments: [{
          callback_id: '2',
          attachment_type: 'default',
          pretext: `I found multiple matching addresses, please select the correct one!`,
          actions: actions
        }]
      })
    }

    // TODO: ask user to confirm they want to change their location to validated address
    // const updatedMember = await updateMember(user.id, {
    //   'Postal Adress': validatedLocs[0].formatted_address
    // })

    // await botReply(message, {
    //   attachments: [{
    //     pretext: 'Ok, I updated your location to:',
    //     text: updatedMember.fields['Postal Adress'],
    //     mrkdwn_in: ['text', 'pretext']
    //   }]
    // })
  } catch (e) {
    handleError(e, bot)
  }
})

controller.hears('[^\n]+', ['direct_message', 'direct_mention'], async (bot, message) => {
  try {
    const {name} = await getSlackUser(bot, message.user)
    bot.startConversation(message, function (err, convo) {
      if (err) return console.log(err)
      convo.say(`Sorry ${name}, but I'm too young to understand what you mean :flushed:`)
      convo.say(`If you need help, just tell me \`help\` :wink:`)
    })
  } catch (e) {
    handleError(e, bot)
  }
})

// receive an interactive message, and reply with a message that will replace the original
controller.on('interactive_message_callback', function(bot, message) {
  console.log(message)
  switch (message.callback_id) {
    // address confirmation
    case '1':
      handleAddressConfirmation(bot, message)
      break
    // address selection
    case '2':
      handleAddressSelect(bot, message)
      break
  }
})

const handleAddressConfirmation = async function(bot, message) {
  let actions = [];
  if (message.actions[0].value) {
    const slackUser = await getSlackUser(bot, message.user)
    const user = await getMemberBySlackHandler(slackUser.name)

    updateMember(user.id, {
    'Postal Adress': message.actions[0].value
    })

    actions.push({
      text: `:white_check_mark:`
    })
  } else {
    actions.push({
      text: `:x:`
    })
  }

  const attachments = message.original_message.attachments
  attachments[0].actions = actions
  bot.replyInteractive(message, {attachments: attachments})
}

const handleAddressSelect = function(bot, message) {
  const slackUser = await getSlackUser(bot, message.user)
  const user = await getMemberBySlackHandler(slackUser.name)
  updateMember(user.id, {
    'Postal Adress': message.actions[0].value
  })
  bot.replyInteractive(message, {
    attachments: [{
      callback_id: '2',
      attachment_type: 'default',
      pretext: `I found multiple matching addresses, please select the correct one!`,
      actions: [
        {
          'text': `:white_check_mark:`
        }
      ]
    }]
  })
}
<|endoftext|>


<commit_before>'use strict';

angular.module('ddsCommon').factory('CustomizationService', function(lyonMetropoleInseeCodes) {

    function determineCustomizationId(testCase, currentPeriod) {
        if (testCase.menages &&
            testCase.menages._) {
            if (testCase.menages._.depcom[currentPeriod].match(/^06/))
                return 'D06-ALPES_MARITIMES';
            if (testCase.menages._.depcom[currentPeriod].match(/^13/))
                return 'D13-BDR';
            if (testCase.menages._.depcom[currentPeriod].match(/^14/))
                return 'D14-CALVADOS';
            if (testCase.menages._.depcom[currentPeriod].match(/^29/))
                return 'D29-FINISTERE';
            if (testCase.menages._.depcom[currentPeriod].match(/^31/))
                return 'D31-HAUTE_GARONNE';
            if (testCase.menages._.depcom[currentPeriod].match(/^33/))
                return 'D33-GIRONDE';
            if (testCase.menages._.depcom[currentPeriod].match(/^34/))
                return 'D34-HERAULT';
            if (testCase.menages._.depcom[currentPeriod].match(/^35/))
                return 'D35-ILLE_ET_VILAINE';
            if (testCase.menages._.depcom[currentPeriod].match(/^42/))
                return 'D42-LOIRE';
            if (testCase.menages._.depcom[currentPeriod].match(/^44/))
                return 'D44-LOIRE_ATLANTIQUE';
            if (testCase.menages._.depcom[currentPeriod].match(/^57/))
                return 'D57-MOSELLE';
            if (testCase.menages._.depcom[currentPeriod].match(/^59/))
                return 'D59-NORD';
            if (testCase.menages._.depcom[currentPeriod].match(/^62/))
                return 'D62-PDC';
            if (testCase.menages._.depcom[currentPeriod].match(/^67/))
                return 'D67-BAS_RHIN';
            if (testCase.menages._.depcom[currentPeriod].match(/^75/))
                return 'D75-PARIS';
            if (testCase.menages._.depcom[currentPeriod].match(/^76/))
                return 'D76-SEINE_MARITIME';
            if (testCase.menages._.depcom[currentPeriod].match(/^77/))
                return 'D77-SEINE_ET_MARNE';
            if (testCase.menages._.depcom[currentPeriod].match(/^83/))
                return 'D83-VAR';
            if (testCase.menages._.depcom[currentPeriod].match(/^92/))
                return 'D92-HAUTS_DE_SEINE';
            if (testCase.menages._.depcom[currentPeriod].match(/^93/))
                return 'D93-SSD';
            if (_.includes(lyonMetropoleInseeCodes, testCase.menages._.depcom[currentPeriod]))
                return 'M69-LYON';
        }
        return undefined;
    }
    return {
        determineCustomizationId: determineCustomizationId,
    };
});
<commit_msg>Add customization cd05<commit_after>'use strict';

angular.module('ddsCommon').factory('CustomizationService', function(lyonMetropoleInseeCodes) {

    function determineCustomizationId(testCase, currentPeriod) {
        if (testCase.menages &&
            testCase.menages._) {
            if (testCase.menages._.depcom[currentPeriod].match(/^05/))
                return 'D05-HAUTES_ALPES';
            if (testCase.menages._.depcom[currentPeriod].match(/^06/))
                return 'D06-ALPES_MARITIMES';
            if (testCase.menages._.depcom[currentPeriod].match(/^13/))
                return 'D13-BDR';
            if (testCase.menages._.depcom[currentPeriod].match(/^14/))
                return 'D14-CALVADOS';
            if (testCase.menages._.depcom[currentPeriod].match(/^29/))
                return 'D29-FINISTERE';
            if (testCase.menages._.depcom[currentPeriod].match(/^31/))
                return 'D31-HAUTE_GARONNE';
            if (testCase.menages._.depcom[currentPeriod].match(/^33/))
                return 'D33-GIRONDE';
            if (testCase.menages._.depcom[currentPeriod].match(/^34/))
                return 'D34-HERAULT';
            if (testCase.menages._.depcom[currentPeriod].match(/^35/))
                return 'D35-ILLE_ET_VILAINE';
            if (testCase.menages._.depcom[currentPeriod].match(/^42/))
                return 'D42-LOIRE';
            if (testCase.menages._.depcom[currentPeriod].match(/^44/))
                return 'D44-LOIRE_ATLANTIQUE';
            if (testCase.menages._.depcom[currentPeriod].match(/^57/))
                return 'D57-MOSELLE';
            if (testCase.menages._.depcom[currentPeriod].match(/^59/))
                return 'D59-NORD';
            if (testCase.menages._.depcom[currentPeriod].match(/^62/))
                return 'D62-PDC';
            if (testCase.menages._.depcom[currentPeriod].match(/^67/))
                return 'D67-BAS_RHIN';
            if (testCase.menages._.depcom[currentPeriod].match(/^75/))
                return 'D75-PARIS';
            if (testCase.menages._.depcom[currentPeriod].match(/^76/))
                return 'D76-SEINE_MARITIME';
            if (testCase.menages._.depcom[currentPeriod].match(/^77/))
                return 'D77-SEINE_ET_MARNE';
            if (testCase.menages._.depcom[currentPeriod].match(/^83/))
                return 'D83-VAR';
            if (testCase.menages._.depcom[currentPeriod].match(/^92/))
                return 'D92-HAUTS_DE_SEINE';
            if (testCase.menages._.depcom[currentPeriod].match(/^93/))
                return 'D93-SSD';
            if (_.includes(lyonMetropoleInseeCodes, testCase.menages._.depcom[currentPeriod]))
                return 'M69-LYON';
        }
        return undefined;
    }
    return {
        determineCustomizationId: determineCustomizationId,
    };
});
<|endoftext|>


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

(function(shared, testing) {

  var fills = 'backwards|forwards|both|none'.split('|');
  var directions = 'reverse|alternate|alternate-reverse'.split('|');

  function cloneTimingInput(timingInput) {
    if (typeof timingInput == 'number') {
      return timingInput;
    }
    var clone = {};
    for (var m in timingInput) {
      clone[m] = timingInput[m];
    }
    return clone;
  }

  function AnimationEffectTiming() {
    this._delay = 0;
    this._endDelay = 0;
    this._fill = 'none';
    this._iterationStart = 0;
    this._iterations = 1;
    this._duration = 0;
    this._playbackRate = 1;
    this._direction = 'normal';
    this._easing = 'linear';
  }

  AnimationEffectTiming.prototype = {
    _renormalize: function() {
      this._effect._timing = shared.normalizeTimingInput(
        shared.normalizeTimingInput(this._effect._timingInput));
    },
    _setMember: function(member, value) {
      this['_' + member] = value;
      if (this._effect) {
        this._effect._timingInput[member] = value;
        this._renormalize();
        this._effect.activeDuration = shared.calculateActiveDuration(this._effect._timing);
        if (this._effect._animation) {
          this._effect._animation._rebuildUnderlyingAnimation();
        }
      }
    },
    set delay(value) {
      this._setMember('delay', value);
    },
    get delay() {
      return this._delay;
    },
    set endDelay(value) {
      this._setMember('endDelay', value);
    },
    get endDelay() {
      return this._endDelay;
    },
    set fill(value) {
      this._setMember('fill', value);
    },
    get fill() {
      return this._fill;
    },
    set iterationStart(value) {
      this._setMember('iterationStart', value);
    },
    get iterationStart() {
      return this._iterationStart;
    },
    set duration(value) {
      this._setMember('duration', value);
    },
    get duration() {
      return this._duration;
    },
    get playbackRate() {
      return this._playbackRate;
    },
    set direction(value) {
      this._setMember('direction', value);
    },
    get direction() {
      return this._direction;
    },
    set easing(value) {
      this._setMember('easing', value);
    },
    get easing() {
      return this._easing;
    },
    set iterations(value) {
      this._setMember('iterations', value);
    },
    get iterations() {
      return this._iterations;
    }
  }

  function makeTiming(timingInput, forGroup, effect) {
    var timing = new AnimationEffectTiming;
    if (forGroup) {
      timing.fill = 'both';
      timing.duration = 'auto';
    }
    if (typeof timingInput == 'number' && !isNaN(timingInput)) {
      timing.duration = timingInput;
    } else if (timingInput !== undefined) {
      Object.getOwnPropertyNames(timingInput).forEach(function(property) {
        if (timingInput[property] != 'auto') {
          if (typeof timing[property] == 'number' || property == 'duration') {
            if (typeof timingInput[property] != 'number' || isNaN(timingInput[property])) {
              return;
            }
          }
          if ((property == 'fill') && (fills.indexOf(timingInput[property]) == -1)) {
            return;
          }
          if ((property == 'direction') && (directions.indexOf(timingInput[property]) == -1)) {
            return;
          }
          if (property == 'playbackRate' && timingInput[property] !== 1 && shared.isDeprecated('AnimationEffectTiming.playbackRate', '2014-11-28', 'Use Animation.playbackRate instead.')) {
            return;
          }
          timing[property] = timingInput[property];
        }
      });
    }
    return timing;
  }

  function normalizeTimingInput(timingInput, forGroup) {
    var timing = makeTiming(timingInput, forGroup);
    timing._easing = toTimingFunction(timing.easing);
    return timing;
  }

  function cubic(a, b, c, d) {
    if (a < 0 || a > 1 || c < 0 || c > 1) {
      return linear;
    }
    return function(x) {
      if (x == 0 || x == 1) {
        return x;
      }
      var start = 0, end = 1;
      while (1) {
        var mid = (start + end) / 2;
        function f(a, b, m) { return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m};
        var xEst = f(a, c, mid);
        if (Math.abs(x - xEst) < 0.001) {
          return f(b, d, mid);
        }
        if (xEst < x) {
          start = mid;
        } else {
          end = mid;
        }
      }
    }
  }

  var Start = 1;
  var Middle = 0.5;
  var End = 0;

  function step(count, pos) {
    return function(x) {
      if (x >= 1) {
        return 1;
      }
      var stepSize = 1 / count;
      x += pos * stepSize;
      return x - x % stepSize;
    }
  }

  var presets = {
    'ease': cubic(0.25, 0.1, 0.25, 1),
    'ease-in': cubic(0.42, 0, 1, 1),
    'ease-out': cubic(0, 0, 0.58, 1),
    'ease-in-out': cubic(0.42, 0, 0.58, 1),
    'step-start': step(1, Start),
    'step-middle': step(1, Middle),
    'step-end': step(1, End)
  };

  var numberString = '\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*';
  var cubicBezierRe = new RegExp('cubic-bezier\\(' + numberString + ',' + numberString + ',' + numberString + ',' + numberString + '\\)');
  var stepRe = /steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;
  var linear = function(x) { return x; };

  function toTimingFunction(easing) {
    var cubicData = cubicBezierRe.exec(easing);
    if (cubicData) {
      return cubic.apply(this, cubicData.slice(1).map(Number));
    }
    var stepData = stepRe.exec(easing);
    if (stepData) {
      return step(Number(stepData[1]), {'start': Start, 'middle': Middle, 'end': End}[stepData[2]]);
    }
    var preset = presets[easing];
    if (preset) {
      return preset;
    }
    return linear;
  };

  function calculateActiveDuration(timing) {
    return Math.abs(repeatedDuration(timing) / timing.playbackRate);
  }

  function repeatedDuration(timing) {
    return timing.duration * timing.iterations;
  }

  var PhaseNone = 0;
  var PhaseBefore = 1;
  var PhaseAfter = 2;
  var PhaseActive = 3;

  function calculatePhase(activeDuration, localTime, timing) {
    if (localTime == null) {
      return PhaseNone;
    }
    if (localTime < timing.delay) {
      return PhaseBefore;
    }
    if (localTime >= timing.delay + activeDuration) {
      return PhaseAfter;
    }
    return PhaseActive;
  }

  function calculateActiveTime(activeDuration, fillMode, localTime, phase, delay) {
    switch (phase) {
      case PhaseBefore:
        if (fillMode == 'backwards' || fillMode == 'both')
          return 0;
        return null;
      case PhaseActive:
        return localTime - delay;
      case PhaseAfter:
        if (fillMode == 'forwards' || fillMode == 'both')
          return activeDuration;
        return null;
      case PhaseNone:
        return null;
    }
  }

  function calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing) {
    return (timing.playbackRate < 0 ? activeTime - activeDuration : activeTime) * timing.playbackRate + startOffset;
  }

  function calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, timing) {
    if (scaledActiveTime === Infinity || scaledActiveTime === -Infinity || (scaledActiveTime - startOffset == repeatedDuration && timing.iterations && ((timing.iterations + timing.iterationStart) % 1 == 0))) {
      return iterationDuration;
    }

    return scaledActiveTime % iterationDuration;
  }

  function calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, timing) {
    if (scaledActiveTime === 0) {
      return 0;
    }
    if (iterationTime == iterationDuration) {
      return timing.iterationStart + timing.iterations - 1;
    }
    return Math.floor(scaledActiveTime / iterationDuration);
  }

  function calculateTransformedTime(currentIteration, iterationDuration, iterationTime, timing) {
    var currentIterationIsOdd = currentIteration % 2 >= 1;
    var currentDirectionIsForwards = timing.direction == 'normal' || timing.direction == (currentIterationIsOdd ? 'alternate-reverse' : 'alternate');
    var directedTime = currentDirectionIsForwards ? iterationTime : iterationDuration - iterationTime;
    var timeFraction = directedTime / iterationDuration;
    return iterationDuration * timing.easing(timeFraction);
  }

  function calculateTimeFraction(activeDuration, localTime, timing) {
    var phase = calculatePhase(activeDuration, localTime, timing);
    var activeTime = calculateActiveTime(activeDuration, timing.fill, localTime, phase, timing.delay);
    if (activeTime === null)
      return null;
    if (activeDuration === 0)
      return phase === PhaseBefore ? 0 : 1;
    var startOffset = timing.iterationStart * timing.duration;
    var scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing);
    var iterationTime = calculateIterationTime(timing.duration, repeatedDuration(timing), scaledActiveTime, startOffset, timing);
    var currentIteration = calculateCurrentIteration(timing.duration, iterationTime, scaledActiveTime, timing);
    return calculateTransformedTime(currentIteration, timing.duration, iterationTime, timing) / timing.duration;
  }

  shared.cloneTimingInput = cloneTimingInput;
  shared.makeTiming = makeTiming;
  shared.normalizeTimingInput = normalizeTimingInput;
  shared.calculateActiveDuration = calculateActiveDuration;
  shared.calculateTimeFraction = calculateTimeFraction;
  shared.calculatePhase = calculatePhase;
  shared.toTimingFunction = toTimingFunction;

  if (WEB_ANIMATIONS_TESTING) {
    testing.normalizeTimingInput = normalizeTimingInput;
    testing.toTimingFunction = toTimingFunction;
    testing.calculateActiveDuration = calculateActiveDuration;
    testing.calculatePhase = calculatePhase;
    testing.PhaseNone = PhaseNone;
    testing.PhaseBefore = PhaseBefore;
    testing.PhaseActive = PhaseActive;
    testing.PhaseAfter = PhaseAfter;
    testing.calculateActiveTime = calculateActiveTime;
    testing.calculateScaledActiveTime = calculateScaledActiveTime;
    testing.calculateIterationTime = calculateIterationTime;
    testing.calculateCurrentIteration = calculateCurrentIteration;
    testing.calculateTransformedTime = calculateTransformedTime;
  }

})(webAnimationsShared, webAnimationsTesting);
<commit_msg>linter<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//     You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//     See the License for the specific language governing permissions and
// limitations under the License.

(function(shared, testing) {

  var fills = 'backwards|forwards|both|none'.split('|');
  var directions = 'reverse|alternate|alternate-reverse'.split('|');

  function cloneTimingInput(timingInput) {
    if (typeof timingInput == 'number') {
      return timingInput;
    }
    var clone = {};
    for (var m in timingInput) {
      clone[m] = timingInput[m];
    }
    return clone;
  }

  function AnimationEffectTiming() {
    this._delay = 0;
    this._endDelay = 0;
    this._fill = 'none';
    this._iterationStart = 0;
    this._iterations = 1;
    this._duration = 0;
    this._playbackRate = 1;
    this._direction = 'normal';
    this._easing = 'linear';
  }

  AnimationEffectTiming.prototype = {
    _renormalize: function() {
      this._effect._timing = shared.normalizeTimingInput(
          shared.normalizeTimingInput(this._effect._timingInput));
    },
    _setMember: function(member, value) {
      this['_' + member] = value;
      if (this._effect) {
        this._effect._timingInput[member] = value;
        this._renormalize();
        this._effect.activeDuration = shared.calculateActiveDuration(this._effect._timing);
        if (this._effect._animation) {
          this._effect._animation._rebuildUnderlyingAnimation();
        }
      }
    },
    set delay(value) {
      this._setMember('delay', value);
    },
    get delay() {
      return this._delay;
    },
    set endDelay(value) {
      this._setMember('endDelay', value);
    },
    get endDelay() {
      return this._endDelay;
    },
    set fill(value) {
      this._setMember('fill', value);
    },
    get fill() {
      return this._fill;
    },
    set iterationStart(value) {
      this._setMember('iterationStart', value);
    },
    get iterationStart() {
      return this._iterationStart;
    },
    set duration(value) {
      this._setMember('duration', value);
    },
    get duration() {
      return this._duration;
    },
    get playbackRate() {
      return this._playbackRate;
    },
    set direction(value) {
      this._setMember('direction', value);
    },
    get direction() {
      return this._direction;
    },
    set easing(value) {
      this._setMember('easing', value);
    },
    get easing() {
      return this._easing;
    },
    set iterations(value) {
      this._setMember('iterations', value);
    },
    get iterations() {
      return this._iterations;
    }
  };

  function makeTiming(timingInput, forGroup, effect) {
    var timing = new AnimationEffectTiming;
    if (forGroup) {
      timing.fill = 'both';
      timing.duration = 'auto';
    }
    if (typeof timingInput == 'number' && !isNaN(timingInput)) {
      timing.duration = timingInput;
    } else if (timingInput !== undefined) {
      Object.getOwnPropertyNames(timingInput).forEach(function(property) {
        if (timingInput[property] != 'auto') {
          if (typeof timing[property] == 'number' || property == 'duration') {
            if (typeof timingInput[property] != 'number' || isNaN(timingInput[property])) {
              return;
            }
          }
          if ((property == 'fill') && (fills.indexOf(timingInput[property]) == -1)) {
            return;
          }
          if ((property == 'direction') && (directions.indexOf(timingInput[property]) == -1)) {
            return;
          }
          if (property == 'playbackRate' && timingInput[property] !== 1 && shared.isDeprecated('AnimationEffectTiming.playbackRate', '2014-11-28', 'Use Animation.playbackRate instead.')) {
            return;
          }
          timing[property] = timingInput[property];
        }
      });
    }
    return timing;
  }

  function normalizeTimingInput(timingInput, forGroup) {
    var timing = makeTiming(timingInput, forGroup);
    timing._easing = toTimingFunction(timing.easing);
    return timing;
  }

  function cubic(a, b, c, d) {
    if (a < 0 || a > 1 || c < 0 || c > 1) {
      return linear;
    }
    return function(x) {
      if (x == 0 || x == 1) {
        return x;
      }
      var start = 0, end = 1;
      while (1) {
        var mid = (start + end) / 2;
        function f(a, b, m) { return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m};
        var xEst = f(a, c, mid);
        if (Math.abs(x - xEst) < 0.001) {
          return f(b, d, mid);
        }
        if (xEst < x) {
          start = mid;
        } else {
          end = mid;
        }
      }
    }
  }

  var Start = 1;
  var Middle = 0.5;
  var End = 0;

  function step(count, pos) {
    return function(x) {
      if (x >= 1) {
        return 1;
      }
      var stepSize = 1 / count;
      x += pos * stepSize;
      return x - x % stepSize;
    }
  }

  var presets = {
    'ease': cubic(0.25, 0.1, 0.25, 1),
    'ease-in': cubic(0.42, 0, 1, 1),
    'ease-out': cubic(0, 0, 0.58, 1),
    'ease-in-out': cubic(0.42, 0, 0.58, 1),
    'step-start': step(1, Start),
    'step-middle': step(1, Middle),
    'step-end': step(1, End)
  };

  var numberString = '\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*';
  var cubicBezierRe = new RegExp('cubic-bezier\\(' + numberString + ',' + numberString + ',' + numberString + ',' + numberString + '\\)');
  var stepRe = /steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;
  var linear = function(x) { return x; };

  function toTimingFunction(easing) {
    var cubicData = cubicBezierRe.exec(easing);
    if (cubicData) {
      return cubic.apply(this, cubicData.slice(1).map(Number));
    }
    var stepData = stepRe.exec(easing);
    if (stepData) {
      return step(Number(stepData[1]), {'start': Start, 'middle': Middle, 'end': End}[stepData[2]]);
    }
    var preset = presets[easing];
    if (preset) {
      return preset;
    }
    return linear;
  };

  function calculateActiveDuration(timing) {
    return Math.abs(repeatedDuration(timing) / timing.playbackRate);
  }

  function repeatedDuration(timing) {
    return timing.duration * timing.iterations;
  }

  var PhaseNone = 0;
  var PhaseBefore = 1;
  var PhaseAfter = 2;
  var PhaseActive = 3;

  function calculatePhase(activeDuration, localTime, timing) {
    if (localTime == null) {
      return PhaseNone;
    }
    if (localTime < timing.delay) {
      return PhaseBefore;
    }
    if (localTime >= timing.delay + activeDuration) {
      return PhaseAfter;
    }
    return PhaseActive;
  }

  function calculateActiveTime(activeDuration, fillMode, localTime, phase, delay) {
    switch (phase) {
      case PhaseBefore:
        if (fillMode == 'backwards' || fillMode == 'both')
          return 0;
        return null;
      case PhaseActive:
        return localTime - delay;
      case PhaseAfter:
        if (fillMode == 'forwards' || fillMode == 'both')
          return activeDuration;
        return null;
      case PhaseNone:
        return null;
    }
  }

  function calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing) {
    return (timing.playbackRate < 0 ? activeTime - activeDuration : activeTime) * timing.playbackRate + startOffset;
  }

  function calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, timing) {
    if (scaledActiveTime === Infinity || scaledActiveTime === -Infinity || (scaledActiveTime - startOffset == repeatedDuration && timing.iterations && ((timing.iterations + timing.iterationStart) % 1 == 0))) {
      return iterationDuration;
    }

    return scaledActiveTime % iterationDuration;
  }

  function calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, timing) {
    if (scaledActiveTime === 0) {
      return 0;
    }
    if (iterationTime == iterationDuration) {
      return timing.iterationStart + timing.iterations - 1;
    }
    return Math.floor(scaledActiveTime / iterationDuration);
  }

  function calculateTransformedTime(currentIteration, iterationDuration, iterationTime, timing) {
    var currentIterationIsOdd = currentIteration % 2 >= 1;
    var currentDirectionIsForwards = timing.direction == 'normal' || timing.direction == (currentIterationIsOdd ? 'alternate-reverse' : 'alternate');
    var directedTime = currentDirectionIsForwards ? iterationTime : iterationDuration - iterationTime;
    var timeFraction = directedTime / iterationDuration;
    return iterationDuration * timing.easing(timeFraction);
  }

  function calculateTimeFraction(activeDuration, localTime, timing) {
    var phase = calculatePhase(activeDuration, localTime, timing);
    var activeTime = calculateActiveTime(activeDuration, timing.fill, localTime, phase, timing.delay);
    if (activeTime === null)
      return null;
    if (activeDuration === 0)
      return phase === PhaseBefore ? 0 : 1;
    var startOffset = timing.iterationStart * timing.duration;
    var scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing);
    var iterationTime = calculateIterationTime(timing.duration, repeatedDuration(timing), scaledActiveTime, startOffset, timing);
    var currentIteration = calculateCurrentIteration(timing.duration, iterationTime, scaledActiveTime, timing);
    return calculateTransformedTime(currentIteration, timing.duration, iterationTime, timing) / timing.duration;
  }

  shared.cloneTimingInput = cloneTimingInput;
  shared.makeTiming = makeTiming;
  shared.normalizeTimingInput = normalizeTimingInput;
  shared.calculateActiveDuration = calculateActiveDuration;
  shared.calculateTimeFraction = calculateTimeFraction;
  shared.calculatePhase = calculatePhase;
  shared.toTimingFunction = toTimingFunction;

  if (WEB_ANIMATIONS_TESTING) {
    testing.normalizeTimingInput = normalizeTimingInput;
    testing.toTimingFunction = toTimingFunction;
    testing.calculateActiveDuration = calculateActiveDuration;
    testing.calculatePhase = calculatePhase;
    testing.PhaseNone = PhaseNone;
    testing.PhaseBefore = PhaseBefore;
    testing.PhaseActive = PhaseActive;
    testing.PhaseAfter = PhaseAfter;
    testing.calculateActiveTime = calculateActiveTime;
    testing.calculateScaledActiveTime = calculateScaledActiveTime;
    testing.calculateIterationTime = calculateIterationTime;
    testing.calculateCurrentIteration = calculateCurrentIteration;
    testing.calculateTransformedTime = calculateTransformedTime;
  }

})(webAnimationsShared, webAnimationsTesting);
<|endoftext|>


<commit_before>/* global assert, process, setup, suite, test, THREE */
var entityFactory = require('../helpers').entityFactory;

suite('vive-controls', function () {
  var component;
  var controlsSystem;
  var el;

  setup(function (done) {
    el = entityFactory();
    el.addEventListener('componentinitialized', function (evt) {
      if (evt.detail.name !== 'vive-controls') { return; }
      component = el.components['vive-controls'];
      component.controllersWhenPresent = [
        {id: 'OpenVR Gamepad', index: 0, hand: 'right', pose: {}}
      ];
      controlsSystem = el.sceneEl.systems['tracked-controls'];
      done();
    });
    el.setAttribute('vive-controls', 'hand: right; model: false');  // To ensure index = 0.
  });

  suite('checkIfControllerPresent', function () {
    test('remember not present if no controllers on first call', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('does not remove event listeners if no controllers again', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('attaches events if controller is newly present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.ok(injectTrackedControlsSpy.called);
      assert.ok(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('does not inject/attach events again if controller is already present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('remove event listeners if controller disappears', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.ok(removeEventListenersSpy.called);
      assert.notOk(component.controllerPresent);
    });
  });

  suite('axismove', function () {
    test('emits trackpadmoved on axismove', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;

      component.checkIfControllerPresent();

      // Install event handler listening for trackpad.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.equal(evt.detail.x, 0.1);
        assert.equal(evt.detail.y, 0.2);
        assert.ok(evt.detail);
        done();
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [true, false]});
    });

    test('does not emit trackpadmoved on axismove with no changes', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();

      // Install event handler listening for trackpadmoved.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.notOk(evt.detail);
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]});

      setTimeout(function () { done(); });
    });
  });

  suite('buttonchanged', function () {
    test('emits triggerchanged on buttonchanged', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();

      // Install event handler listening for triggerchanged.
      el.addEventListener('triggerchanged', function (evt) {
        assert.ok(evt.detail);
        done();
      });

      // Emit buttonchanged.
      el.emit('buttonchanged', {id: 1, state: {value: 0.5, pressed: true, touched: true}});
    });

    test('emits triggerdown on buttonchanged', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();
      el.addEventListener('triggerdown', function (evt) {
        done();
      });
      el.emit('buttondown', {id: 1});
    });

    test('emits triggerup on buttonchanged', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();
      el.addEventListener('triggerup', function (evt) {
        done();
      });
      el.emit('buttonup', {id: 1});
    });
  });

  suite('model', function () {
    test.skip('loads', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        assert.ok(component.buttonMeshes);
        assert.ok(component.buttonMeshes.trigger);
        assert.ok(el.getObject3D('mesh'));
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite.skip('button colors', function () {
    test('has trigger at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trigger.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has trackpad at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trackpad.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has grips at default colors', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.grip.left.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        color = component.buttonMeshes.grip.right.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger back to default color when up', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        component.buttonMeshes.trigger.material.color.set('#22d1ee');
        el.emit('buttonup', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trackpad to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trigger touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trackpad touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite('event listener', function () {
    test('toggles controllerEventsActive', function () {
      component.controllerEventsActive = false;
      component.addEventListeners();
      assert.ok(component.controllerEventsActive);
      component.removeEventListeners();
      assert.notOk(component.controllerEventsActive);
    });
  });
});
<commit_msg>Generator for consistently testing all button remappings<commit_after>/* global assert, process, setup, suite, test, THREE */
var entityFactory = require('../helpers').entityFactory;

suite('vive-controls', function () {
  var component;
  var controlsSystem;
  var el;

  setup(function (done) {
    el = entityFactory();
    el.addEventListener('componentinitialized', function (evt) {
      if (evt.detail.name !== 'vive-controls') { return; }
      component = el.components['vive-controls'];
      component.controllersWhenPresent = [
        {id: 'OpenVR Gamepad', index: 0, hand: 'right', pose: {}}
      ];
      controlsSystem = el.sceneEl.systems['tracked-controls'];
      done();
    });
    el.setAttribute('vive-controls', 'hand: right; model: false');  // To ensure index = 0.
  });

  suite('checkIfControllerPresent', function () {
    test('remember not present if no controllers on first call', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('does not remove event listeners if no controllers again', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.strictEqual(component.controllerPresent, false);  // Not undefined.
    });

    test('attaches events if controller is newly present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock not looked before.
      component.controllerPresent = false;

      component.checkIfControllerPresent();

      assert.ok(injectTrackedControlsSpy.called);
      assert.ok(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('does not inject/attach events again if controller is already present', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = component.controllersWhenPresent;

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.notOk(removeEventListenersSpy.called);
      assert.ok(component.controllerPresent);
    });

    test('remove event listeners if controller disappears', function () {
      var addEventListenersSpy = this.sinon.spy(component, 'addEventListeners');
      var injectTrackedControlsSpy = this.sinon.spy(component, 'injectTrackedControls');
      var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners');
      controlsSystem.controllers = [];

      // Mock looked before.
      component.controllerEventsActive = true;
      component.controllerPresent = true;

      component.checkIfControllerPresent();

      assert.notOk(injectTrackedControlsSpy.called);
      assert.notOk(addEventListenersSpy.called);
      assert.ok(removeEventListenersSpy.called);
      assert.notOk(component.controllerPresent);
    });
  });

  suite('axismove', function () {
    test('emits trackpadmoved on axismove', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;

      component.checkIfControllerPresent();

      // Install event handler listening for trackpad.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.equal(evt.detail.x, 0.1);
        assert.equal(evt.detail.y, 0.2);
        assert.ok(evt.detail);
        done();
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [true, false]});
    });

    test('does not emit trackpadmoved on axismove with no changes', function (done) {
      controlsSystem.controllers = component.controllersWhenPresent;
      component.checkIfControllerPresent();

      // Install event handler listening for trackpadmoved.
      el.addEventListener('trackpadmoved', function (evt) {
        assert.notOk(evt.detail);
      });

      // Emit axismove.
      el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]});

      setTimeout(function () { done(); });
    });
  });

  suite('buttonchanged', function () {
    // Generate 3 tests for each button. Verify that it fires up/down/changed for all remapped buttons.
    [ { button: 'trackpad', id: 0 },
      { button: 'trigger', id: 1 },
      { button: 'grip', id: 2 },
      { button: 'menu', id: 3 },
      { button: 'system', id: 4 }
    ].forEach(function (buttonDescription) {
      test('emits ' + buttonDescription.button + 'changed on buttonchanged', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'changed', function (evt) {
          assert.ok(evt.detail);
          done();
        });
        el.emit('buttonchanged', {id: buttonDescription.id, state: {value: 0.5, pressed: true, touched: true}});
      });

      test('emits ' + buttonDescription.button + 'down on buttondown', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'down', function (evt) {
          done();
        });
        el.emit('buttondown', {id: buttonDescription.id});
      });

      test('emits ' + buttonDescription.button + 'up on buttonup', function (done) {
        controlsSystem.controllers = component.controllersWhenPresent;
        component.checkIfControllerPresent();
        el.addEventListener(buttonDescription.button + 'up', function (evt) {
          done();
        });
        el.emit('buttonup', {id: buttonDescription.id});
      });
    });
  });

  suite('model', function () {
    test.skip('loads', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        assert.ok(component.buttonMeshes);
        assert.ok(component.buttonMeshes.trigger);
        assert.ok(el.getObject3D('mesh'));
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite.skip('button colors', function () {
    test('has trigger at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trigger.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has trackpad at default color', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.trackpad.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('has grips at default colors', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        var color = component.buttonMeshes.grip.left.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        color = component.buttonMeshes.grip.right.material.color;
        assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
        done();
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trigger back to default color when up', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        component.buttonMeshes.trigger.material.color.set('#22d1ee');
        el.emit('buttonup', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('sets trackpad to highlight color when down', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('buttondown', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), '22d1ee');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trigger touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 1, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trigger.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });

    test('does not change color for trackpad touch', function (done) {
      component.addEventListeners();
      el.addEventListener('model-loaded', function (evt) {
        el.emit('touchstart', {id: 0, state: {}});
        setTimeout(() => {
          var color = component.buttonMeshes.trackpad.material.color;
          assert.equal(new THREE.Color(color).getHexString(), 'fafafa');
          done();
        });
      });
      component.data.model = true;
      component.injectTrackedControls();
    });
  });

  suite('event listener', function () {
    test('toggles controllerEventsActive', function () {
      component.controllerEventsActive = false;
      component.addEventListeners();
      assert.ok(component.controllerEventsActive);
      component.removeEventListeners();
      assert.notOk(component.controllerEventsActive);
    });
  });
});
<|endoftext|>


<commit_before>// Global variables for isolated world
var iconActive = false;

function toggle(){
  // Show "on" icon when showing the help
  if(iconActive == false){
    activate();
  } else{
    deactivate();
  }
}

function deactivate(){
  iconActive = false;
  chrome.browserAction.setIcon({"path":"icon-" + "off" + ".png"});
  chrome.tabs.executeScript(null, {file: "assets/jquery-2.1.1.min.js"}, function() {
    chrome.tabs.executeScript(null, {file: "deactivate.js"});
    chrome.browserAction.setIcon(
      {
        "path": {
          19: "images/icon-19-" + "off" + ".png",
          38: "images/icon-38-" + "off" + ".png"
        }
      }
    );
  });
}

function activate(){
  iconActive = true;
  chrome.browserAction.setIcon(
    {
      "path": {
        19: "images/icon-19-" + "on" + ".png",
        38: "images/icon-38-" + "on" + ".png"
      }
    }
  );
  chrome.tabs.executeScript(null, {file: "assets/jquery-2.1.1.min.js"}, function() {
    chrome.tabs.executeScript(null, {file: "activate.js"});
  });
}

//////////////////////////////////////
// Tab event bindings
//////////////////////////////////////

chrome.tabs.onUpdated.addListener(function(){
  deactivate();
});

chrome.tabs.onRemoved.addListener(function(){
  deactivate();
});

chrome.browserAction.onClicked.addListener(function(tab) {
  toggle();
});
<commit_msg>Remove extraneous icon call<commit_after>// Global variables for isolated world
var iconActive = false;

function toggle(){
  // Show "on" icon when showing the help
  if(iconActive == false){
    activate();
  } else{
    deactivate();
  }
}

function deactivate(){
  iconActive = false;
  chrome.tabs.executeScript(null, {file: "assets/jquery-2.1.1.min.js"}, function() {
    chrome.tabs.executeScript(null, {file: "deactivate.js"});
    chrome.browserAction.setIcon(
      {
        "path": {
          19: "images/icon-19-" + "off" + ".png",
          38: "images/icon-38-" + "off" + ".png"
        }
      }
    );
  });
}

function activate(){
  iconActive = true;
  chrome.browserAction.setIcon(
    {
      "path": {
        19: "images/icon-19-" + "on" + ".png",
        38: "images/icon-38-" + "on" + ".png"
      }
    }
  );
  chrome.tabs.executeScript(null, {file: "assets/jquery-2.1.1.min.js"}, function() {
    chrome.tabs.executeScript(null, {file: "activate.js"});
  });
}

//////////////////////////////////////
// Tab event bindings
//////////////////////////////////////

chrome.tabs.onUpdated.addListener(function(){
  deactivate();
});

chrome.tabs.onRemoved.addListener(function(){
  deactivate();
});

chrome.browserAction.onClicked.addListener(function(tab) {
  toggle();
});
<|endoftext|>


<commit_before>require('babel-runtime/core-js/promise').default = require('bluebird')
import 'isomorphic-fetch'

import React from 'react'
import ReactDOM from 'react-dom'
import Router, {Route, IndexRoute, Link} from 'react-router'

import App from './components/app'
import MainMenu from './components/main-menu'
import CreateNewNavigation from './components/create-new-navigation'
import SavedNavigationScreen from './components/saved-navigation-screen'
import Help from './components/help'

const routes = (
	<Route path='/' component={App}>
		<IndexRoute component={MainMenu} />
			<Route path='createnewnavigation' component={CreateNewNavigation} />
			<Route path='help' component={Help} />
			<Route path='savednavigationscreen' component={SavedNavigationScreen} />
	</Route>
)

// run it
console.log('3. 2.. 1... Blast off! 🚀')

ReactDOM.render(<Router>{routes}</Router>, document.getElementById('app'))<commit_msg>Deleted the Help screen route. Added the routes for the create new navigation help screen and the saved navigation help screen.<commit_after>require('babel-runtime/core-js/promise').default = require('bluebird')
import 'isomorphic-fetch'

import React from 'react'
import ReactDOM from 'react-dom'
import Router, {Route, IndexRoute, Link} from 'react-router'

import App from './components/app'
import MainMenu from './components/main-menu'
import CreateNewNavigation from './components/create-new-navigation'
import SavedNavigationScreen from './components/saved-navigation-screen'
import CreateNewNavigationHelp from './components/create-new-navigation-help'
import SavedNavigationHelp from './components/saved-navigation-help'

const routes = (
	<Route path='/' component={App}>
		<IndexRoute component={MainMenu} />
			<Route path='createnewnavigation' component={CreateNewNavigation} />
				<Route path='createnewnavigationhelp' component={CreateNewNavigationHelp} />
			<Route path='savednavigationscreen' component={SavedNavigationScreen} />
				<Route path='savednavigationhelp' component={SavedNavigationHelp} />
	</Route>
)

// run it
console.log('3. 2.. 1... Blast off! 🚀')

ReactDOM.render(<Router>{routes}</Router>, document.getElementById('app'))<|endoftext|>