<commit_before>import React,{Component} from 'react';
import DatePicker from 'react-datepicker';
import {Panel,Button} from 'react-bootstrap';
import {hashHistory,Link} from 'react-router';
import {connect} from 'react-redux';
import {dispatch} from 'redux';
import {
  actionInsertRuleData,
  actionUpdateRuleData
} from '../../actions/MaintainReportRuleAction';
import RegOpzReportGrid from './../RegOpzDataGrid/RegOpzReportGrid';
require('./MaintainReportRules.css');

class AddReportAggRules extends Component {
    constructor(props) {
        super(props);
        this.state = {
          form: {
            id: null,
            report_id: this.props.report_id,
            sheet_id: this.props.sheet_id,
            cell_id: this.props.cell_id,
            comp_agg_ref: null,
            reporting_scale: null,
            rounding_option: null,
            valid_from: null,
            valid_to: null,
            last_updated_by: null
          },
          audit_form:{
            comment:null
          },
          openDataGridCollapsible: false
        }
        // this.aggRulesList = new RegExp('[A-Z0-9]+') Options are included
        //this.aggRulesPattern = /(\w+([\+\-\*\/]\w+)?)|(\(\w+\))/g;
        this.aggRulesPattern = /[\+\-\*\/\(\)\[\]\{\}\^]/g;

        this.ruleIndex = typeof this.props.index === 'number' ? this.props.index : -1;
        this.dml_allowed = this.props.dml_allowed === 'Y' ? true : false;
        this.writeOnly = this.props.writeOnly;
    }

    componentWillMount() {
        if (this.ruleIndex !== -1) {
            Object.assign(this.state.form, this.props.cell_rules.comp_agg_rules[this.ruleIndex]);
        }
    }

    componentWillReceiveProps(nextProps) {
        this.ruleIndex = nextProps.ruleIndex
        if (this.ruleIndex !== -1) {
            Object.assign(this.state.form, nextProps.cell_rules.comp_agg_rules[this.ruleIndex]);
        }
        this.dml_allowed = nextProps.dml_allowed;
        this.writeOnly = nextProps.writeOnly;
    }

  render() {
    this.viewOnly = ! (this.writeOnly && this.dml_allowed);
    return(

Maintain report rule Add a new aggregation rule

           <form className="form-horizontal form-label-left" onSubmit={this.handleSubmit.bind(this)}>

              Report ID *

                <input
                  value={this.state.form.report_id}
                  type="text"
                  className="form-control col-md-7 col-xs-12"
                  readOnly="true"
                />

                Sheet ID *

                  <input
                    value={this.state.form.sheet_id}
                    type="text"
                    className="form-control col-md-7 col-xs-12"
                    readOnly="true"
                  />

                  Cell ID *

                    <input
                      value={this.state.form.cell_id}
                      type="text"
                      className="form-control col-md-7 col-xs-12"
                      readOnly="true"
                    />

                    Composite Aggregation Reference *

                      <input
                        value={this.state.form.comp_agg_ref}
                        type="text"
                        className="form-control col-md-7 col-xs-12"
                        readOnly={this.viewOnly}
                        onChange={(event) => {
                          let newState = {...this.state};
                          //if(this.checkRuleValidity(event) == "valid") {
                            newState.form.comp_agg_ref = event.target.value;
                            this.setState(newState);
                          // }
                          // else {
                          //   alert("Invalid formula, please check");
                          //   this.setState(newState);
                          // }
                         }
                        }
                      />

                      <Button
                        type='button'
                        onClick={() => {
                          let currentState = this.state.openDataGridCollapsible;
                          this.setState({openDataGridCollapsible: !currentState});
                        }}
                      >
                        Show Data Grid
                      </Button>

                    <Panel collapsible expanded={this.state.openDataGridCollapsible}>
                        <RegOpzReportGrid
                          gridData={this.props.gridData}
                          handleSelectCell={(data) => {
                            // TODO: Display To Row Input Field
                            console.log(data);
                          }}
                        />
                    </Panel>

                    Reporting Scale*

                      <input
                        value={this.state.form.reporting_scale}
                        readOnly={this.viewOnly}
                        type="number"
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                            let newState = {...this.state};
                            newState.form.reporting_scale = event.target.value;
                            this.setState(newState);
                          }
                        }
                      />

                    Rounding Option*

                      <select
                        defaultValue = {this.state.form.rounding_option}
                        className="form-control"
                        readOnly={this.viewOnly}
                        onChange={
                          (event) => {
                            let newState = {...this.state};
                            newState.form.rounding_option = event.target.value;
                            this.setState(newState);
                          }
                        }
                      >
                        <option>Choose option</option>
                        <option value="NONE">NONE</option>
                        <option value="CEIL">CEIL</option>
                        <option value="FLOOR">FLOOR</option>
                        <option value="TRUNC">TRUNC</option>
                        <option value="DECIMAL0">DECIMAL0</option>
                        <option value="DECIMAL1">DECIMAL1</option>
                        <option value="DECIMAL2">DECIMAL2</option>
                        <option value="DECIMAL3">DECIMAL3</option>
                        <option value="DECIMAL4">DECIMAL4</option>
                        <option value="DECIMAL5">DECIMAL5</option>
                        <option value="DECIMAL6">DECIMAL6</option>
                        <option value="DECIMAL7">DECIMAL7</option>
                        <option value="DECIMAL8">DECIMAL8</option>
                        <option value="DECIMAL9">DECIMAL9</option>
                        <option value="DECIMAL10">DECIMAL10</option>
                      </select>

                    Valid from

                      <DatePicker
                          dateFormat="YYYYMMDD"
                          selected={this.state.form.valid_from}
                          onChange={console.log("this.handleValidFromDateChange.bind(this)")}
                          placeholderText="Rule Valid From"
                          readOnly="readonly"
                          className="view_data_date_picker_input form-control"
                      />

                    Valid till

                      <DatePicker
                          dateFormat="YYYYMMDD"
                          selected={this.state.form.valid_to}
                          onChange={console.log("this.handleValidTillDateChange.bind(this)")}
                          placeholderText="Rule Valid Till"
                          readOnly="readonly"
                          className="view_data_date_picker_input form-control"
                      />

                    Comment*

                      <textarea
                        value={this.state.audit_form.comment}
                        minLength="20"
                        maxLength="1000"
                        required="true"
                        type="text"
                        readOnly={this.viewOnly}
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                          let newState = {...this.state};
                          newState.audit_form.comment = event.target.value;
                          this.setState(newState);
                          }
                        }
                      />

                    Last Updated By*

                      <input
                        value={this.state.form.last_updated_by}
                        type="text"
                        readOnly={this.viewOnly}
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                          let newState = {...this.state};
                          newState.form.last_updated_by = event.target.value;
                          this.setState(newState);
                          }
                        }
                      />

                      <button type="button" className="btn btn-primary" onClick={this.props.handleClose}>
                        Cancel</button>
                      {
                        ((viewOnly)=>{
                          if(! viewOnly) {
                            return(
                                <button type="submit" className="btn btn-success" >Submit</button>
                            );
                          }
                        })(this.viewOnly)
                      }

          </form>

    );
  }

  handleSubmit(event) {
    event.preventDefault();
    console.log(this.state.form);
    let data = {
      table_name: "report_comp_agg_def",
      update_info: this.state.form
    };
    data['change_type'] = this.ruleIndex === -1 ? "INSERT" : "UPDATE";

    let audit_info={
      table_name:data["table_name"],
      change_type:data["change_type"],
      change_reference:`Aggregation Rule of : ${this.state.form.report_id}->${this.state.form.sheet_id}->${this.state.form.cell_id}`,
      maker: this.props.login_details.user,
    };

    Object.assign(audit_info,this.state.audit_form);

    data['audit_info']=audit_info;

    if (data['change_type'] == "INSERT") {
      this.props.insertRuleData(data);
    } else {
      this.props.updateRuleData(this.state.form.id,data);
    }

    this.props.handleClose();
  }

  checkRuleValidity(event){
    var nstr = ''
    var str = event.target.value;
    var str1 = event.target.value;
    var nnstr=''
    var aggRulesPattern = /[\+\-\*\/\(\)\[\]\{\}\^]/g;
    //do {
      //nstr = str.replace(this.aggRulesPattern, '0');
      nstr = str.replace(aggRulesPattern, ',');
      nstr = nstr.split(",");
      nstr.map(function(item,index){
          this.state.form.cell_business_rules += `${item.text},`;
        }.bind(this));
      console.log('inside while...',nstr,str);
    //} while (nstr !== str && ((str = nstr) || 1));
    nnstr = str1.replace(/(AB\b|A\b|ABC\b)/g,'2');
    console.log('outside while...',nnstr,nstr,str);
    if (str === '0') {
      console.log("valid");
      return "valid";
    } else {
      console.log("invalid");
      return "invalid";
    }
  }

}

function mapStateToProps(state) {
  return{
    cell_rules: state.report_store.cell_rules,
    login_details: state.login_store,
  };
}

const mapDispatchToProps = (dispatch) => {
  return {
    insertRuleData:(data) => {
      dispatch(actionInsertRuleData(data));
    },
    updateRuleData:(id, data) => {
      dispatch(actionUpdateRuleData(id, data));
    }
  };
}

const VisibleAddReportAggRules = connect(
  mapStateToProps,
  mapDispatchToProps
)(AddReportAggRules);

export default VisibleAddReportAggRules;
<commit_msg>Updated Dsiplay Data<commit_after>import React,{Component} from 'react';
import DatePicker from 'react-datepicker';
import {Panel,Button} from 'react-bootstrap';
import {hashHistory,Link} from 'react-router';
import {connect} from 'react-redux';
import {dispatch} from 'redux';
import {
  actionInsertRuleData,
  actionUpdateRuleData
} from '../../actions/MaintainReportRuleAction';
import RegOpzReportGrid from './../RegOpzDataGrid/RegOpzReportGrid';
require('./MaintainReportRules.css');

class AddReportAggRules extends Component {
    constructor(props) {
        super(props);
        this.state = {
          form: {
            id: null,
            report_id: this.props.report_id,
            sheet_id: this.props.sheet_id,
            cell_id: this.props.cell_id,
            comp_agg_ref: null,
            reporting_scale: null,
            rounding_option: null,
            valid_from: null,
            valid_to: null,
            last_updated_by: null
          },
          audit_form:{
            comment:null
          },
          openDataGridCollapsible: false
        }
        // this.aggRulesList = new RegExp('[A-Z0-9]+') Options are included
        //this.aggRulesPattern = /(\w+([\+\-\*\/]\w+)?)|(\(\w+\))/g;
        this.aggRulesPattern = /[\+\-\*\/\(\)\[\]\{\}\^]/g;

        this.ruleIndex = typeof this.props.index === 'number' ? this.props.index : -1;
        this.dml_allowed = this.props.dml_allowed === 'Y' ? true : false;
        this.writeOnly = this.props.writeOnly;
    }

    componentWillMount() {
        if (this.ruleIndex !== -1) {
            Object.assign(this.state.form, this.props.cell_rules.comp_agg_rules[this.ruleIndex]);
        }
    }

    componentWillReceiveProps(nextProps) {
        this.ruleIndex = nextProps.ruleIndex
        if (this.ruleIndex !== -1) {
            Object.assign(this.state.form, nextProps.cell_rules.comp_agg_rules[this.ruleIndex]);
        }
        this.dml_allowed = nextProps.dml_allowed;
        this.writeOnly = nextProps.writeOnly;
    }

  render() {
    this.viewOnly = ! (this.writeOnly && this.dml_allowed);
    return(

Maintain report rule Add a new aggregation rule

           <form className="form-horizontal form-label-left" onSubmit={this.handleSubmit.bind(this)}>

              Report ID *

                <input
                  value={this.state.form.report_id}
                  type="text"
                  className="form-control col-md-7 col-xs-12"
                  readOnly="true"
                />

                Sheet ID *

                  <input
                    value={this.state.form.sheet_id}
                    type="text"
                    className="form-control col-md-7 col-xs-12"
                    readOnly="true"
                  />

                  Cell ID *

                    <input
                      value={this.state.form.cell_id}
                      type="text"
                      className="form-control col-md-7 col-xs-12"
                      readOnly="true"
                    />

                    Composite Aggregation Reference *

                      <input
                        value={this.state.form.comp_agg_ref}
                        type="text"
                        className="form-control col-md-7 col-xs-12"
                        readOnly={this.viewOnly}
                        onChange={(event) => {
                          let newState = {...this.state};
                          //if(this.checkRuleValidity(event) == "valid") {
                            newState.form.comp_agg_ref = event.target.value;
                            this.setState(newState);
                          // }
                          // else {
                          //   alert("Invalid formula, please check");
                          //   this.setState(newState);
                          // }
                         }
                        }
                      />

                      <Button
                        type='button'
                        disabled={this.viewOnly}
                        onClick={() => {
                          let currentState = this.state.openDataGridCollapsible;
                          this.setState({openDataGridCollapsible: !currentState});
                        }}
                      >
                        Show Data Grid
                      </Button>

                    <Panel collapsible expanded={this.state.openDataGridCollapsible}>
                        <RegOpzReportGrid
                          gridData={this.props.gridData}
                          handleSelectCell={(data) => {
                            // TODO: Display To Row Input Field
                            console.log(data);
                          }}
                        />
                    </Panel>

                    Reporting Scale*

                      <input
                        value={this.state.form.reporting_scale}
                        readOnly={this.viewOnly}
                        type="number"
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                            let newState = {...this.state};
                            newState.form.reporting_scale = event.target.value;
                            this.setState(newState);
                          }
                        }
                      />

                    Rounding Option*

                      <select
                        defaultValue = {this.state.form.rounding_option}
                        className="form-control"
                        readOnly={this.viewOnly}
                        onChange={
                          (event) => {
                            let newState = {...this.state};
                            newState.form.rounding_option = event.target.value;
                            this.setState(newState);
                          }
                        }
                      >
                        <option>Choose option</option>
                        <option value="NONE">NONE</option>
                        <option value="CEIL">CEIL</option>
                        <option value="FLOOR">FLOOR</option>
                        <option value="TRUNC">TRUNC</option>
                        <option value="DECIMAL0">DECIMAL0</option>
                        <option value="DECIMAL1">DECIMAL1</option>
                        <option value="DECIMAL2">DECIMAL2</option>
                        <option value="DECIMAL3">DECIMAL3</option>
                        <option value="DECIMAL4">DECIMAL4</option>
                        <option value="DECIMAL5">DECIMAL5</option>
                        <option value="DECIMAL6">DECIMAL6</option>
                        <option value="DECIMAL7">DECIMAL7</option>
                        <option value="DECIMAL8">DECIMAL8</option>
                        <option value="DECIMAL9">DECIMAL9</option>
                        <option value="DECIMAL10">DECIMAL10</option>
                      </select>

                    Valid from

                      <DatePicker
                          dateFormat="YYYYMMDD"
                          selected={this.state.form.valid_from}
                          onChange={console.log("this.handleValidFromDateChange.bind(this)")}
                          placeholderText="Rule Valid From"
                          readOnly="readonly"
                          className="view_data_date_picker_input form-control"
                      />

                    Valid till

                      <DatePicker
                          dateFormat="YYYYMMDD"
                          selected={this.state.form.valid_to}
                          onChange={console.log("this.handleValidTillDateChange.bind(this)")}
                          placeholderText="Rule Valid Till"
                          readOnly="readonly"
                          className="view_data_date_picker_input form-control"
                      />

                    Comment*

                      <textarea
                        value={this.state.audit_form.comment}
                        minLength="20"
                        maxLength="1000"
                        required="true"
                        type="text"
                        readOnly={this.viewOnly}
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                          let newState = {...this.state};
                          newState.audit_form.comment = event.target.value;
                          this.setState(newState);
                          }
                        }
                      />

                    Last Updated By*

                      <input
                        value={this.state.form.last_updated_by}
                        type="text"
                        readOnly={this.viewOnly}
                        className="form-control col-md-7 col-xs-12"
                        onChange={(event) => {
                          let newState = {...this.state};
                          newState.form.last_updated_by = event.target.value;
                          this.setState(newState);
                          }
                        }
                      />

                      <button type="button" className="btn btn-primary" onClick={this.props.handleClose}>
                        Cancel</button>
                      {
                        ((viewOnly)=>{
                          if(! viewOnly) {
                            return(
                                <button type="submit" className="btn btn-success" >Submit</button>
                            );
                          }
                        })(this.viewOnly)
                      }

          </form>

    );
  }

  handleSubmit(event) {
    event.preventDefault();
    console.log(this.state.form);
    let data = {
      table_name: "report_comp_agg_def",
      update_info: this.state.form
    };
    data['change_type'] = this.ruleIndex === -1 ? "INSERT" : "UPDATE";

    let audit_info={
      table_name:data["table_name"],
      change_type:data["change_type"],
      change_reference:`Aggregation Rule of : ${this.state.form.report_id}->${this.state.form.sheet_id}->${this.state.form.cell_id}`,
      maker: this.props.login_details.user,
    };

    Object.assign(audit_info,this.state.audit_form);

    data['audit_info']=audit_info;

    if (data['change_type'] == "INSERT") {
      this.props.insertRuleData(data);
    } else {
      this.props.updateRuleData(this.state.form.id,data);
    }

    this.props.handleClose();
  }

  checkRuleValidity(event){
    var nstr = ''
    var str = event.target.value;
    var str1 = event.target.value;
    var nnstr=''
    var aggRulesPattern = /[\+\-\*\/\(\)\[\]\{\}\^]/g;
    //do {
      //nstr = str.replace(this.aggRulesPattern, '0');
      nstr = str.replace(aggRulesPattern, ',');
      nstr = nstr.split(",");
      nstr.map(function(item,index){
          this.state.form.cell_business_rules += `${item.text},`;
        }.bind(this));
      console.log('inside while...',nstr,str);
    //} while (nstr !== str && ((str = nstr) || 1));
    nnstr = str1.replace(/(AB\b|A\b|ABC\b)/g,'2');
    console.log('outside while...',nnstr,nstr,str);
    if (str === '0') {
      console.log("valid");
      return "valid";
    } else {
      console.log("invalid");
      return "invalid";
    }
  }

}

function mapStateToProps(state) {
  return{
    cell_rules: state.report_store.cell_rules,
    login_details: state.login_store,
  };
}

const mapDispatchToProps = (dispatch) => {
  return {
    insertRuleData:(data) => {
      dispatch(actionInsertRuleData(data));
    },
    updateRuleData:(id, data) => {
      dispatch(actionUpdateRuleData(id, data));
    }
  };
}

const VisibleAddReportAggRules = connect(
  mapStateToProps,
  mapDispatchToProps
)(AddReportAggRules);

export default VisibleAddReportAggRules;
<|endoftext|>


<commit_before>import test from 'ava';
import format from '../';

test('should format 2.15 as `2,15 €`', t => {
  t.is(format(2.15), '2,15 €');
});

test('should format `"2.15"` as `2,15 €`', t => {
  t.is(format('2.15'), '2,15 €');
});

test('should format `2` as `2 €`', t => {
  t.is(format(2), '2 €');
});

test('should format `2000` as `2.000 €`', t => {
  t.is(format(2000), '2.000 €');
});

test('should format `"123456.789"` as `$123,456.79`', t => {
  t.is(format('123456.789', {
    currency: '$',
    currencyPosition: 'before',
    decimalSeparator: '.',
    orderSeparator: ',',
    space: ''
  }), '$123,456.79');
});

test('should format `987.65` as `988 €`', t => {
  t.is(format(987.65, {
    decimals: 0
  }), '988 €');
});

test('should format `200` as `200,- €`', t => {
  t.is(format(200, {
    zeroDecimals: '-'
  }), '200,- €');
});

test('should format `two` as empty string', t => {
  t.is(format('two'), '');
});

test('should format `null` as empty string', t => {
  t.is(format(null), '');
});
<commit_msg>Add another test for `zeroDecimals`.<commit_after>import test from 'ava';
import geld from '../';

test('should format `2.15` as `"2,15 €"` ', t => {
  t.is(geld(2.15), '2,15 €');
});

test('should format `"2.15"` as `"2,15 €"`', t => {
  t.is(geld('2.15'), '2,15 €');
});

test('should format `2` as `"2 €"`', t => {
  t.is(geld(2), '2 €');
});

test('should format `2000` as `"2.000 €"`', t => {
  t.is(geld(2000), '2.000 €');
});

test('should format `"123456.789"` as `"$123,456.79"`', t => {
  t.is(geld('123456.789', {
    currency: '$',
    currencyPosition: 'before',
    decimalSeparator: '.',
    orderSeparator: ',',
    space: ''
  }), '$123,456.79');
});

test('should format `987.65` as `"988 €"`', t => {
  t.is(geld(987.65, {
    decimals: 0
  }), '988 €');
});

test('should format `200` as `"200,- €"`', t => {
  t.is(geld(200, {
    zeroDecimals: '-'
  }), '200,- €');
});

test('should format `200` as `"200,00 €"`', t => {
  t.is(geld(200, {
    zeroDecimals: '00'
  }), '200,00 €');
});

test('should format `two` as empty string', t => {
  t.is(geld('two'), '');
});

test('should format `null` as empty string', t => {
  t.is(geld(null), '');
});
<|endoftext|>


<commit_before>/* jslint node: true */
'use strict';

var chai = require( 'chai' );
var _ = require( 'lodash' );
var should = chai.should();
var sinon = require( 'sinon' );
var https = require( 'https' );
var httpsStub;
var LogglyInterface = require( '../lib/logglyInterface' );
// prime the interface with some dummy connection info
var logglyInterface = new LogglyInterface( loadTestResource( './fixtures/logglyConfig' ) );

function loadTestResource( resource ) {
	return _.cloneDeep( require( resource ) );
}

describe( 'logglyInterface', function() {

	describe( '#log', function() {

		beforeEach( function( done ) {
			httpsStub = sinon.stub( https, 'request', function() {
				return {
					write: function() {},
					end: function() {}
				}
			} );
			done();
		} );

		it( 'should fire an https request when the correct arguments are passed in', function( done ) {
			logglyInterface.log( loadTestResource( './fixtures/logOptions' ), loadTestResource( './fixtures/logLog' ) );
			httpsStub.calledWith( loadTestResource( './expected/logResult' ) ).should.be.true;
			done();
		} );

		it( 'should fire an http request when log is a string', function( done ) {
			logglyInterface.log(  loadTestResource( './fixtures/logOptions' ), 'test' );
			httpsStub.calledWith( loadTestResource( './expected/logResult' ) ).should.be.true;
			done();
		} );

		it( 'should not make a https request when no log argument is passed', function( done ) {
			logglyInterface.log();
			httpsStub.callCount.should.equal( 0 );
			done();
		} );

		afterEach( function( done ) {
			httpsStub.restore();
			done();
		} );

	} );

} );<commit_msg>abstract fixtures and expecteds<commit_after>/* jslint node: true */
'use strict';

var chai = require( 'chai' );
var _ = require( 'lodash' );
var should = chai.should();
var sinon = require( 'sinon' );
var https = require( 'https' );
var httpsStub;
var LogglyInterface = require( '../lib/logglyInterface' );
// prime the interface with some dummy connection info
var logglyInterface = new LogglyInterface( loadTestResource( './fixtures/logglyConfig' ) );

function loadTestResource( resource ) {
	return _.cloneDeep( require( resource ) );
}

describe( 'logglyInterface', function() {

	describe( '#log', function() {

		beforeEach( function( done ) {
			httpsStub = sinon.stub( https, 'request', function() {
				return {
					write: function() {},
					end: function() {}
				}
			} );
			done();
		} );

		it( 'should make an https request when the correct arguments are passed in', function( done ) {
			logglyInterface.log( loadTestResource( './fixtures/logOptions' ), loadTestResource( './fixtures/logLog' ) );
			httpsStub.calledWith( loadTestResource( './expected/logResult' ) ).should.be.true;
			done();
		} );

		it( 'should make an http request when log is a string', function( done ) {
			logglyInterface.log(  loadTestResource( './fixtures/logOptions' ), 'test' );
			httpsStub.calledWith( loadTestResource( './expected/logResult' ) ).should.be.true;
			done();
		} );

		it( 'should not make a https request when no log argument is passed', function( done ) {
			logglyInterface.log();
			httpsStub.callCount.should.equal( 0 );
			done();
		} );

		afterEach( function( done ) {
			httpsStub.restore();
			done();
		} );

	} );

} );<|endoftext|>


<commit_before>angular.module('player')
	.controller('ScorecardController', function($scope, $stateParams, localStorage)
	{
		// get player information
		$scope.player = getPlayer($stateParams.player);

		// mock data to be deleted
		var data = [1200, 1208, 1227, 1225, 1231, 1235, 1235, 1236, 1242, 1226, 1251, 1256, 1267, 1264, 1261, 1272];
		var dates = ["7/12", "7/15", "7/15", "7/16", "7/23", "7/29", "8/2", "8/19", "8/21", "8/25", "9/13", "9/21", "9/23", "10/3", "10/4", "11/17"];

		// set up charts
		setUpCharts();

		function getPlayer(name)
		{
			return {
				name: name,
				elo: getElo(name),
				avg: getAvg(name),
				percent: getPercent(name)
			}
		}

		function getElo(name)
		{
			// load from local storage
      var elos = localStorage.getObject('elos');
      var index = _.indexOf(_.pluck(elos, 'name'), name);

			return elos[index].elo;
		}

		function getAvg(name)
		{
			var avgs = localStorage.getObject('avgs');
			var index = _.indexOf(_.pluck(avgs, 'name'), name);

			return avgs[index].avg;
		}

		function getPercent(name)
		{
      var percent = localStorage.getObject('percent');
      var index = _.indexOf(_.pluck(percent, 'name'), name);

			return percent[index].percent;
		}

		function setUpCharts()
		{
			$scope.charts = [];

			// Set up ELO Rating chart
			$scope.charts.push(getEloChartOptions());

			// Set up Avg Score chart
			$scope.charts.push(getAvgChartOptions());

			// Set up Win Percent chart
			$scope.charts.push(getPercentChartOptions());
		}

		function getEloChartOptions()
		{
			return {
				title: 'ELO Rating',
				subtitle: 'This is placeholder data for now',
				yAxis: 'ELO',
				class: 'elo',
				data: data,
				dates: dates
			};
		}

		function getAvgChartOptions()
		{
			return {
				title: 'Average Score Per Game',
				subtitle: 'This is placeholder data for now',
				yAxis: 'Score',
				class: 'avg',
				data: data,
				dates: dates
			};
		}

		function getPercentChartOptions()
		{
			return {
				title: 'Percent Games Won',
				subtitle: 'This is placeholder data for now',
				yAxis: 'Percent',
				class: 'percent',
				data: data,
				dates: dates
			};
		}
	});<commit_msg>Better documentation on the scorecard functions<commit_after>angular.module('player')
	.controller('ScorecardController', function($scope, $stateParams, localStorage)
	{
		// set up the player
		$scope.player = getPlayer($stateParams.player);

		// mock data to be deleted
		var data = [1200, 1208, 1227, 1225, 1231, 1235, 1235, 1236, 1242, 1226, 1251, 1256, 1267, 1264, 1261, 1272];
		var dates = ["7/12", "7/15", "7/15", "7/16", "7/23", "7/29", "8/2", "8/19", "8/21", "8/25", "9/13", "9/21", "9/23", "10/3", "10/4", "11/17"];

		// set up charts
		setUpCharts();

		// get the player information
		function getPlayer(name)
		{
			return {
				name: name,
				elo: getElo(name),
				avg: getAvg(name),
				percent: getPercent(name)
			}
		}

		// get the elo for this playe from local storage
		function getElo(name)
		{
			// load from local storage
      var elos = localStorage.getObject('elos');
      var index = _.indexOf(_.pluck(elos, 'name'), name);

			return elos[index].elo;
		}

		// get the average score for this player from local storage
		function getAvg(name)
		{
			var avgs = localStorage.getObject('avgs');
			var index = _.indexOf(_.pluck(avgs, 'name'), name);

			return avgs[index].avg;
		}

		// get the win % for this player from local storage
		function getPercent(name)
		{
      var percent = localStorage.getObject('percent');
      var index = _.indexOf(_.pluck(percent, 'name'), name);

			return percent[index].percent;
		}

		// set up the charts for the scorecard page
		function setUpCharts()
		{
			$scope.charts = [];

			// Set up ELO Rating chart
			$scope.charts.push(getEloChartOptions());

			// Set up Avg Score chart
			$scope.charts.push(getAvgChartOptions());

			// Set up Win Percent chart
			$scope.charts.push(getPercentChartOptions());
		}

		// define options for the ELO Rating chart
		function getEloChartOptions()
		{
			return {
				title: 'ELO Rating',
				subtitle: 'This is placeholder data for now',
				yAxis: 'ELO',
				class: 'elo',
				data: data,
				dates: dates
			};
		}

		// define options for the Average Score chart
		function getAvgChartOptions()
		{
			return {
				title: 'Average Score Per Game',
				subtitle: 'This is placeholder data for now',
				yAxis: 'Score',
				class: 'avg',
				data: data,
				dates: dates
			};
		}

		// define options for the Win Percentage chart
		function getPercentChartOptions()
		{
			return {
				title: 'Percent Games Won',
				subtitle: 'This is placeholder data for now',
				yAxis: 'Percent',
				class: 'percent',
				data: data,
				dates: dates
			};
		}
	});<|endoftext|>


<commit_before>let { type, rangeCheck, repeat } = require("../utility");

module.exports = class Matrix {

  constructor(columns, rows, data) {
    this.columns = columns;
    this.rows    = rows;
    this.data    = data;
  }

  static create(m) {
    let columns = null;
    let rows = 0;
    let data = [ ];
    for (let row of m) {
      let rowLength = 0;
      for (let element of row) {
        if (typeof element != "number")
          throw new Error(`Expected number, got '${ type(element) }'`)
        data.push(element);
        rowLength++;
      }
      if (columns == null) columns = rowLength;
      else if (rowLength != columns)
        throw new Error(`Row lengths don't match (${ rowLength } != ${ columns })`);
      rows++;
    }
    if ((rows == 0) || (columns == 0))
      throw new Error("Matrix must have at least one element");
    return new Matrix(columns, rows, data);
  }

  static zero(columns, rows = columns) {
    if ((columns <= 0) || (rows <= 0))
      throw new Error(`Invalid matrix dimensions (${ columns },${ rows })`);
    let data = new Array(columns * rows);
    return new Matrix(columns, rows, data);
  }

  static identity(size) {
    let matrix = Matrix.zero(size);
    for (let i = 0; i < size; i++)
      matrix.set(i, i, 1);
    return matrix;
  }

  static translation(...v) {
    let matrix = Matrix.identity(v.length - 1);
    for (let i = 0; i < v.length; i++)
      matrix.set(i, matrix.rows - 1, v[i]);
    return matrix;
  }

  static scale(...v) {
    let matrix = Matrix.identity(v.length - 1);
    for (let i = 0; i < v.length; i++)
      matrix.set(i, i, v[i]);
    return matrix;
  }

  static lookAt(eye, center, up) {
    let z = eye.subtract(center).toUnitVector();
    let x = up.cross(z).toUnitVector();
    let y = z.cross(x).toUnitVector();

    let m = Matrix.identity(4);
    m.setRow(0, ...repeat(x, 3));
    m.setRow(1, ...repeat(y, 3));
    m.setRow(2, ...repeat(z, 3));

    let t = Matrix.identity(4);
    t.setColumn(3, ...eye.negate());

    return m.multiply(t);
  }

  static frustum(left, right, bottom, top, znear, zfar) {
    let X = 2 * znear / (right - left);
    let Y = 2 * znear / (top - bottom);
    let A = (right + left) / (right - left);
    let B = (top + bottom) / (top - bottom);
    let C = -(zfar + znear) / (zfar - znear);
    let D = -2 * zfar * znear / (zfar - znear);

    return Matrix.create(
      [[ X, 0,  A, 0 ]
       [ 0, Y,  B, 0 ]
       [ 0, 0,  C, D ]
       [ 0, 0, -1, 0 ]]);
  }

  static perspective(fovy, aspect, znear, zfar) {
    let ymax = znear * Math.tan(fovy * Math.PI / 360.0);
    let ymin = -ymax;
    let xmin = ymin * aspect;
    let xmax = ymax * aspect;

    return Matrix.frustum(xmin, xmax, ymin, ymax, znear, zfar);
  };

  static ortho(left, right, bottom, top, znear, zfar) {
    let tx = -(right + left) / (right - left);
    let ty = -(top + bottom) / (top - bottom);
    let tz = -(zfar + znear) / (zfar - znear);

    return Matrix.create(
      [[ 2 / (right - left), 0, 0, 0 ]
      [ 0, 2 / (top - bottom), 0, 0 ]
      [ 0, 0, -2 / (zfar - znear), 0 ]
      [ tx, ty, tz, 1 ]]);
  };

  get size() { return [ this.columns, this.rows ]; }

  get elements() { return this.elements[Symbol.iterator]; }

  _index(i, j) { return (i + j * this.columns); }

  _indexWithCheck(i, j) {
    if (!rangeCheck(i, 0, this.rows - 1) ||
        !rangeCheck(j, 0, this.columns - 1))
      throw new Error(`[${ i },${ j }] is not a valid index in Matrix of size (${ this.size.join(",") })`);
    return this._index(i, j);
  }

  get(i, j) { return this.data[this._indexWithCheck(i, j)]; }

  set(i, j, v) { this.data[this._indexWithCheck(i, j)] = v; }

  * row(row) {
    if (!rangeCheck(row, 0, this.rows - 1))
      throw new Error(`Row ${ row } is not valid in Matrix of size (${ this.size.join(",") })`);
    for (let i = 0; i < this.columns; i++)
      yield this.data[this._index(i, row)];
  }

  * column(column) {
    if (!rangeCheck(column, 0, this.columns - 1))
      throw new Error(`Column ${ column } is not valid in Matrix of size (${ this.size.join(",") })`);
    for (let i = 0; i < this.rows; i++)
      yield this.data[this._index(column, i)];
  }

  setRow(row, ...v) {
    if (!rangeCheck(row, 0, this.rows - 1))
      throw new Error(`Row ${ row } is not valid in Matrix of size (${ this.size.join(",") })`);
    if (v.length > this.columns)
      throw new Error(`Can't put ${ v.length } values into a matrix with ${ this.columns } columns`);
    for (let i = 0; i < this.columns; i++)
      this.data[this._index(i, row)] = v[i];
  }

  setColumn(column, ...v) {
    if (!rangeCheck(column, 0, this.columns - 1))
      throw new Error(`Columns ${ column } is not valid in Matrix of size (${ this.size.join(",") })`);
    if (v.length > this.rows)
      throw new Error(`Can't put ${ v.length } values into a matrix with ${ this.rows } rows`);
    for (let i = 0; i < this.rows; i++)
      this.data[this._index(column, i)] = v[i];
  }

  clone() { return new Matrix(this.columns, this.rows, this.data.slice(0)); }

};
<commit_msg>Update Matrix to use toVector (and normalize)<commit_after>let { type, rangeCheck, repeat } = require("../utility");
let Vector = require("./Vector");

module.exports = class Matrix {

  constructor(columns, rows, data) {
    this.columns = columns;
    this.rows    = rows;
    this.data    = data;
  }

  static create(m) {
    let columns = null;
    let rows = 0;
    let data = [ ];
    for (let row of m) {
      let rowLength = 0;
      for (let element of row) {
        if (typeof element != "number")
          throw new Error(`Expected number, got '${ type(element) }'`)
        data.push(element);
        rowLength++;
      }
      if (columns == null) columns = rowLength;
      else if (rowLength != columns)
        throw new Error(`Row lengths don't match (${ rowLength } != ${ columns })`);
      rows++;
    }
    if ((rows == 0) || (columns == 0))
      throw new Error("Matrix must have at least one element");
    return new Matrix(columns, rows, data);
  }

  static zero(columns, rows = columns) {
    if ((columns <= 0) || (rows <= 0))
      throw new Error(`Invalid matrix dimensions (${ columns },${ rows })`);
    let data = new Array(columns * rows);
    return new Matrix(columns, rows, data);
  }

  static identity(size) {
    let matrix = Matrix.zero(size);
    for (let i = 0; i < size; i++)
      matrix.set(i, i, 1);
    return matrix;
  }

  static translation(...v) {
    let matrix = Matrix.identity(v.length - 1);
    for (let i = 0; i < v.length; i++)
      matrix.set(i, matrix.rows - 1, v[i]);
    return matrix;
  }

  static scale(...v) {
    let matrix = Matrix.identity(v.length - 1);
    for (let i = 0; i < v.length; i++)
      matrix.set(i, i, v[i]);
    return matrix;
  }

  static lookAt(eye, center, up) {
    let z = eye.subtract(center).normalize();
    let x = up.cross(z).normalize();
    let y = z.cross(x).normalize();

    let m = Matrix.identity(4);
    m.setRow(0, ...repeat(x, 3));
    m.setRow(1, ...repeat(y, 3));
    m.setRow(2, ...repeat(z, 3));

    let t = Matrix.identity(4);
    t.setColumn(3, ...eye.negate());

    return m.multiply(t);
  }

  static frustum(left, right, bottom, top, znear, zfar) {
    let X = 2 * znear / (right - left);
    let Y = 2 * znear / (top - bottom);
    let A = (right + left) / (right - left);
    let B = (top + bottom) / (top - bottom);
    let C = -(zfar + znear) / (zfar - znear);
    let D = -2 * zfar * znear / (zfar - znear);

    return Matrix.create(
      [[ X, 0,  A, 0 ]
       [ 0, Y,  B, 0 ]
       [ 0, 0,  C, D ]
       [ 0, 0, -1, 0 ]]);
  }

  static perspective(fovy, aspect, znear, zfar) {
    let ymax = znear * Math.tan(fovy * Math.PI / 360.0);
    let ymin = -ymax;
    let xmin = ymin * aspect;
    let xmax = ymax * aspect;

    return Matrix.frustum(xmin, xmax, ymin, ymax, znear, zfar);
  };

  static ortho(left, right, bottom, top, znear, zfar) {
    let tx = -(right + left) / (right - left);
    let ty = -(top + bottom) / (top - bottom);
    let tz = -(zfar + znear) / (zfar - znear);

    return Matrix.create(
      [[ 2 / (right - left), 0, 0, 0 ]
      [ 0, 2 / (top - bottom), 0, 0 ]
      [ 0, 0, -2 / (zfar - znear), 0 ]
      [ tx, ty, tz, 1 ]]);
  };

  get size() { return [ this.columns, this.rows ]; }

  get elements() { return this.elements[Symbol.iterator]; }

  _index(i, j) { return (i + j * this.columns); }

  _indexWithCheck(i, j) {
    if (!rangeCheck(i, 0, this.rows - 1) ||
        !rangeCheck(j, 0, this.columns - 1))
      throw new Error(`[${ i },${ j }] is not a valid index in Matrix of size (${ this.size.join(",") })`);
    return this._index(i, j);
  }

  get(i, j) { return this.data[this._indexWithCheck(i, j)]; }

  set(i, j, v) { this.data[this._indexWithCheck(i, j)] = v; }

  * row(row) {
    if (!rangeCheck(row, 0, this.rows - 1))
      throw new Error(`Row ${ row } is not valid in Matrix of size (${ this.size.join(",") })`);
    for (let i = 0; i < this.columns; i++)
      yield this.data[this._index(i, row)];
  }

  * column(column) {
    if (!rangeCheck(column, 0, this.columns - 1))
      throw new Error(`Column ${ column } is not valid in Matrix of size (${ this.size.join(",") })`);
    for (let i = 0; i < this.rows; i++)
      yield this.data[this._index(column, i)];
  }

  setRow(row, ...v) {
    v = Vector.toVector(v, true);
    if (!rangeCheck(row, 0, this.rows - 1))
      throw new Error(`Row ${ row } is not valid in Matrix of size (${ this.size.join(",") })`);
    if (v.length > this.columns)
      throw new Error(`Can't put ${ v.length } values into a matrix with ${ this.columns } columns`);
    for (let i = 0; i < this.columns; i++)
      this.data[this._index(i, row)] = v[i];
  }

  setColumn(column, ...v) {
    v = Vector.toVector(v, true);
    if (!rangeCheck(column, 0, this.columns - 1))
      throw new Error(`Columns ${ column } is not valid in Matrix of size (${ this.size.join(",") })`);
    if (v.length > this.rows)
      throw new Error(`Can't put ${ v.length } values into a matrix with ${ this.rows } rows`);
    for (let i = 0; i < this.rows; i++)
      this.data[this._index(column, i)] = v[i];
  }

  clone() { return new Matrix(this.columns, this.rows, this.data.slice(0)); }

};
<|endoftext|>


<commit_before>import {Howler, Howl} from "howler";

let soundMap = new Map();

let muteLooped = /\bmutelooped\b/.test(window.location.search);

let muted = false;

export default class SoundManager {
  static add(url, {loop = false} = {}) {
    let sound = new Howl({
      urls: [url],
      loop: loop
    });
    let split = url.split("/");
    let name = split[split.length - 1].split(".")[0];
    soundMap.set(name, sound);
  }
  static play(name, {loop = undefined} = {}) {
    let sound = soundMap.get(name);
    if(loop !== undefined) {
      sound.loop(loop);
    }
    if(sound.loop() && muteLooped) {
      sound.mute();
    }
    sound.play();
  }
  static toggleMute() {
    if(muted) {
      SoundManager.unmute();
    } else {
      SoundManager.mute();
    }
  }
  static mute() {
    muted = true;
    Howler.mute();
  }
  static unmute() {
    muted = false;
    Howler.unmute();
  }
}

if(/\bmute\b/.test(window.location.search)) {
  SoundManager.mute();
}
<commit_msg>add stop method to sounds manager<commit_after>import {Howler, Howl} from "howler";

let soundMap = new Map();

let muteLooped = /\bmutelooped\b/.test(window.location.search);

let muted = false;

export default class SoundManager {
  static add(url, {loop = false} = {}) {
    let split = url.split("/");
    let name = split[split.length - 1].split(".")[0];
    if(soundMap.get(name)) {
      console.warn(`Sound ${name} is added twice`);
      return;
    }
    let sound = new Howl({
      urls: [url],
      loop: loop
    });
    soundMap.set(name, sound);
  }
  static play(name, {loop = undefined} = {}) {
    let sound = soundMap.get(name);
    if(!sound) {
      console.error(`Sound ${name} hasn't been added`);
      return;
    }
    if(loop !== undefined) {
      sound.loop(loop);
    }
    if(sound.loop() && muteLooped) {
      sound.mute();
    }
    sound.play();
  }
  static stop(name) {
    let sound = soundMap.get(name);
    sound.stop();
  }
  static toggleMute() {
    if(muted) {
      SoundManager.unmute();
    } else {
      SoundManager.mute();
    }
  }
  static mute() {
    muted = true;
    Howler.mute();
  }
  static unmute() {
    muted = false;
    Howler.unmute();
  }
}

if(/\bmute\b/.test(window.location.search)) {
  SoundManager.mute();
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.views.calendar");
frappe.provide("frappe.views.calendars");

frappe.views.CalendarView = frappe.views.ListRenderer.extend({
	name: 'Calendar',
	render_view: function() {
		var me = this;
		var options = {
			doctype: this.doctype,
			parent: this.wrapper,
			page: this.list_view.page,
			filter_vals: this.list_view.filter_list.get_filters()
		}
		$.extend(options, frappe.views.calendar[this.doctype]);
		this.calendar = new frappe.views.Calendar(options);
	},
	set_defaults: function() {
		this._super();
		this.page_title = this.page_title + ' ' + __('Calendar');
		this.no_realtime = true;
		this.show_no_result = false;
		this.hide_sort_selector = true;
	},
	get_header_html: function() {
		return null;
	},
	required_libs: [
		'assets/frappe/js/lib/fullcalendar/fullcalendar.min.css',
		'assets/frappe/js/lib/fullcalendar/fullcalendar.min.js'
	]
})

frappe.views.Calendar = Class.extend({
	init: function(options) {
		$.extend(this, options);
		this.make_page();
		this.setup_options();
		this.make();
	},
	make_page: function() {
		var me = this;

		// add links to other calendars
		$.each(frappe.boot.calendars, function(i, doctype) {
			if(frappe.model.can_read(doctype)) {
				me.page.add_menu_item(__(doctype), function() {
					frappe.set_route("List", doctype, "Calendar");
				});
			}
		});

		$(this.parent).on("show", function() {
			me.$cal.fullCalendar("refetchEvents");
		})
	},

	make: function() {
		var me = this;
		this.$wrapper = this.parent;
		this.$cal = $("<div>").appendTo(this.$wrapper);
		this.footnote_area = frappe.utils.set_footnote(this.footnote_area, this.$wrapper,
			__("Select or drag across time slots to create a new event."));
		this.footnote_area.css({"border-top": "0px"});

		this.$cal.fullCalendar(this.cal_options);
		this.set_css();
	},
	set_css: function() {
		// flatify buttons
		this.$wrapper.find("button.fc-state-default")
			.removeClass("fc-state-default")
			.addClass("btn btn-default");

		this.$wrapper.find(".fc-button-group").addClass("btn-group");

		this.$wrapper.find('.fc-prev-button span')
			.attr('class', '').addClass('fa fa-chevron-left')
		this.$wrapper.find('.fc-next-button span')
			.attr('class', '').addClass('fa fa-chevron-right')

		var btn_group = this.$wrapper.find(".fc-button-group");
		btn_group.find(".fc-state-active").addClass("active");

		btn_group.find(".btn").on("click", function() {
			btn_group.find(".btn").removeClass("active");
			$(this).addClass("active");
		});
	},
	field_map: {
		"id": "name",
		"start": "start",
		"end": "end",
		"allDay": "all_day",
	},
	styles: {
		"standard": {
			"color": "#F0F4F7"
		},
		"important": {
			"color": "#FFDCDC"
		},
		"danger": {
			"color": "#FFDCDC"
		},
		"warning": {
			"color": "#FFE6BF",
		},
		"success": {
			"color": "#E4FFC1",
		},
		"info": {
			"color": "#E8DDFF"
		},
		"inverse": {
			"color": "#D9F6FF"
		},
		"": {
			"color": "#F0F4F7"
		}
	},
	get_system_datetime: function(date) {
		date._offset = moment.user_utc_offset;
		return frappe.datetime.convert_to_system_tz(date);
	},
	setup_options: function() {
		var me = this;
		this.cal_options = {
			header: {
				left: 'title',
				center: '',
				right: 'prev,next month,agendaWeek,agendaDay'
			},
			editable: true,
			selectable: true,
			selectHelper: true,
			forceEventDuration: true,
			events: function(start, end, timezone, callback) {
				return frappe.call({
					method: me.get_events_method || "frappe.desk.calendar.get_events",
					type: "GET",
					args: me.get_args(start, end),
					callback: function(r) {
						var events = r.message;
						me.prepare_events(events);
						callback(events);
					}
				})
			},
			eventClick: function(event, jsEvent, view) {
				// edit event description or delete
				var doctype = event.doctype || me.doctype;
				if(frappe.model.can_read(doctype)) {
					frappe.set_route("Form", doctype, event.name);
				}
			},
			eventDrop: function(event, delta, revertFunc, jsEvent, ui, view) {
				me.update_event(event, revertFunc);
			},
			eventResize: function(event, delta, revertFunc, jsEvent, ui, view) {
				me.update_event(event, revertFunc);
			},
			select: function(startDate, endDate, jsEvent, view) {
				if (view.name==="month" && (endDate - startDate)===86400000) {
					// detect single day click in month view
					return;

				}

				var event = frappe.model.get_new_doc(me.doctype);

				event[me.field_map.start] = me.get_system_datetime(startDate);

				if(me.field_map.end)
					event[me.field_map.end] = me.get_system_datetime(endDate);

				if(me.field_map.allDay) {
					var all_day = (startDate._ambigTime && endDate._ambigTime) ? 1 : 0;

					event[me.field_map.allDay] = all_day;

					if (all_day)
						event[me.field_map.end] = me.get_system_datetime(moment(endDate).subtract(1, "s"));
				}

				frappe.set_route("Form", me.doctype, event.name);
			},
			dayClick: function(date, allDay, jsEvent, view) {
				jsEvent.day_clicked = true;
				return false;
			}
		};

		if(this.options) {
			$.extend(this.cal_options, this.options);
		}
	},
	get_args: function(start, end) {
		if(this.filter_vals) {
			var filters = {};
			this.filter_vals.forEach(function(f) {
				if(f[2]==="=") {
					filters[f[1]] = f[3];
				}
			});
		}
		var args = {
			doctype: this.doctype,
			start: this.get_system_datetime(start),
			end: this.get_system_datetime(end),
			filters: filters
		};
		return args;
	},
	refresh: function() {
		this.$cal.fullCalendar('refetchEvents');
	},
	prepare_events: function(events) {
		var me = this;
		$.each(events || [], function(i, d) {
			d.id = d.name;
			d.editable = frappe.model.can_write(d.doctype || me.doctype);

			// do not allow submitted/cancelled events to be moved / extended
			if(d.docstatus && d.docstatus > 0) {
				d.editable = false;
			}

			$.each(me.field_map, function(target, source) {
				d[target] = d[source];
			});

			if(!me.field_map.allDay)
				d.allDay = 1;

			// convert to user tz
			d.start = frappe.datetime.convert_to_user_tz(d.start);
			d.end = frappe.datetime.convert_to_user_tz(d.end);

			me.fix_end_date_for_event_render(d);

			if(me.get_css_class) {
				$.extend(d, me.styles[me.get_css_class(d)] || {});
			} else if(me.style_map) {
				$.extend(d, me.styles[me.style_map[d.status]] || {});
			} else {
				$.extend(d, me.styles[frappe.utils.guess_style(d.status, "standard")]);
			}
			d["textColor"] = "#36414C";
		})

		var palette_colors = ['red', 'green', 'blue', 'yellow', 'skyblue', 'orange'];
		var index = 0;

		if(events) {
			events = events.map(function(event) {
				event.className = "fc-bg-" + palette_colors[index];
				index = (index + 1) % palette_colors.length;
			})
		}
	},
	update_event: function(event, revertFunc) {
		var me = this;
		frappe.model.remove_from_locals(me.doctype, event.name);
		return frappe.call({
			method: me.update_event_method || "frappe.desk.calendar.update_event",
			args: me.get_update_args(event),
			callback: function(r) {
				if(r.exc) {
					show_alert(__("Unable to update event"));
					revertFunc();
				}
			},
			error: function() {
				revertFunc();
			}
		});
	},
	get_update_args: function(event) {
		var me = this;
		var args = {
			name: event[this.field_map.id]
		};

		args[this.field_map.start] = me.get_system_datetime(event.start);

		if(this.field_map.allDay)
			args[this.field_map.allDay] = (event.start._ambigTime && event.end._ambigTime) ? 1 : 0;

		if(this.field_map.end) {
			if (!event.end) {
				event.end = event.start.add(1, "hour");
			}

			args[this.field_map.end] = me.get_system_datetime(event.end);

			if (args[this.field_map.allDay]) {
				args[this.field_map.end] = me.get_system_datetime(moment(event.end).subtract(1, "s"));
			}
		}

		args.doctype = event.doctype || this.doctype;

		return { args: args, field_map: this.field_map };
	},

	fix_end_date_for_event_render: function(event) {
		if (event.allDay) {
			// We use inclusive end dates. This workaround fixes the rendering of events
			event.start = event.start ? $.fullCalendar.moment(event.start).stripTime() : null;
			event.end = event.end ? $.fullCalendar.moment(event.end).add(1, "day").stripTime() : null;
		}
	},
	add_filters: function() {
		var me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				df.change = function() {
					me.refresh();
				};
				me.page.add_field(df);
			});
		}
	},
	set_filter: function(doctype, value) {
		var me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				if(df.options===value)
					me.page.fields_dict[df.fieldname].set_input(value);
					return false;
			});
		}
	},
	get_filters: function() {
		var filter_vals = {},
			me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				filter_vals[df.fieldname || df.label] =
					me.page.fields_dict[df.fieldname || df.label].get_parsed_value();
			});
		}
		return filter_vals;
	},
	set_filters_from_route_options: function() {
		var me = this;
		if(frappe.route_options) {
			$.each(frappe.route_options, function(k, value) {
				if(me.page.fields_dict[k]) {
					me.page.fields_dict[k].set_input(value);
				};
			})
			frappe.route_options = null;
			me.refresh();
			return false;
		}
	}
})
<commit_msg>Update calendar.js<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.views.calendar");
frappe.provide("frappe.views.calendars");

frappe.views.CalendarView = frappe.views.ListRenderer.extend({
	name: 'Calendar',
	render_view: function() {
		var me = this;
		var options = {
			doctype: this.doctype,
			parent: this.wrapper,
			page: this.list_view.page,
			filter_vals: this.list_view.filter_list.get_filters()
		}
		$.extend(options, frappe.views.calendar[this.doctype]);
		this.calendar = new frappe.views.Calendar(options);
	},
	set_defaults: function() {
		this._super();
		this.page_title = this.page_title + ' ' + __('Calendar');
		this.no_realtime = true;
		this.show_no_result = false;
		this.hide_sort_selector = true;
	},
	get_header_html: function() {
		return null;
	},
	required_libs: [
		'assets/frappe/js/lib/fullcalendar/fullcalendar.min.css',
		'assets/frappe/js/lib/fullcalendar/fullcalendar.min.js',
		'assets/frappe/js/lib/fullcalendar/locale-all.js'
	]
})

frappe.views.Calendar = Class.extend({
	init: function(options) {
		$.extend(this, options);
		this.make_page();
		this.setup_options();
		this.make();
	},
	make_page: function() {
		var me = this;

		// add links to other calendars
		$.each(frappe.boot.calendars, function(i, doctype) {
			if(frappe.model.can_read(doctype)) {
				me.page.add_menu_item(__(doctype), function() {
					frappe.set_route("List", doctype, "Calendar");
				});
			}
		});

		$(this.parent).on("show", function() {
			me.$cal.fullCalendar("refetchEvents");
		})
	},

	make: function() {
		var me = this;
		this.$wrapper = this.parent;
		this.$cal = $("<div>").appendTo(this.$wrapper);
		this.footnote_area = frappe.utils.set_footnote(this.footnote_area, this.$wrapper,
			__("Select or drag across time slots to create a new event."));
		this.footnote_area.css({"border-top": "0px"});

		this.$cal.fullCalendar(this.cal_options);
		this.set_css();
	},
	set_css: function() {
		// flatify buttons
		this.$wrapper.find("button.fc-state-default")
			.removeClass("fc-state-default")
			.addClass("btn btn-default");

		this.$wrapper.find(".fc-button-group").addClass("btn-group");

		this.$wrapper.find('.fc-prev-button span')
			.attr('class', '').addClass('fa fa-chevron-left')
		this.$wrapper.find('.fc-next-button span')
			.attr('class', '').addClass('fa fa-chevron-right')

		var btn_group = this.$wrapper.find(".fc-button-group");
		btn_group.find(".fc-state-active").addClass("active");

		btn_group.find(".btn").on("click", function() {
			btn_group.find(".btn").removeClass("active");
			$(this).addClass("active");
		});
	},
	field_map: {
		"id": "name",
		"start": "start",
		"end": "end",
		"allDay": "all_day",
	},
	styles: {
		"standard": {
			"color": "#F0F4F7"
		},
		"important": {
			"color": "#FFDCDC"
		},
		"danger": {
			"color": "#FFDCDC"
		},
		"warning": {
			"color": "#FFE6BF",
		},
		"success": {
			"color": "#E4FFC1",
		},
		"info": {
			"color": "#E8DDFF"
		},
		"inverse": {
			"color": "#D9F6FF"
		},
		"": {
			"color": "#F0F4F7"
		}
	},
	get_system_datetime: function(date) {
		date._offset = moment.user_utc_offset;
		return frappe.datetime.convert_to_system_tz(date);
	},
	setup_options: function() {
		var me = this;
		this.cal_options = {
			locale: frappe.boot.user.language || "en",
			header: {
				left: 'title',
				center: '',
				right: 'prev,next month,agendaWeek,agendaDay'
			},
			editable: true,
			selectable: true,
			selectHelper: true,
			forceEventDuration: true,
			events: function(start, end, timezone, callback) {
				return frappe.call({
					method: me.get_events_method || "frappe.desk.calendar.get_events",
					type: "GET",
					args: me.get_args(start, end),
					callback: function(r) {
						var events = r.message;
						me.prepare_events(events);
						callback(events);
					}
				})
			},
			eventClick: function(event, jsEvent, view) {
				// edit event description or delete
				var doctype = event.doctype || me.doctype;
				if(frappe.model.can_read(doctype)) {
					frappe.set_route("Form", doctype, event.name);
				}
			},
			eventDrop: function(event, delta, revertFunc, jsEvent, ui, view) {
				me.update_event(event, revertFunc);
			},
			eventResize: function(event, delta, revertFunc, jsEvent, ui, view) {
				me.update_event(event, revertFunc);
			},
			select: function(startDate, endDate, jsEvent, view) {
				if (view.name==="month" && (endDate - startDate)===86400000) {
					// detect single day click in month view
					return;

				}

				var event = frappe.model.get_new_doc(me.doctype);

				event[me.field_map.start] = me.get_system_datetime(startDate);

				if(me.field_map.end)
					event[me.field_map.end] = me.get_system_datetime(endDate);

				if(me.field_map.allDay) {
					var all_day = (startDate._ambigTime && endDate._ambigTime) ? 1 : 0;

					event[me.field_map.allDay] = all_day;

					if (all_day)
						event[me.field_map.end] = me.get_system_datetime(moment(endDate).subtract(1, "s"));
				}

				frappe.set_route("Form", me.doctype, event.name);
			},
			dayClick: function(date, allDay, jsEvent, view) {
				jsEvent.day_clicked = true;
				return false;
			}
		};

		if(this.options) {
			$.extend(this.cal_options, this.options);
		}
	},
	get_args: function(start, end) {
		if(this.filter_vals) {
			var filters = {};
			this.filter_vals.forEach(function(f) {
				if(f[2]==="=") {
					filters[f[1]] = f[3];
				}
			});
		}
		var args = {
			doctype: this.doctype,
			start: this.get_system_datetime(start),
			end: this.get_system_datetime(end),
			filters: filters
		};
		return args;
	},
	refresh: function() {
		this.$cal.fullCalendar('refetchEvents');
	},
	prepare_events: function(events) {
		var me = this;
		$.each(events || [], function(i, d) {
			d.id = d.name;
			d.editable = frappe.model.can_write(d.doctype || me.doctype);

			// do not allow submitted/cancelled events to be moved / extended
			if(d.docstatus && d.docstatus > 0) {
				d.editable = false;
			}

			$.each(me.field_map, function(target, source) {
				d[target] = d[source];
			});

			if(!me.field_map.allDay)
				d.allDay = 1;

			// convert to user tz
			d.start = frappe.datetime.convert_to_user_tz(d.start);
			d.end = frappe.datetime.convert_to_user_tz(d.end);

			me.fix_end_date_for_event_render(d);

			if(me.get_css_class) {
				$.extend(d, me.styles[me.get_css_class(d)] || {});
			} else if(me.style_map) {
				$.extend(d, me.styles[me.style_map[d.status]] || {});
			} else {
				$.extend(d, me.styles[frappe.utils.guess_style(d.status, "standard")]);
			}
			d["textColor"] = "#36414C";
		})

		var palette_colors = ['red', 'green', 'blue', 'yellow', 'skyblue', 'orange'];
		var index = 0;

		if(events) {
			events = events.map(function(event) {
				event.className = "fc-bg-" + palette_colors[index];
				index = (index + 1) % palette_colors.length;
			})
		}
	},
	update_event: function(event, revertFunc) {
		var me = this;
		frappe.model.remove_from_locals(me.doctype, event.name);
		return frappe.call({
			method: me.update_event_method || "frappe.desk.calendar.update_event",
			args: me.get_update_args(event),
			callback: function(r) {
				if(r.exc) {
					show_alert(__("Unable to update event"));
					revertFunc();
				}
			},
			error: function() {
				revertFunc();
			}
		});
	},
	get_update_args: function(event) {
		var me = this;
		var args = {
			name: event[this.field_map.id]
		};

		args[this.field_map.start] = me.get_system_datetime(event.start);

		if(this.field_map.allDay)
			args[this.field_map.allDay] = (event.start._ambigTime && event.end._ambigTime) ? 1 : 0;

		if(this.field_map.end) {
			if (!event.end) {
				event.end = event.start.add(1, "hour");
			}

			args[this.field_map.end] = me.get_system_datetime(event.end);

			if (args[this.field_map.allDay]) {
				args[this.field_map.end] = me.get_system_datetime(moment(event.end).subtract(1, "s"));
			}
		}

		args.doctype = event.doctype || this.doctype;

		return { args: args, field_map: this.field_map };
	},

	fix_end_date_for_event_render: function(event) {
		if (event.allDay) {
			// We use inclusive end dates. This workaround fixes the rendering of events
			event.start = event.start ? $.fullCalendar.moment(event.start).stripTime() : null;
			event.end = event.end ? $.fullCalendar.moment(event.end).add(1, "day").stripTime() : null;
		}
	},
	add_filters: function() {
		var me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				df.change = function() {
					me.refresh();
				};
				me.page.add_field(df);
			});
		}
	},
	set_filter: function(doctype, value) {
		var me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				if(df.options===value)
					me.page.fields_dict[df.fieldname].set_input(value);
					return false;
			});
		}
	},
	get_filters: function() {
		var filter_vals = {},
			me = this;
		if(this.filters) {
			$.each(this.filters, function(i, df) {
				filter_vals[df.fieldname || df.label] =
					me.page.fields_dict[df.fieldname || df.label].get_parsed_value();
			});
		}
		return filter_vals;
	},
	set_filters_from_route_options: function() {
		var me = this;
		if(frappe.route_options) {
			$.each(frappe.route_options, function(k, value) {
				if(me.page.fields_dict[k]) {
					me.page.fields_dict[k].set_input(value);
				};
			})
			frappe.route_options = null;
			me.refresh();
			return false;
		}
	}
})
<|endoftext|>


<commit_before>import React from 'react';
import DayPicker, { DateUtils } from 'react-day-picker';

import 'react-day-picker/lib/style.css';

export default class DisabledDays extends React.Component {
  constructor(props) {
    super(props);
    this.handleDayClick = this.handleDayClick.bind(this);
  }
  state = {
    selectedDay: null
  };
  handleDayClick(e, day, { disabled, selected }) {
    if (disabled) {
      return;
    }
    this.setState({
      selectedDay: selected ? null : day
    });
  }
  render() {
    const { selectedDay } = this.state;
    return (

        <DayPicker
          selectedDays={day => DateUtils.isSameDay(selectedDay, day)}
          disabledDays={DateUtils.isPastDay}
          enableOutsideDays
          onDayClick={this.handleDayClick}
        />

          {selectedDay ? selectedDay.toLocaleDateString() : 'Please select a day 👻'}

    );
  }
}<commit_msg>Removed file commited by error<commit_after><|endoftext|>


<commit_before>var Flexio = require('../src/main.js')

test('Flexio.task.echo; code to object', () => {
  expect(
    Flexio.task.echo('hello')
  ).toEqual(
    { op: 'echo', params: { msg: 'hello' } }
  )
})

test('Flexio.task.echo; object to code', () => {
  var obj = { op: 'echo', params: { msg: 'hello' } }

  expect(
    Flexio.task.echo.toCode(obj)
  ).toEqual(
    `echo("hello")`
  )
})<commit_msg>added newline at end<commit_after>var Flexio = require('../src/main.js')

test('Flexio.task.echo; code to object', () => {
  expect(
    Flexio.task.echo('hello')
  ).toEqual(
    { op: 'echo', params: { msg: 'hello' } }
  )
})

test('Flexio.task.echo; object to code', () => {
  var obj = { op: 'echo', params: { msg: 'hello' } }

  expect(
    Flexio.task.echo.toCode(obj)
  ).toEqual(
    `echo("hello")`
  )
})
<|endoftext|>


<commit_before>	function fight() {}

fight.prototype = {
  create: function() {
  	console.log(game.state.current)

  	// Logic to only scatter aliens once, called in fight - update loop
  	gameUI.alienScatterEnabled = true

	  game.physics.startSystem(Phaser.Physics.ARCADE)

	  // scrolling tile sprite
	  starfieldBackground.create(game)

	  // Ceiling visible line and collision detector
	  gameUI.gameAreaCeilingLine = new Phaser.Rectangle(0,200, 1200, 1)
	  gameUI.gameAreaCeiling = game.add.sprite(0,200,null)
	  game.physics.enable(gameUI.gameAreaCeiling, Phaser.Physics.ARCADE)
	  gameUI.gameAreaCeiling.body.setSize(1200, 1, 0, 0)
	  gameUI.gameAreaCeiling.body.immovable = true

	  // rain
	  rain.create(game)

	  // playerBullets
	  playerBullets = gameState.groups.playerBullets = game.add.group()
	  playerBullets.enableBody = true
	  playerBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  playerBullets.createMultiple(250, 'bullet')

	  playerBullets.setAll('anchor.x', 0.5)
	  playerBullets.setAll('anchor.y', 0.5)
	  playerBullets.setAll('damage', 5)

	  bossAlienBullets = gameState.groups.bossAlienBullets = game.add.group()
	  bossAlienBullets.enableBody = true
	  bossAlienBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  bossAlienBullets.createMultiple(250, 'bullet')

	  bossAlienBullets.setAll('anchor.x', 0.5)
	  bossAlienBullets.setAll('anchor.y', 0.5)
	  bossAlienBullets.setAll('damage', 50)

	  // create player object
	  var player = gameState.player = game.add.sprite(32, game.world.height - 150, 'dude')
	  game.physics.arcade.enable(player)
	  player.body.bounce.y = 0.2
	  player.body.collideWorldBounds = true
	  player.health = 100
	  gameUI.upgradeGun(gameState.questionsCorrect)

	  // create explosions
	  var explosions = gameState.groups.explosions = game.add.group()
    explosions.createMultiple(21, 'explosion')
    explosions.forEach(setUpExplosion)

    function setUpExplosion(explode){
    	explode.animations.add('explosion')
    }

	  // create regular aliens
	  aliens = gameState.groups.aliens = game.add.group()
	  aliens.enableBody = true
	  aliens.physicsBodyType = Phaser.Physics.ARCADE

	  // create boss alien
	  bossAlien = gameState.bossAlien = game.add.sprite(1500, 350, 'diamond')
	  game.physics.arcade.enable(bossAlien)
	  bossAlien.enableBody = true
	  bossAlien.physicsBodyType = Phaser.Physics.ARCADE
	  bossAlien.body.bounce.x = 1
	  bossAlien.body.bounce.y = 1
	  var scale = gameUI.alienBossScale(gameState.questionsCorrect)
	  bossAlien.scale.setTo(scale,scale)
	  bossAlien.anchor.x = 0.5
	  bossAlien.anchor.y = 0.5

	  // create keyboard listeners
	  gameState.cursors = game.input.keyboard.createCursorKeys()

	  // create text fields ------------------------------------------------
	  gameUI.scoreObject = game.add.text(
	    32, 32, // x coord, y coord
	    'Score: ' + gameUI.score, // text field
	    {fontSize: '32px', fill: '#ffffff'} // text styling
	    )

	  gameUI.spawnAliens()
  },
  update: function() {
  	 	var player = gameState.player
		  var cursors = gameState.cursors
		  var shootThePlayerGun = false
		  var shootTheBossAlienGun = false

		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(player, gameUI.gameAreaCeiling)
		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.groups.aliens, gameUI.gameAreaCeiling)
		  // boss alien cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens bounce off of each other
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.groups.aliens)
		  // aliens bounce off of boss alien
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.bossAlien)

		  // Bullets cause damage to aliens and then disappear
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.groups.aliens, gameUI.hitAlien , null, this)
		  // Bullets cause the boss alien to shrink
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.bossAlien, gameUI.shrinkBoss , null, this)
		  // Aliens damage the player when they touch
		  game.physics.arcade.overlap(player, gameState.groups.aliens, gameUI.hitPlayer, null, this)
		  // Boss alien bullets damage player
		  game.physics.arcade.overlap(player, gameState.groups.bossAlienBullets, gameUI.hitPlayer, null, this)

		  // set scroll speed of background
		  // starfield.tilePosition.x -= 1
		  starfieldBackground.update()

		    if (cursors.left.isDown) {
		      // player UP
		      player.body.velocity.y = -250;
		      // player.animations.play('up')
		    } else if (cursors.right.isDown){
		      // player DOWN
		      player.body.velocity.y = 250;
		      // player.animations.play('down')
		    } else {
		      // player stand still
		      player.animations.stop()
		      player.frame = 4
		      player.body.velocity.y = 0
		    }

		  // fire!
		  gameUI.firePlayerGunCounter += 1
		  if (gameUI.firePlayerGunCounter >= gameUI.firePlayerGunRate){
		    shootThePlayerGun = true
		    gameUI.firePlayerGunCounter = 0
		  }
		  if (shootThePlayerGun) {
		    gameUI.firePlayerBullet()
		  }

		  gameUI.fireBossAlienGunCounter += 1
		  if (gameUI.fireBossAlienGunCounter >= gameUI.fireBossAlienGunRate){
		    shootTheBossAlienGun = true
		    gameUI.fireBossAlienGunCounter = 0
		  }

		  if (shootTheBossAlienGun && gameState.bossAlien.alive) {
		    gameUI.fireBossAlienBullet()
		  }

		  if (gameUI.aliensDead()) {
		    gameState.currentLevel++
		    gameState.firstTimeOnLevel = true
		    game.state.start('level_intro')
		  }

		  if (gameUI.playerDead(gameState.player)){
		  	gameState.lifes -= 1
		  	if (gameState.lifes <= 0){
		  		console.log('game over')
		  		// gameState.firstTimeOnLevel = false
		  		// game.state.start('game_over')
		  	} else {
		  		gameState.firstTimeOnLevel = false
		    	game.state.start('level_intro')
		  	}
		  }

		  if (gameState.groups.aliens.x < 850){
		    if (gameUI.alienScatterEnabled) {
		    	gameUI.scatterAliens()
		    	gameUI.sendBossAlien()
		    }
		  }

		  if (gameState.bossAlien.x < 600 ){
		  	gameUI.bossInGameArea = true
		  	gameState.bossAlien.setAll('body.collideWorldBounds', true)
		  	gameState.bossAlien.body.velocity.x = 100
		  	gameState.bossAlien.body.velocity.y = 100
		  }

		  if (gameState.bossAlien.y > 500 && gameState.bossAlien.x < 900 && gameUI.bossInGameArea){
		  	gameState.bossAlien.body.velocity.x = 100
		  	gameState.bossAlien.body.velocity.y = -100
		  }

		  if (gameState.bossAlien.y < 300 && gameState.bossAlien.x < 900 && gameUI.bossInGameArea){
		  	gameState.bossAlien.body.velocity.x = 10
		  	gameState.bossAlien.body.velocity.y = 10
		  }

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x < 100) {
		  		alien.body.velocity.x = 0}
		  })
  },
  render: function() {
    game.debug.geom(gameUI.gameAreaCeilingLine,'#FFFFFF')
  },
}
<commit_msg>alien boss moves around<commit_after>	function fight() {}

fight.prototype = {
  create: function() {
  	console.log(game.state.current)

  	// Logic to only scatter aliens once, called in fight - update loop
  	gameUI.alienScatterEnabled = true

	  game.physics.startSystem(Phaser.Physics.ARCADE)

	  // scrolling tile sprite
	  starfieldBackground.create(game)

	  // Ceiling visible line and collision detector
	  gameUI.gameAreaCeilingLine = new Phaser.Rectangle(0,200, 1200, 1)
	  gameUI.gameAreaCeiling = game.add.sprite(0,200,null)
	  game.physics.enable(gameUI.gameAreaCeiling, Phaser.Physics.ARCADE)
	  gameUI.gameAreaCeiling.body.setSize(1200, 1, 0, 0)
	  gameUI.gameAreaCeiling.body.immovable = true

	  // rain
	  rain.create(game)

	  // playerBullets
	  playerBullets = gameState.groups.playerBullets = game.add.group()
	  playerBullets.enableBody = true
	  playerBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  playerBullets.createMultiple(250, 'bullet')

	  playerBullets.setAll('anchor.x', 0.5)
	  playerBullets.setAll('anchor.y', 0.5)
	  playerBullets.setAll('damage', 5)

	  bossAlienBullets = gameState.groups.bossAlienBullets = game.add.group()
	  bossAlienBullets.enableBody = true
	  bossAlienBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  bossAlienBullets.createMultiple(250, 'bullet')

	  bossAlienBullets.setAll('anchor.x', 0.5)
	  bossAlienBullets.setAll('anchor.y', 0.5)
	  bossAlienBullets.setAll('damage', 50)

	  // create player object
	  var player = gameState.player = game.add.sprite(32, game.world.height - 150, 'dude')
	  game.physics.arcade.enable(player)
	  player.body.bounce.y = 0.2
	  player.body.collideWorldBounds = true
	  player.health = 100
	  gameUI.upgradeGun(gameState.questionsCorrect)

	  // create explosions
	  var explosions = gameState.groups.explosions = game.add.group()
    explosions.createMultiple(21, 'explosion')
    explosions.forEach(setUpExplosion)

    function setUpExplosion(explode){
    	explode.animations.add('explosion')
    }

	  // create regular aliens
	  aliens = gameState.groups.aliens = game.add.group()
	  aliens.enableBody = true
	  aliens.physicsBodyType = Phaser.Physics.ARCADE

	  // create boss alien
	  bossAlien = gameState.bossAlien = game.add.sprite(1500, 350, 'diamond')
	  game.physics.arcade.enable(bossAlien)
	  bossAlien.enableBody = true
	  bossAlien.physicsBodyType = Phaser.Physics.ARCADE
	  bossAlien.body.bounce.x = .9
	  bossAlien.body.bounce.y = .9
	  var scale = gameUI.alienBossScale(gameState.questionsCorrect)
	  bossAlien.scale.setTo(scale,scale)
	  bossAlien.anchor.x = 0.5
	  bossAlien.anchor.y = 0.5

	  // create keyboard listeners
	  gameState.cursors = game.input.keyboard.createCursorKeys()

	  // create text fields ------------------------------------------------
	  gameUI.scoreObject = game.add.text(
	    32, 32, // x coord, y coord
	    'Score: ' + gameUI.score, // text field
	    {fontSize: '32px', fill: '#ffffff'} // text styling
	    )

	  gameUI.spawnAliens()
  },
  update: function() {
  	 	var player = gameState.player
		  var cursors = gameState.cursors
		  var shootThePlayerGun = false
		  var shootTheBossAlienGun = false

		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(player, gameUI.gameAreaCeiling)
		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.groups.aliens, gameUI.gameAreaCeiling)
		  // boss alien cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens bounce off of each other
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.groups.aliens)
		  // aliens bounce off of boss alien
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.bossAlien)

		  // Bullets cause damage to aliens and then disappear
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.groups.aliens, gameUI.hitAlien , null, this)
		  // Bullets cause the boss alien to shrink
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.bossAlien, gameUI.shrinkBoss , null, this)
		  // Aliens damage the player when they touch
		  game.physics.arcade.overlap(player, gameState.groups.aliens, gameUI.hitPlayer, null, this)
		  // Boss alien bullets damage player
		  game.physics.arcade.overlap(player, gameState.groups.bossAlienBullets, gameUI.hitPlayer, null, this)

		  // set scroll speed of background
		  // starfield.tilePosition.x -= 1
		  starfieldBackground.update()

		    if (cursors.left.isDown) {
		      // player UP
		      player.body.velocity.y = -250;
		      // player.animations.play('up')
		    } else if (cursors.right.isDown){
		      // player DOWN
		      player.body.velocity.y = 250;
		      // player.animations.play('down')
		    } else {
		      // player stand still
		      player.animations.stop()
		      player.frame = 4
		      player.body.velocity.y = 0
		    }

		  // fire!
		  gameUI.firePlayerGunCounter += 1
		  if (gameUI.firePlayerGunCounter >= gameUI.firePlayerGunRate){
		    shootThePlayerGun = true
		    gameUI.firePlayerGunCounter = 0
		  }
		  if (shootThePlayerGun) {
		    gameUI.firePlayerBullet()
		  }

		  gameUI.fireBossAlienGunCounter += 1
		  if (gameUI.fireBossAlienGunCounter >= gameUI.fireBossAlienGunRate){
		    shootTheBossAlienGun = true
		    gameUI.fireBossAlienGunCounter = 0
		  }

		  if (shootTheBossAlienGun && gameState.bossAlien.alive) {
		    gameUI.fireBossAlienBullet()
		  }

		  if (gameUI.aliensDead()) {
		    gameState.currentLevel++
		    gameState.firstTimeOnLevel = true
		    game.state.start('level_intro')
		  }

		  if (gameUI.playerDead(gameState.player)){
		  	gameState.lifes -= 1
		  	if (gameState.lifes <= 0){
		  		console.log('game over')
		  		// gameState.firstTimeOnLevel = false
		  		// game.state.start('game_over')
		  	} else {
		  		gameState.firstTimeOnLevel = false
		    	game.state.start('level_intro')
		  	}
		  }

		  if (gameState.groups.aliens.x < 850){
		    if (gameUI.alienScatterEnabled) {
		    	gameUI.scatterAliens()
		    	gameUI.sendBossAlien()
		    }
		  }

		  if (gameState.bossAlien.x < 800 ){
		  	gameUI.bossInGameArea = true
		  	gameState.bossAlien.body.collideWorldBounds = true
		  	gameState.bossAlien.body.velocity.x = 30
		  	gameState.bossAlien.body.velocity.y = 30
		  }

		  // if (gameState.bossAlien.y > 500 && gameState.bossAlien.x < 900 && gameUI.bossInGameArea){
		  // 	gameState.bossAlien.body.velocity.x = 100
		  // 	gameState.bossAlien.body.velocity.y = -100
		  // }

		  // if (gameState.bossAlien.y < 300 && gameState.bossAlien.x < 900 && gameUI.bossInGameArea){
		  // 	gameState.bossAlien.body.velocity.x = 10
		  // 	gameState.bossAlien.body.velocity.y = 10
		  // }

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x < 100) {
		  		alien.body.velocity.x = 0}
		  })
  },
  render: function() {
    game.debug.geom(gameUI.gameAreaCeilingLine,'#FFFFFF')
  },
}
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2018 Mailvelope GmbH
 * Licensed under the GNU Affero General Public License version 3
 */

import React from 'react';
import PropTypes from 'prop-types';

export default class FormSandbox extends React.Component {
  constructor(props) {
    super(props);
    this.sandbox = null;
    this.form = null;
    this.iframe = null;
    this.files = [];
  }

  shouldComponentUpdate() {
    // create sandbox iframe only once
    return false;
  }

  componentDidMount() {
    this.iframe = document.getElementsByTagName('iframe')[0];
    this.iframe.onload = () => {
      this.resizeIframe();
      this.form = this.iframe.contentDocument.getElementsByTagName('form')[0];

      // Remove all input type submit
      this.removeInputSubmit();

      // Check that form has at least one valid input
      this.checkForEmptyForm();

      // Prevent default behavior on form submit event
      this.form.addEventListener('submit', event => {
        this.onFormSubmit(event);
        event.preventDefault();
        event.stopPropagation();
      });
      // Pressing enter in an input field also triggers a submit
      $(this.form).on('keypress', 'input', event => {
        const code = event.keyCode || event.which;
        if (code === 13) {
          this.onFormSubmit(event);
          event.preventDefault();
          return false;
        }
      });

      // Keyup and focus out can trigger validation and therefore change height
      $(this.form).on('focusout keyup', 'input, textarea, select', () => {
        this.resizeIframe();
      });
    };
  }

  removeInputSubmit() {
    // TODO add ability to remove tags by type using DOMPurify
    $(this.form).find('input[type=submit]').each(function() {
      $(this).remove();
    });
  }

  checkForEmptyForm() {
    // check that there is at least a valid input field to send
    let validInput = 0;
    $(this.form).find('[name]').each(function() {
      const tag = $(this).prop('tagName').toLowerCase();
      if (tag.match(/(input|select|textarea)/g).length) {
        validInput++;
      }
    });
    if (!validInput) {
      this.onError(new Error('There should be at least one input field with name property set.'));
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.needSubmit === true) {
      this.form.dispatchEvent(new Event('submit'));
    }
  }

  resizeIframe() {
    const height = `${this.iframe.contentDocument.body.scrollHeight}px`;
    if (height !== this.iframe.style.height) {
      const offset = 8;
      const newHeight = this.iframe.contentDocument.body.scrollHeight + offset;
      this.iframe.style.height = `${newHeight}px`;
      this.props.onResizeIframe();
    }
  }

  onFormSubmit() {
    if (this.form.checkValidity()) {
      this.getFilesValues().then(() => {
        const data = this.serializeFormData(this.props.formEncoding);
        this.props.onValidated(data);
      });
    }
    this.form.classList.add('was-validated');
    this.resizeIframe();
  }

  onError(error) {
    this.props.onError(error);
  }

  serializeFormData(mode) {
    switch (mode) {
      case 'array': {
        let result = $(this.form).serializeArray();
        if (this.files.length) {
          result = result.concat(this.files);
        }
        return result;
      }
      case 'json':
        return JSON.stringify(this.serializeFormData('array'));
      case 'url':
        return $.param(this.serializeFormData('array'));
      case 'html':
        this.updateFormValues();
        return this.form.outerHTML;
      default:
        throw new Error('This response mode format is not supported.');
    }
  }

  getFilesValues() {
    return new Promise(resolve => {
      const that = this;
      const promises = [];
      $(this.form).find('input[type=file]').each(function() {
        const name = $(this).prop('name');
        if (name !== undefined) {
          for (let i = 0; i < this.files.length; i++) {
            const reader = new FileReader();
            promises.push(new Promise((resolve => {
              reader.addEventListener('load', () => {
                that.files.push({name, 'value': reader.result});
                resolve();
              });
              reader.readAsDataURL(this.files[i]);
            })));
          }
        }
      });
      Promise.all(promises).then(resolve);
    });
  }

  updateFormValues() {
    $(this.form).find('[name]').each(function() {
      switch ($(this).prop('tagName').toLowerCase()) {
        case 'textarea':
          // <textarea>value</textarea>
          $(this).text($(this).val());
          break;
        case 'select':
          // <select><option value='1' selected /></select>
          $(this).find('option').each(function() {
            $(this).attr('selected', $(this).is(':selected'));
          });
          break;
        case 'input': {
          switch ($(this).prop('type').toLowerCase()) {
            case 'radio':
            case 'checkbox':
              // <input type='checkbox|radio' checked=true|false />
              $(this).attr('checked', $(this).is(':checked'));
              break;
            case 'file': {
              // TODO ignore value in this case or reuse values in this.files?
              break;
            }
            default:
              // <input type='text|url|email|etc.' value='val' />
              $(this).attr('value', $(this).val());
              break;
          }
          break;
        }
      }
    });
  }

  render() {
    const sandboxContent = `
      <!DOCTYPE html>

          <meta charset="utf-8">
          <link rel="stylesheet" href="../../dep/bootstrap4/css/bootstrap.css">

         ${this.props.formDefinition}

    `;
    return (
       this.sandbox = node}
        onLoad={() => this.resizeIframe()} />
    );
  }
}

FormSandbox.propTypes = {
  formDefinition: PropTypes.string,
  formEncoding: PropTypes.string,
  needSubmit: PropTypes.bool,
  onTerminate: PropTypes.func,
  onValidated: PropTypes.func,
  onResizeIframe: PropTypes.func,
  onError: PropTypes.func
};

FormSandbox.defaultProps = {
  formEncoding: 'json',
};
<commit_msg>Refactor to use react sandbox refs and onLoad<commit_after>/**
 * Copyright (C) 2018 Mailvelope GmbH
 * Licensed under the GNU Affero General Public License version 3
 */

import React from 'react';
import PropTypes from 'prop-types';

export default class FormSandbox extends React.Component {
  constructor(props) {
    super(props);
    this.sandbox = null;
    this.form = null;
    this.files = [];
  }

  shouldComponentUpdate() {
    // create sandbox iframe only once
    return false;
  }

  removeInputSubmit() {
    // TODO add ability to remove tags by type using DOMPurify
    $(this.form).find('input[type=submit]').each(function() {
      $(this).remove();
    });
  }

  checkForEmptyForm() {
    // check that there is at least a valid input field to send
    let validInput = 0;
    $(this.form).find('[name]').each(function() {
      const tag = $(this).prop('tagName').toLowerCase();
      if (tag.match(/(input|select|textarea)/g).length) {
        validInput++;
      }
    });
    if (!validInput) {
      this.onError(new Error('There should be at least one input field with name property set.'));
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.needSubmit === true) {
      this.form.dispatchEvent(new Event('submit'));
    }
  }

  resizeIframe() {
    const height = `${this.sandbox.contentDocument.body.scrollHeight}px`;
    if (height !== this.sandbox.style.height) {
      const offset = 8;
      const newHeight = this.sandbox.contentDocument.body.scrollHeight + offset;
      this.sandbox.style.height = `${newHeight}px`;
      this.props.onResizeIframe();
    }
  }

  onFormSubmit() {
    if (this.form.checkValidity()) {
      this.getFilesValues().then(() => {
        const data = this.serializeFormData(this.props.formEncoding);
        this.props.onValidated(data);
      });
    }
    this.form.classList.add('was-validated');
    this.resizeIframe();
  }

  onError(error) {
    this.props.onError(error);
  }

  onIframeLoad() {
    this.resizeIframe();
    this.form = this.sandbox.contentDocument.getElementsByTagName('form')[0];

    // Remove all input type submit
    this.removeInputSubmit();

    // Check that form has at least one valid input
    this.checkForEmptyForm();

    // Prevent default behavior on form submit event
    this.form.addEventListener('submit', event => {
      this.onFormSubmit(event);
      event.preventDefault();
      event.stopPropagation();
    });
    // Pressing enter in an input field also triggers a submit
    $(this.form).on('keypress', 'input', event => {
      const code = event.keyCode || event.which;
      if (code === 13) {
        this.onFormSubmit(event);
        event.preventDefault();
        return false;
      }
    });

    // Keyup and focus out can trigger validation and therefore change height
    $(this.form).on('focusout keyup', 'input, textarea, select', () => {
      this.resizeIframe();
    });
  }

  serializeFormData(mode) {
    switch (mode) {
      case 'array': {
        let result = $(this.form).serializeArray();
        if (this.files.length) {
          result = result.concat(this.files);
        }
        return result;
      }
      case 'json':
        return JSON.stringify(this.serializeFormData('array'));
      case 'url':
        return $.param(this.serializeFormData('array'));
      case 'html':
        this.updateFormValues();
        return this.form.outerHTML;
      default:
        throw new Error('This response mode format is not supported.');
    }
  }

  getFilesValues() {
    return new Promise(resolve => {
      const that = this;
      const promises = [];
      $(this.form).find('input[type=file]').each(function() {
        const name = $(this).prop('name');
        if (name !== undefined) {
          for (let i = 0; i < this.files.length; i++) {
            const reader = new FileReader();
            promises.push(new Promise((resolve => {
              reader.addEventListener('load', () => {
                that.files.push({name, 'value': reader.result});
                resolve();
              });
              reader.readAsDataURL(this.files[i]);
            })));
          }
        }
      });
      Promise.all(promises).then(resolve);
    });
  }

  updateFormValues() {
    $(this.form).find('[name]').each(function() {
      switch ($(this).prop('tagName').toLowerCase()) {
        case 'textarea':
          // <textarea>value</textarea>
          $(this).text($(this).val());
          break;
        case 'select':
          // <select><option value='1' selected /></select>
          $(this).find('option').each(function() {
            $(this).attr('selected', $(this).is(':selected'));
          });
          break;
        case 'input': {
          switch ($(this).prop('type').toLowerCase()) {
            case 'radio':
            case 'checkbox':
              // <input type='checkbox|radio' checked=true|false />
              $(this).attr('checked', $(this).is(':checked'));
              break;
            case 'file': {
              // TODO ignore value in this case or reuse values in this.files?
              break;
            }
            default:
              // <input type='text|url|email|etc.' value='val' />
              $(this).attr('value', $(this).val());
              break;
          }
          break;
        }
      }
    });
  }

  render() {
    const sandboxContent = `
      <!DOCTYPE html>

          <meta charset="utf-8">
          <link rel="stylesheet" href="../../dep/bootstrap4/css/bootstrap.css">

         ${this.props.formDefinition}

    `;
    return (
       this.sandbox = node}
        onLoad={() => this.onIframeLoad()} />
    );
  }
}

FormSandbox.propTypes = {
  formDefinition: PropTypes.string,
  formEncoding: PropTypes.string,
  needSubmit: PropTypes.bool,
  onTerminate: PropTypes.func,
  onValidated: PropTypes.func,
  onResizeIframe: PropTypes.func,
  onError: PropTypes.func
};

FormSandbox.defaultProps = {
  formEncoding: 'json',
};
<|endoftext|>


<commit_before>'use strict';

const	freeport	= require('freeport'),
	//request	= require('requestretry'),
	async	= require('async'),
	test	= require('tape'),
	//App	= require(__dirname + '/../index.js'),
	db	= require('larvitdb');

if ( ! process.env.DBCONFFILE) {
	process.env.DBCONFFILE	= 'config/db_test.json';
}

db.setup(require(__dirname + '/../' + process.env.DBCONFFILE));

test('Basic request', function (t) {
	const	tasks	= [];

	// Get free port
	tasks.push(function (cb) {
		freeport(function (err, result) {
			port	= result;
			cb(err);
		});
	});

	async.series(tasks, function (err) {
		if (err) throw err;
		t.end();
	});
});<commit_msg>Minor console log just to push travis tests<commit_after>'use strict';

const	freeport	= require('freeport'),
	//request	= require('requestretry'),
	async	= require('async'),
	test	= require('tape'),
	//App	= require(__dirname + '/../index.js'),
	db	= require('larvitdb');

if ( ! process.env.DBCONFFILE) {
	process.env.DBCONFFILE	= 'config/db_test.json';
}

db.setup(require(__dirname + '/../' + process.env.DBCONFFILE));

test('Basic request', function (t) {
	const	tasks	= [];

	// Get free port
	tasks.push(function (cb) {
		freeport(function (err, result) {
			port	= result;
			console.log(port);
			cb(err);
		});
	});

	async.series(tasks, function (err) {
		if (err) throw err;
		t.end();
	});
});<|endoftext|>