<commit_before>import React from 'react'
import '../assets/stylesheets/application.css';
import { Link } from 'react-router-dom'
import { defaultState } from '../utils/constants'
import { setFlatFileContentToState } from '../utils/utils';
import { getOldState } from '../utils/utils'
import { StepNavigation } from './Common/StepNavigation'
import { NAVIGATION_STEPS } from '../utils/constants'
const { CROWDSALE_CONTRACT, TOKEN_SETUP, CROWDSALE_SETUP, PUBLISH, CROWDSALE_PAGE } = NAVIGATION_STEPS

export class stepOne extends React.Component {
  constructor(props) {
    super(props);
    let oldState = getOldState(props, defaultState)
    this.state = Object.assign({}, oldState)
  }

  getStandardCrowdsaleAssets (state) {
    const contractName = "CrowdsaleStandard";
    let srcC, binC
    setFlatFileContentToState("./contracts/" + contractName + "_flat.sol", (content) => srcC = content);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.bin", (_bin) => binC = _bin);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.abi", (_abi) => this.addContractsToState(srcC, binC, _abi, "crowdsale", state));

    const tokenName = "CrowdsaleStandardToken";
    let srcT, binT
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.sol", (content) => srcT = content);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.bin", (_bin) => binT = _bin);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.abi", (_abi) => this.addContractsToState(srcT, binT, _abi, "token", state));
  }

  getWhiteListWithCapCrowdsaleAssets (state) {
    const contractName = "CrowdsaleWhiteListWithCap";
    let srcC, binC
    setFlatFileContentToState("./contracts/" + contractName + "_flat.sol", (content) => srcC = content);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.bin", (_bin) => binC = _bin);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.abi", (_abi) => this.addContractsToState(srcC, binC, _abi, "crowdsale", state));

    const tokenName = "CrowdsaleWhiteListWithCapToken";
    let srcT, binT
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.sol", (content) => srcT = content);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.bin", (_bin) => binT = _bin);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.abi", (_abi) => this.addContractsToState(srcT, binT, _abi, "token", state));

    const pricingStrategyName = "CrowdsaleWhiteListWithCapPricingStrategy";
    let srcP, binP
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.sol", (content) => srcP = content);
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.bin", (_bin) => binP = _bin);
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.abi", (_abi) => this.addContractsToState(srcP, binP, _abi, "pricingStrategy", state));

    const tokenTransferProxyName = "TokenTransferProxy";
    let srcTTP, binTTP
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.sol", (content) => srcTTP = content);
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.bin", (_bin) => binTTP = _bin);
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.abi", (_abi) => this.addContractsToState(srcTTP, binTTP, _abi, "tokenTransferProxy", state));

    const multiSigName = "MultiSig";
    let srcM, binM
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.sol", (content) => srcM = content);
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.bin", (_bin) => binM = _bin);
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.abi", (_abi) => this.addContractsToState(srcM, binM, _abi, "multisig", state));

    const finalizeAgentName = "FinalizeAgent";
    let srcF, binF
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.sol", (content) => srcF = content);
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.bin", (_bin) => binF = _bin);
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.abi", (_abi) => this.addContractsToState(srcF, binF, _abi, "finalizeAgent", state));

    const nullFinalizeAgentName = "NullFinalizeAgent";
    let srcNF, binNF
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.sol", (content) => srcNF = content);
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.bin", (_bin) => binNF = _bin);
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.abi", (_abi) => this.addContractsToState(srcNF, binNF, _abi, "nullFinalizeAgent", state));
  }

  componentDidMount() {
    let newState = { ...this.state }
    newState.contractType = this.state.contractTypes.standard
    this.getStandardCrowdsaleAssets(newState);
  }

  addContractsToState (src, bin, abi, contract, state) {
    //let newState = Object.assign({}, state)
    console.log('state', state)
    state.contracts[contract] = {
      src,
      bin,
      abi: JSON.parse(abi),
      addr: (contract=="crowdsale" || contract=="pricingStrategy" || contract=="finalizeAgent")?[]:"",
      abiConstructor: (contract=="crowdsale" || contract=="pricingStrategy" || contract=="finalizeAgent")?[]:""
    }
    this.setState(state)
  }

  contractTypeSelected(e) {
    let newState = { ...this.state }
    newState.contractType = e.currentTarget.id;
    console.log(e.currentTarget.id);
    switch (e.currentTarget.id) {
      case this.state.contractTypes.standard: {
        this.getStandardCrowdsaleAssets(newState);
      } break;
      case this.state.contractTypes.whitelistwithcap: {
        this.getWhiteListWithCapCrowdsaleAssets(newState);
      } break;
      default:
        break;
    }
  }

  render() {
    return (

       <StepNavigation activeStep={CROWDSALE_CONTRACT}/>

Crowdsale Contract

              Select a strategy for you crowdsale contract.

              <input
                type="radio"
                checked={this.state.contractType === this.state.contractTypes.standard}
                name="contract-type"
                id={this.state.contractTypes.standard}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Standard

                Standard crowdsale for educational use.

              <input
                type="radio"
                checked={this.state.contractType === this.state.contractTypes.whitelistwithcap}
                name="contract-type"
                id={this.state.contractTypes.whitelistwithcap}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Whitelist with Cap

                Modern crowdsale strategy with tiers, whitelists, and limits.

            {/*
              <input
                type="radio"
                disabled
                checked={this.state.contractType === this.state.contractTypes.capped}
                name="contract-type"
                id={this.state.contractTypes.whitelistwithcap}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Capped

                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
                quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

             */}

          <Link to={{ pathname: '/2', query: { state: this.state } }}>Continue</Link>

    )}
}
<commit_msg>added info to README.md<commit_after>import React from 'react'
import '../assets/stylesheets/application.css';
import { Link } from 'react-router-dom'
import { defaultState } from '../utils/constants'
import { setFlatFileContentToState } from '../utils/utils';
import { getOldState } from '../utils/utils'
import { StepNavigation } from './Common/StepNavigation'
import { NAVIGATION_STEPS } from '../utils/constants'
const { CROWDSALE_CONTRACT, TOKEN_SETUP, CROWDSALE_SETUP, PUBLISH, CROWDSALE_PAGE } = NAVIGATION_STEPS

export class stepOne extends React.Component {
  constructor(props) {
    super(props);
    let oldState = getOldState(props, defaultState)
    this.state = Object.assign({}, oldState)
  }

  getStandardCrowdsaleAssets (state) {
    const contractName = "CrowdsaleStandard";
    let srcC, binC
    setFlatFileContentToState("./contracts/" + contractName + "_flat.sol", (content) => srcC = content);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.bin", (_bin) => binC = _bin);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.abi", (_abi) => this.addContractsToState(srcC, binC, _abi, "crowdsale", state));

    const tokenName = "CrowdsaleStandardToken";
    let srcT, binT
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.sol", (content) => srcT = content);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.bin", (_bin) => binT = _bin);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.abi", (_abi) => this.addContractsToState(srcT, binT, _abi, "token", state));
  }

  getWhiteListWithCapCrowdsaleAssets (state) {
    const contractName = "CrowdsaleWhiteListWithCap";
    let srcC, binC
    setFlatFileContentToState("./contracts/" + contractName + "_flat.sol", (content) => srcC = content);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.bin", (_bin) => binC = _bin);
    setFlatFileContentToState("./contracts/" + contractName + "_flat.abi", (_abi) => this.addContractsToState(srcC, binC, _abi, "crowdsale", state));

    const tokenName = "CrowdsaleWhiteListWithCapToken";
    let srcT, binT
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.sol", (content) => srcT = content);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.bin", (_bin) => binT = _bin);
    setFlatFileContentToState("./contracts/" + tokenName + "_flat.abi", (_abi) => this.addContractsToState(srcT, binT, _abi, "token", state));

    const pricingStrategyName = "CrowdsaleWhiteListWithCapPricingStrategy";
    let srcP, binP
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.sol", (content) => srcP = content);
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.bin", (_bin) => binP = _bin);
    setFlatFileContentToState("./contracts/" + pricingStrategyName + "_flat.abi", (_abi) => this.addContractsToState(srcP, binP, _abi, "pricingStrategy", state));

    const tokenTransferProxyName = "TokenTransferProxy";
    let srcTTP, binTTP
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.sol", (content) => srcTTP = content);
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.bin", (_bin) => binTTP = _bin);
    setFlatFileContentToState("./contracts/" + tokenTransferProxyName + "_flat.abi", (_abi) => this.addContractsToState(srcTTP, binTTP, _abi, "tokenTransferProxy", state));

    const multiSigName = "MultiSig";
    let srcM, binM
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.sol", (content) => srcM = content);
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.bin", (_bin) => binM = _bin);
    setFlatFileContentToState("./contracts/" + multiSigName + "_flat.abi", (_abi) => this.addContractsToState(srcM, binM, _abi, "multisig", state));

    const finalizeAgentName = "FinalizeAgent";
    let srcF, binF
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.sol", (content) => srcF = content);
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.bin", (_bin) => binF = _bin);
    setFlatFileContentToState("./contracts/" + finalizeAgentName + "_flat.abi", (_abi) => this.addContractsToState(srcF, binF, _abi, "finalizeAgent", state));

    const nullFinalizeAgentName = "NullFinalizeAgent";
    let srcNF, binNF
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.sol", (content) => srcNF = content);
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.bin", (_bin) => binNF = _bin);
    setFlatFileContentToState("./contracts/" + nullFinalizeAgentName + "_flat.abi", (_abi) => this.addContractsToState(srcNF, binNF, _abi, "nullFinalizeAgent", state));
  }

  componentDidMount() {
    let newState = { ...this.state }
    newState.contractType = this.state.contractTypes.standard
    this.getStandardCrowdsaleAssets(newState);
  }

  addContractsToState (src, bin, abi, contract, state) {
    //let newState = Object.assign({}, state)
    console.log('state', state)
    state.contracts[contract] = {
      src,
      bin,
      abi: JSON.parse(abi),
      addr: (contract=="crowdsale" || contract=="pricingStrategy" || contract=="finalizeAgent")?[]:"",
      abiConstructor: (contract=="crowdsale" || contract=="pricingStrategy" || contract=="finalizeAgent")?[]:""
    }
    this.setState(state)
  }

  contractTypeSelected(e) {
    let newState = { ...this.state }
    newState.contractType = e.currentTarget.id;
    console.log(e.currentTarget.id);
    switch (e.currentTarget.id) {
      case this.state.contractTypes.standard: {
        this.getStandardCrowdsaleAssets(newState);
      } break;
      case this.state.contractTypes.whitelistwithcap: {
        this.getWhiteListWithCapCrowdsaleAssets(newState);
      } break;
      default:
        break;
    }
  }

  render() {
    return (

       <StepNavigation activeStep={CROWDSALE_CONTRACT}/>

Crowdsale Contract

              Select a strategy for your crowdsale contract.

              <input
                type="radio"
                checked={this.state.contractType === this.state.contractTypes.standard}
                name="contract-type"
                id={this.state.contractTypes.standard}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Standard

                Standard crowdsale for educational use.

              <input
                type="radio"
                checked={this.state.contractType === this.state.contractTypes.whitelistwithcap}
                name="contract-type"
                id={this.state.contractTypes.whitelistwithcap}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Whitelist with Cap

                Modern crowdsale strategy with tiers, whitelists, and limits.

            {/*
              <input
                type="radio"
                disabled
                checked={this.state.contractType === this.state.contractTypes.capped}
                name="contract-type"
                id={this.state.contractTypes.whitelistwithcap}
                onChange={(e) => this.contractTypeSelected(e)}
              />
              Capped

                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
                quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

             */}

          <Link to={{ pathname: '/2', query: { state: this.state } }}>Continue</Link>

    )}
}
<|endoftext|>


<commit_before>'use strict';

describe('timeslider', function () {
  // create a new pad before each test run
  beforeEach(async function () {
    this.timeout(60000);
    await helper.aNewPad();
  });

  it('loads adds a hundred revisions', async function () {
    this.timeout(100000);
    const chrome$ = helper.padChrome$;

    // Create a bunch of revisions.
    for (let i = 0; i < 99; i++) await helper.edit('a');
    chrome$('.buttonicon-savedRevision').click();

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider`);

    await new Promise((resolve) => setTimeout(resolve, 6000));

    const timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
    const $sliderBar = timeslider$('#ui-slider-bar');

    const latestContents = timeslider$('#innerdocbody').text();

    // Click somewhere on the timeslider
    let e = new jQuery.Event('mousedown');
    // sets y co-ordinate of the pad slider modal.
    const base = (timeslider$('#ui-slider-bar').offset().top - 24);
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base + 5;
    $sliderBar.trigger(e);

    e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base;
    $sliderBar.trigger(e);

    e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base - 5;
    $sliderBar.trigger(e);

    $sliderBar.trigger('mouseup');

    await new Promise((resolve) => setTimeout(resolve, 1000));

    // make sure the text has changed
    expect(timeslider$('#innerdocbody').text()).not.to.eql(latestContents);
    const starIsVisible = timeslider$('.star').is(':visible');
    expect(starIsVisible).to.eql(true);
  });

  // Disabled as jquery trigger no longer works properly
  xit('changes the url when clicking on the timeslider', async function () {
    // Create some revisions.
    for (let i = 0; i < 20; i++) await helper.edit('a');

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider`);

    await new Promise((resolve) => setTimeout(resolve, 6000));

    const timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
    const $sliderBar = timeslider$('#ui-slider-bar');

    const oldUrl = $('#iframe-container iframe')[0].contentWindow.location.hash;

    // Click somewhere on the timeslider
    const e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = 60;
    $sliderBar.trigger(e);

    await helper.waitForPromise(
        () => $('#iframe-container iframe')[0].contentWindow.location.hash !== oldUrl, 6000);
  });

  it('jumps to a revision given in the url', async function () {
    const inner$ = helper.padInner$;
    this.timeout(40000);

    // wait for the text to be loaded
    await helper.waitForPromise(() => inner$('body').text().length !== 0, 10000);

    const newLines = inner$('body div').length;
    const oldLength = inner$('body').text().length + newLines / 2;
    expect(oldLength).to.not.eql(0);
    inner$('div').first().sendkeys('a');
    let timeslider$;

    // wait for our additional revision to be added
    await helper.waitForPromise(() => {
      // newLines takes the new lines into account which are strippen when using
      // inner$('body').text(), one <div> is used for one line in ACE.
      const lenOkay = inner$('body').text().length + newLines / 2 !== oldLength;
      // this waits for the color to be added to our <span>, which means that the revision
      // was accepted by the server.
      const colorOkay = inner$('span').first().attr('class').indexOf('author-') === 0;
      return lenOkay && colorOkay;
    }, 10000);

    // go to timeslider with a specific revision set
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider#0`);

    // wait for the timeslider to be loaded
    await helper.waitForPromise(() => {
      try {
        timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
      } catch (e) {
        // Empty catch block <3
      }
      return timeslider$ && timeslider$('#innerdocbody').text().length === oldLength;
    }, 10000);
  });

  it('checks the export url', async function () {
    const inner$ = helper.padInner$;
    this.timeout(11000);
    inner$('div').first().sendkeys('a');

    await new Promise((resolve) => setTimeout(resolve, 2500));

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider#0`);
    let timeslider$;
    let exportLink;

    await helper.waitForPromise(() => {
      try {
        timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
      } catch (e) {
        // Empty catch block <3
      }
      if (!timeslider$) return false;
      exportLink = timeslider$('#exportplaina').attr('href');
      if (!exportLink) return false;
      return exportLink.substr(exportLink.length - 12) === '0/export/txt';
    }, 6000);
  });
});
<commit_msg>tests: Fix race in `timeslider_revisions.js`<commit_after>'use strict';

describe('timeslider', function () {
  // create a new pad before each test run
  beforeEach(async function () {
    this.timeout(60000);
    await helper.aNewPad();
  });

  it('loads adds a hundred revisions', async function () {
    this.timeout(100000);
    const chrome$ = helper.padChrome$;

    // Create a bunch of revisions.
    for (let i = 0; i < 99; i++) await helper.edit('a');
    chrome$('.buttonicon-savedRevision').click();
    await helper.waitForPromise(() => helper.padChrome$('.saved-revision').length > 0);
    // Give some time to send the SAVE_REVISION message to the server before navigating away.
    await new Promise((resolve) => setTimeout(resolve, 100));

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider`);

    await new Promise((resolve) => setTimeout(resolve, 6000));

    const timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
    const $sliderBar = timeslider$('#ui-slider-bar');

    const latestContents = timeslider$('#innerdocbody').text();

    // Click somewhere on the timeslider
    let e = new jQuery.Event('mousedown');
    // sets y co-ordinate of the pad slider modal.
    const base = (timeslider$('#ui-slider-bar').offset().top - 24);
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base + 5;
    $sliderBar.trigger(e);

    e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base;
    $sliderBar.trigger(e);

    e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = base - 5;
    $sliderBar.trigger(e);

    $sliderBar.trigger('mouseup');

    await new Promise((resolve) => setTimeout(resolve, 1000));

    // make sure the text has changed
    expect(timeslider$('#innerdocbody').text()).not.to.eql(latestContents);
    const starIsVisible = timeslider$('.star').is(':visible');
    expect(starIsVisible).to.eql(true);
  });

  // Disabled as jquery trigger no longer works properly
  xit('changes the url when clicking on the timeslider', async function () {
    // Create some revisions.
    for (let i = 0; i < 20; i++) await helper.edit('a');

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider`);

    await new Promise((resolve) => setTimeout(resolve, 6000));

    const timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
    const $sliderBar = timeslider$('#ui-slider-bar');

    const oldUrl = $('#iframe-container iframe')[0].contentWindow.location.hash;

    // Click somewhere on the timeslider
    const e = new jQuery.Event('mousedown');
    e.clientX = e.pageX = 150;
    e.clientY = e.pageY = 60;
    $sliderBar.trigger(e);

    await helper.waitForPromise(
        () => $('#iframe-container iframe')[0].contentWindow.location.hash !== oldUrl, 6000);
  });

  it('jumps to a revision given in the url', async function () {
    const inner$ = helper.padInner$;
    this.timeout(40000);

    // wait for the text to be loaded
    await helper.waitForPromise(() => inner$('body').text().length !== 0, 10000);

    const newLines = inner$('body div').length;
    const oldLength = inner$('body').text().length + newLines / 2;
    expect(oldLength).to.not.eql(0);
    inner$('div').first().sendkeys('a');
    let timeslider$;

    // wait for our additional revision to be added
    await helper.waitForPromise(() => {
      // newLines takes the new lines into account which are strippen when using
      // inner$('body').text(), one <div> is used for one line in ACE.
      const lenOkay = inner$('body').text().length + newLines / 2 !== oldLength;
      // this waits for the color to be added to our <span>, which means that the revision
      // was accepted by the server.
      const colorOkay = inner$('span').first().attr('class').indexOf('author-') === 0;
      return lenOkay && colorOkay;
    }, 10000);

    // go to timeslider with a specific revision set
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider#0`);

    // wait for the timeslider to be loaded
    await helper.waitForPromise(() => {
      try {
        timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
      } catch (e) {
        // Empty catch block <3
      }
      return timeslider$ && timeslider$('#innerdocbody').text().length === oldLength;
    }, 10000);
  });

  it('checks the export url', async function () {
    const inner$ = helper.padInner$;
    this.timeout(11000);
    inner$('div').first().sendkeys('a');

    await new Promise((resolve) => setTimeout(resolve, 2500));

    // go to timeslider
    $('#iframe-container iframe')
        .attr('src', `${$('#iframe-container iframe').attr('src')}/timeslider#0`);
    let timeslider$;
    let exportLink;

    await helper.waitForPromise(() => {
      try {
        timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
      } catch (e) {
        // Empty catch block <3
      }
      if (!timeslider$) return false;
      exportLink = timeslider$('#exportplaina').attr('href');
      if (!exportLink) return false;
      return exportLink.substr(exportLink.length - 12) === '0/export/txt';
    }, 6000);
  });
});
<|endoftext|>


<commit_before>//Note that Javascript does not have Liquid template syntax.
//I am actually curious to see if Javascript can even run.

//Hover over the image to start GIF animation.
$(document).ready(function(){
	//ID uses #.
	//Marble Run
	$("#project001").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_marble_run.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_marble_run.png");
         }
 	);
 	//Pixavive Survival
 	$("#project002").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_pixavive.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_pixavive.png");
         }
 	);
 	//Pokemon Walking
 	$("#project003").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_walking.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_walking.png");
         }
 	);
 	//Bluetooth
 	$("#project004").hover(
         //This function is mouseOver. GIF goes here.
         //Note that due to the nature of the project, there is no GIF available.
         function(){
         	$(this).attr("src", "../assets/proj_bluetooth.png");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_bluetooth.png");
         }
 	);
   //Rotation
   $("#project011").hover(
         //This function is mouseOver. GIF goes here.
         //Note that due to the nature of the project, there is no GIF available.
         function(){
            $(this).attr("src", "../assets/proj_rotation.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
            $(this).attr("src", "../assets/proj_rotation.png");
         }
   );
});<commit_msg>Update animateProjectImage.js<commit_after>//Note that Javascript does not have Liquid template syntax.
//I am actually curious to see if Javascript can even run.

//Hover over the image to start GIF animation.
$(document).ready(function(){
	//ID uses #.
	//Marble Run
	$("#project001").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_marble_run.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_marble_run.png");
         }
 	);
 	//Pixavive Survival
 	$("#project002").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_pixavive.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_pixavive.png");
         }
 	);
 	//Pokemon Walking
 	$("#project003").hover(
         //This function is mouseOver. GIF goes here.
         function(){
         	$(this).attr("src", "../assets/proj_walking.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_walking.png");
         }
 	);
 	//Bluetooth
 	$("#project004").hover(
         //This function is mouseOver. GIF goes here.
         //Note that due to the nature of the project, there is no GIF available.
         function(){
         	$(this).attr("src", "../assets/proj_bluetooth.png");
         },
         //This function is mouseOut. Static image goes here.
         function(){
         	$(this).attr("src", "../assets/proj_bluetooth.png");
         }
 	);
   	//Rotation
   	$("#project011").hover(
         //This function is mouseOver. GIF goes here.
         //Note that due to the nature of the project, there is no GIF available.
         function(){
            $(this).attr("src", "../assets/proj_rotation.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
            $(this).attr("src", "../assets/proj_rotation.png");
         }
        $("#project012").hover(
         //This function is mouseOver. GIF goes here.
         //Note that due to the nature of the project, there is no GIF available.
         function(){
            $(this).attr("src", "../assets/proj_getdebt.gif");
         },
         //This function is mouseOut. Static image goes here.
         function(){
            $(this).attr("src", "../assets/proj_getdebt.png");
         }
   );
});
<|endoftext|>


<commit_before>var _ = require('lodash'),
    xml = require('xmlbuilder'),

    util = require('../../util'),
    JunitReporter;

/**
 * A function that creates raw XML to be written to Newman JUnit reports.
 *
 * @param {Object} newman - The collection run object, with a event handler setter, used to enable event wise reporting.
 * @param {Object} reporterOptions - A set of JUnit reporter run options.
 * @param {String=} reporterOptions.export - Optional custom path to create the XML report at.
 * @returns {*}
 */
JunitReporter = function (newman, reporterOptions, options) {
    var _options = options;

    newman.on('beforeDone', function () {
        var report = _.get(newman, 'summary.run.executions'),
            collection = _.get(newman, 'summary.collection'),
            cache,
            root,
            testSuitesExecutionTime = 0,
            executionTime = 0;

        if (!report) {
            return;
        }

        root = xml.create('testsuites', { version: '1.0', encoding: 'UTF-8' });
        root.att('name', collection.name);
        root.att('tests', _.get(newman, 'summary.run.stats.tests.total', 'unknown'));

        cache = _.transform(report, function (accumulator, execution) {
            accumulator[execution.id] = accumulator[execution.id] || [];
            accumulator[execution.id].push(execution);
        }, {});

        var startedUnix = _.get(newman, 'summary.run.timings.started');
        var date = new Date(startedUnix);
        var timestamp = date.toISOString();

        _.forEach(cache, function (executions, itemId) {
            var suite = root.ele('testsuite'),
                currentItem,
                tests = {},
                errors = 0,
                failures = 0,
                errorMessages;

            collection.forEachItem(function (item) {
                (item.id === itemId) && (currentItem = item);
            });

            if (!currentItem) { return; }

            suite.att('name', util.getFullName(currentItem));
            suite.att('id', currentItem.id);

            suite.att('timestamp', timestamp);

            suite.att('classname', _.get(suite, 'attributes.name.value', 'JUnitXmlReporter.constructor'));

            _.forEach(executions, function (execution) {
                var iteration = execution.cursor.iteration,
                    errored,
                    msg = `Iteration: ${iteration}\n`;

                // Process errors
                if (execution.requestError) {
                    ++errors;
                    errored = true;
                    msg += ('RequestError: ' + (execution.requestError.stack) + '\n');
                }
                msg += '\n---\n';
                _.forEach(['testScript', 'prerequestScript'], function (prop) {
                    _.forEach(execution[prop], function (err) {
                        if (err.error) {
                            ++errors;
                            errored = true;
                            msg = (msg + prop + 'Error: ' + (err.error.stack || err.error.message));
                            msg += '\n---\n';
                        }
                    });
                });

                if (errored) {
                    errorMessages = _.isString(errorMessages) ? (errorMessages + msg) : msg;
                }

                // Process assertions
                _.forEach(execution.assertions, function (assertion) {
                    var name = assertion.assertion,
                        err = assertion.error;

                    if (err) {
                        ++failures;
                        (_.isArray(tests[name]) ? tests[name].push(err) : (tests[name] = [err]));
                    }
                    else {
                        tests[name] = [];
                    }
                });
                if (execution.assertions) {
                    suite.att('tests', execution.assertions.length);
                }
                else {
                    suite.att('tests', 0);
                }

                suite.att('failures', failures);
                suite.att('errors', errors);
            });

            suite.att('time', _.mean(_.map(executions, function (execution) {
                executionTime = _.get(execution, 'response.responseTime') / 1000 || 0;
                testSuitesExecutionTime += executionTime;

                return executionTime;
            })).toFixed(3));
            errorMessages && suite.ele('error').dat(errorMessages);

            _.forOwn(tests, function (failures, name) {
                var testcase = suite.ele('testcase'),
                    failure;

                testcase.att('name', name);
                testcase.att('time', executionTime.toFixed(3));
                if (failures && failures.length) {
                    testcase.att('classname', _.get(testcase.up(), 'attributes.name.value',
                        'JUnitXmlReporter.constructor'));

                    failure = testcase.ele('failure');
                    failure.att('type', 'AssertionFailure');
                    failure.dat('Failed ' + failures.length + ' times.');
                    failure.dat('Collection JSON ID: ' + collection.id + '.');
                    failure.dat('Collection name: ' + collection.name + '.');
                    failure.dat('Request name: ' + util.getFullName(currentItem) + '.');
                    failure.dat('Test description: ' + name + '.');
                    if (failures.length !== 0) {
                        failure.att('message', failures[0].message);
                        failure.dat('Error message: ' + failures[0].message + '.');
                        failure.dat('Stacktrace: ' + failures[0].stack + '.');
                    }
                }
            });
        });

        root.att('time', testSuitesExecutionTime.toFixed(3));
        newman.exports.push({
            name: 'junit-reporter',
            default: 'newman-run-report.xml',
            path: reporterOptions.export,
            content: root.end({
                pretty: true,
                indent: '  ',
                newline: '\n',
                allowEmpty: false
            })
        });
    });
};

module.exports = JunitReporter;
<commit_msg>Resolve linting errors<commit_after>var _ = require('lodash'),
    xml = require('xmlbuilder'),

    util = require('../../util'),
    JunitReporter;

/**
 * A function that creates raw XML to be written to Newman JUnit reports.
 *
 * @param {Object} newman - The collection run object, with a event handler setter, used to enable event wise reporting.
 * @param {Object} reporterOptions - A set of JUnit reporter run options.
 * @param {String=} reporterOptions.export - Optional custom path to create the XML report at.
 * @returns {*}
 */
JunitReporter = function (newman, reporterOptions) {
    newman.on('beforeDone', function () {
        var report = _.get(newman, 'summary.run.executions'),
            collection = _.get(newman, 'summary.collection'),
            cache,
            root,
            testSuitesExecutionTime = 0,
            executionTime = 0,
            date,
            timestamp;

        if (!report) {
            return;
        }

        root = xml.create('testsuites', { version: '1.0', encoding: 'UTF-8' });
        root.att('name', collection.name);
        root.att('tests', _.get(newman, 'summary.run.stats.tests.total', 'unknown'));

        cache = _.transform(report, function (accumulator, execution) {
            accumulator[execution.id] = accumulator[execution.id] || [];
            accumulator[execution.id].push(execution);
        }, {});

        date = new Date(_.get(newman, 'summary.run.timings.started'));
        timestamp = date.toISOString();

        _.forEach(cache, function (executions, itemId) {
            var suite = root.ele('testsuite'),
                currentItem,
                tests = {},
                errors = 0,
                failures = 0,
                errorMessages;

            collection.forEachItem(function (item) {
                (item.id === itemId) && (currentItem = item);
            });

            if (!currentItem) { return; }

            suite.att('name', util.getFullName(currentItem));
            suite.att('id', currentItem.id);

            suite.att('timestamp', timestamp);

            suite.att('classname', _.get(suite, 'attributes.name.value', 'JUnitXmlReporter.constructor'));

            _.forEach(executions, function (execution) {
                var iteration = execution.cursor.iteration,
                    errored,
                    msg = `Iteration: ${iteration}\n`;

                // Process errors
                if (execution.requestError) {
                    ++errors;
                    errored = true;
                    msg += ('RequestError: ' + (execution.requestError.stack) + '\n');
                }
                msg += '\n---\n';
                _.forEach(['testScript', 'prerequestScript'], function (prop) {
                    _.forEach(execution[prop], function (err) {
                        if (err.error) {
                            ++errors;
                            errored = true;
                            msg = (msg + prop + 'Error: ' + (err.error.stack || err.error.message));
                            msg += '\n---\n';
                        }
                    });
                });

                if (errored) {
                    errorMessages = _.isString(errorMessages) ? (errorMessages + msg) : msg;
                }

                // Process assertions
                _.forEach(execution.assertions, function (assertion) {
                    var name = assertion.assertion,
                        err = assertion.error;

                    if (err) {
                        ++failures;
                        (_.isArray(tests[name]) ? tests[name].push(err) : (tests[name] = [err]));
                    }
                    else {
                        tests[name] = [];
                    }
                });
                if (execution.assertions) {
                    suite.att('tests', execution.assertions.length);
                }
                else {
                    suite.att('tests', 0);
                }

                suite.att('failures', failures);
                suite.att('errors', errors);
            });

            suite.att('time', _.mean(_.map(executions, function (execution) {
                executionTime = _.get(execution, 'response.responseTime') / 1000 || 0;
                testSuitesExecutionTime += executionTime;

                return executionTime;
            })).toFixed(3));
            errorMessages && suite.ele('error').dat(errorMessages);

            _.forOwn(tests, function (failures, name) {
                var testcase = suite.ele('testcase'),
                    failure;

                testcase.att('name', name);
                testcase.att('time', executionTime.toFixed(3));
                if (failures && failures.length) {
                    testcase.att('classname', _.get(testcase.up(), 'attributes.name.value',
                        'JUnitXmlReporter.constructor'));

                    failure = testcase.ele('failure');
                    failure.att('type', 'AssertionFailure');
                    failure.dat('Failed ' + failures.length + ' times.');
                    failure.dat('Collection JSON ID: ' + collection.id + '.');
                    failure.dat('Collection name: ' + collection.name + '.');
                    failure.dat('Request name: ' + util.getFullName(currentItem) + '.');
                    failure.dat('Test description: ' + name + '.');
                    if (failures.length !== 0) {
                        failure.att('message', failures[0].message);
                        failure.dat('Error message: ' + failures[0].message + '.');
                        failure.dat('Stacktrace: ' + failures[0].stack + '.');
                    }
                }
            });
        });

        root.att('time', testSuitesExecutionTime.toFixed(3));
        newman.exports.push({
            name: 'junit-reporter',
            default: 'newman-run-report.xml',
            path: reporterOptions.export,
            content: root.end({
                pretty: true,
                indent: '  ',
                newline: '\n',
                allowEmpty: false
            })
        });
    });
};

module.exports = JunitReporter;
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var express = require('express'),
    fs = require('fs');

var app = module.exports = express.createServer();
var assetManager = require('connect-assetmanager');
var io = require('socket.io').listen(app);
var lobbyClass = require('./lib/lobby.js');
var siteConfig = require('./siteConfig.js');

// Configuration

io.configure(function () {
  io.set('transports', ['websocket', 'xhr-polling']);
});

var assetManagerGroups = {
  'js': {
    'route': /js\/.*\.js/
    , 'path': './app/'
    , 'dataType': 'javascript'
    , 'files': [
        // siteConfig.uri + '/socket.io/socket.io.js', // combined js has errors with this one in it
        'lib/jquery.cookie/jquery.cookie.js',
        'lib/underscore.min.js',
        'lib/angular/angular.min.js',
        'js/app.js',
        'js/controllers.js',
        'js/directives.js',
        'js/filters.js',
        'js/services.js'
    ]
  },
  'css': {
    'route': /css\/.*\.css/
    , 'path': './app/'
    , 'dataType': 'css'
    , 'files': [
      'css/bootstrap.min.css',
      'css/app.css'
    ]
  }
}
var assetsManagerMiddleware = assetManager(assetManagerGroups);

app.configure(function(){
  app.set('views', __dirname + '/app');
  app.set('view engine', 'ejs');
  app.set('view options', {
      layout: false
  });
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(assetsManagerMiddleware);
  app.use(express.staticCache());
  app.use(express.static(__dirname + '/app'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  var oneYear = 31557600000;
  app.use(express.static(__dirname + '/app', { maxAge: oneYear }));
  app.use(express.errorHandler());
});

// Template helpers
app.dynamicHelpers({
  'assetsCacheHashes': function(req, res) {
    return assetsManagerMiddleware.cacheHashes;
  }
});

app.get('/', function(req, res) {
  res.render('index.ejs');
});

app.get('/:id', function(req, res) {
  if (req.params.id in lobby.rooms) {
    res.render('index.ejs');
    // fs.readFile(__dirname + '/app/index.html', 'utf8', function(err, text){
    //   console.log(text);
    //   res.send(text);
    // });
  } else {
    res.redirect('/');
  }
});

// Heroku won't actually allow us to use WebSockets
// so we have to setup polling instead.
// https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku
io.configure('production', function(){
  io.enable('browser client etag');
  io.set('log level', 1);
  io.set('transports', [
      "websocket"
    ]);
});
io.configure('development', function(){
  io.enable('browser client etag');
  io.set('log level', 2);
  io.set('transports', [
      "websocket"
    ]);
});

var port = process.env.app_port || 5000; // Use the port that Heroku provides or default to 5000
app.listen(port, function() {
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

var lobby = new lobbyClass.Lobby(io);

/* EVENT LISTENERS */

io.sockets.on('connection', function (socket) {

  // console.log("On connect", socket.id);

  socket.on('disconnect', function () {
    // console.log("On disconnect", socket.id);
    lobby.broadcastDisconnect(socket);
  });

  socket.on('create room', function (data, callback) {
    // console.log("on create room", socket.id, data);
    callback(lobby.createRoom());
  });

  socket.on('join room', function (data, callback) {
    // console.log("on join room " + data.roomUrl, socket.id, data);
    var room = lobby.joinRoom(socket, data);
    if(room.error) {
      callback( { error: room.error } );
    } else {
      callback(room.info());
    }
  });

  socket.on('room info', function (data, callback) {
    // console.log("on room info for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    // room = { error: "there was an error" };
    if (room.error) {
      callback( { error: room.error } );
    } else {
      callback(room.info());
    }
  });

  socket.on('set card pack', function (data, cardPack) {
    // console.log("on set card pack " + data.cardPack + " for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    // console.log("error=" + room.error);
    if (!room.error) {
      room.setCardPack(data);
    }
  });

  socket.on('vote', function (data, callback) {
    // console.log("on vote " + data.vote + " received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.recordVote(socket, data);
      callback( {} );
    }
  });

  socket.on('unvote', function (data, callback) {
    // console.log("omn unvote received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.destroyVote(socket, data);
      callback( {} );
    }
  });

  socket.on('reset vote', function (data, callback) {
    // console.log("on reset vote  received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.resetVote();
      callback( {} );
    }
  });

  socket.on('toggle voter', function (data, callback) {
    // console.log("on toggle voter for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.toggleVoter(data);
      callback( {} );
    }
  });

});<commit_msg>Try json polling as next fallback - still can't get iPhone to work on 3G.<commit_after>
/**
 * Module dependencies.
 */

var express = require('express'),
    fs = require('fs');

var app = module.exports = express.createServer();
var assetManager = require('connect-assetmanager');
var io = require('socket.io').listen(app);
var lobbyClass = require('./lib/lobby.js');
var siteConfig = require('./siteConfig.js');

// Configuration

io.configure(function () {
  io.set('transports', ['websocket', 'jsonp-polling', 'htmlfile', 'xhr-polling']);
});

var assetManagerGroups = {
  'js': {
    'route': /js\/.*\.js/
    , 'path': './app/'
    , 'dataType': 'javascript'
    , 'files': [
        // siteConfig.uri + '/socket.io/socket.io.js', // combined js has errors with this one in it
        'lib/jquery.cookie/jquery.cookie.js',
        'lib/underscore.min.js',
        'lib/angular/angular.min.js',
        'js/app.js',
        'js/controllers.js',
        'js/directives.js',
        'js/filters.js',
        'js/services.js'
    ]
  },
  'css': {
    'route': /css\/.*\.css/
    , 'path': './app/'
    , 'dataType': 'css'
    , 'files': [
      'css/bootstrap.min.css',
      'css/app.css'
    ]
  }
}
var assetsManagerMiddleware = assetManager(assetManagerGroups);

app.configure(function(){
  app.set('views', __dirname + '/app');
  app.set('view engine', 'ejs');
  app.set('view options', {
      layout: false
  });
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(assetsManagerMiddleware);
  app.use(express.staticCache());
  app.use(express.static(__dirname + '/app'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  var oneYear = 31557600000;
  app.use(express.static(__dirname + '/app', { maxAge: oneYear }));
  app.use(express.errorHandler());
});

// Template helpers
app.dynamicHelpers({
  'assetsCacheHashes': function(req, res) {
    return assetsManagerMiddleware.cacheHashes;
  }
});

app.get('/', function(req, res) {
  res.render('index.ejs');
});

app.get('/:id', function(req, res) {
  if (req.params.id in lobby.rooms) {
    res.render('index.ejs');
    // fs.readFile(__dirname + '/app/index.html', 'utf8', function(err, text){
    //   console.log(text);
    //   res.send(text);
    // });
  } else {
    res.redirect('/');
  }
});

// Heroku won't actually allow us to use WebSockets
// so we have to setup polling instead.
// https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku
io.configure('production', function(){
  io.enable('browser client etag');
  io.set('log level', 1);
  io.set('transports', [
      "websocket"
    ]);
});
io.configure('development', function(){
  io.enable('browser client etag');
  io.set('log level', 2);
  io.set('transports', [
      "websocket"
    ]);
});

var port = process.env.app_port || 5000; // Use the port that Heroku provides or default to 5000
app.listen(port, function() {
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

var lobby = new lobbyClass.Lobby(io);

/* EVENT LISTENERS */

io.sockets.on('connection', function (socket) {

  // console.log("On connect", socket.id);

  socket.on('disconnect', function () {
    // console.log("On disconnect", socket.id);
    lobby.broadcastDisconnect(socket);
  });

  socket.on('create room', function (data, callback) {
    // console.log("on create room", socket.id, data);
    callback(lobby.createRoom());
  });

  socket.on('join room', function (data, callback) {
    // console.log("on join room " + data.roomUrl, socket.id, data);
    var room = lobby.joinRoom(socket, data);
    if(room.error) {
      callback( { error: room.error } );
    } else {
      callback(room.info());
    }
  });

  socket.on('room info', function (data, callback) {
    // console.log("on room info for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    // room = { error: "there was an error" };
    if (room.error) {
      callback( { error: room.error } );
    } else {
      callback(room.info());
    }
  });

  socket.on('set card pack', function (data, cardPack) {
    // console.log("on set card pack " + data.cardPack + " for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    // console.log("error=" + room.error);
    if (!room.error) {
      room.setCardPack(data);
    }
  });

  socket.on('vote', function (data, callback) {
    // console.log("on vote " + data.vote + " received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.recordVote(socket, data);
      callback( {} );
    }
  });

  socket.on('unvote', function (data, callback) {
    // console.log("omn unvote received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.destroyVote(socket, data);
      callback( {} );
    }
  });

  socket.on('reset vote', function (data, callback) {
    // console.log("on reset vote  received for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.resetVote();
      callback( {} );
    }
  });

  socket.on('toggle voter', function (data, callback) {
    // console.log("on toggle voter for " + data.roomUrl, socket.id, data);
    var room = lobby.getRoom(data.roomUrl);
    if (room.error) {
      callback( { error: room.error });
    } else {
      room.toggleVoter(data);
      callback( {} );
    }
  });

});<|endoftext|>


<commit_before>'use strict';

/**
  Basic event-emitter functionality to mixin to other classes.

  TODO: needs explicit tests (is currently *implicitly* tested by sensor-applet_spec).
*/
module.exports = {

  on: function(evt, cb) {
    if (!this._ee_listeners) {
      this._ee_listeners = {};
    }
    if (!this._ee_listeners[evt]) {
      this._ee_listeners[evt] = [];
    }

    this._ee_listeners[evt].push(cb);
  },

  emit: function(evt) {
    var args = arguments.length > 1 ? [].splice.call(arguments, 1) : [];

    if (this._ee_listeners && this._ee_listeners[evt]) {
      for (var i = 0, len = this._ee_listeners[evt].length; i < len; i++) {
        this._ee_listeners[evt][i].apply(null, args);
      }
    }
  },

  removeListener: function(evt, listener) {
    if (this._ee_listeners && this._ee_listeners[evt]) {
      for (var i = 0, len = this._ee_listeners[evt].length; i < len; i++) {
        if (this._ee_listeners[evt][i] === listener) {
          this._ee_listeners[evt].splice(i, 1);
        }
      }
    }
  },

  removeListeners: function(evt) {
    if (!evt) {
      this._ee_listeners = {};
    } else {
      if (this._ee_listeners) {
        this._ee_listeners[evt] = [];
      }
    }
  }
};
<commit_msg>IE8 requires 2 arguments to Array.prototype.splice<commit_after>'use strict';

/**
  Basic event-emitter functionality to mixin to other classes.

  TODO: needs explicit tests (is currently *implicitly* tested by sensor-applet_spec).
*/
module.exports = {

  on: function(evt, cb) {
    if (!this._ee_listeners) {
      this._ee_listeners = {};
    }
    if (!this._ee_listeners[evt]) {
      this._ee_listeners[evt] = [];
    }

    this._ee_listeners[evt].push(cb);
  },

  emit: function(evt) {
    var args = arguments.length > 1 ? [].slice.call(arguments, 1) : [];

    if (this._ee_listeners && this._ee_listeners[evt]) {
      for (var i = 0, len = this._ee_listeners[evt].length; i < len; i++) {
        this._ee_listeners[evt][i].apply(null, args);
      }
    }
  },

  removeListener: function(evt, listener) {
    if (this._ee_listeners && this._ee_listeners[evt]) {
      for (var i = 0, len = this._ee_listeners[evt].length; i < len; i++) {
        if (this._ee_listeners[evt][i] === listener) {
          this._ee_listeners[evt].splice(i, 1);
        }
      }
    }
  },

  removeListeners: function(evt) {
    if (!evt) {
      this._ee_listeners = {};
    } else {
      if (this._ee_listeners) {
        this._ee_listeners[evt] = [];
      }
    }
  }
};
<|endoftext|>


<commit_before>E2.plugins["clamped_accumulate_modulator"] = function(core, node) {
	var self = this;

	this.desc = 'Every input value is accumulated in an internal buffer (which resets to zero on playback stop). The buffer value is not permitted to be smaller then min or larger than max.';
	this.input_slots =
	[
		{ name: 'value', dt: core.datatypes.FLOAT, desc: 'A small value to be accumulated in an internal buffer.', def: 0 },
		{ name: 'min', dt: core.datatypes.FLOAT, desc: 'Minimum internal buffer value.', def: 0 },
		{ name: 'max', dt: core.datatypes.FLOAT, desc: 'Maximum internal buffer value.', def: 1 }
	];
	this.output_slots = [ { name: 'value', dt: core.datatypes.FLOAT, desc: 'The current value of the accumulation buffer.', def: 0 } ];
	this.state = { value: 0.0 };

	this.reset = function()
	{
		self.updated = true;
	};

	this.update_input = function(slot, data)
	{
		if(slot.index === 0)
		{
			self.value = data;

			self.state.value += self.value;

			self.state.value = self.state.value < self.lo ? self.lo : self.state.value > self.hi ? self.hi : self.state.value;
		}
		if(slot.index === 1)
			self.lo = data;
		if(slot.index === 2)
			self.hi = data;
	};

	this.update_output = function(slot)
	{
		return self.state.value;
	};

	this.state_changed = function(ui)
	{
		if(!ui)
		{
			self.value = 0.0;
			self.lo = 0.0;
			self.hi = 1.0;
		}
	};
};
<commit_msg>Refactored the clamped accumulate plugin to use prototype.<commit_after>E2.p = E2.plugins["clamped_accumulate_modulator"] = function(core, node)
{
	this.desc = 'Every input value is accumulated in an internal buffer. The buffer value is not permitted to be smaller then min or larger than max.';

	this.input_slots =
	[
		{ name: 'value', dt: core.datatypes.FLOAT, desc: 'A small value to be accumulated in an internal buffer.', def: 0 },
		{ name: 'min', dt: core.datatypes.FLOAT, desc: 'Minimum internal buffer value.', def: 0 },
		{ name: 'max', dt: core.datatypes.FLOAT, desc: 'Maximum internal buffer value.', def: 1 }
	];

	this.output_slots = [
		{ name: 'value', dt: core.datatypes.FLOAT, desc: 'The current value of the accumulation buffer.', def: 0 }
	];

	this.state = { value: 0.0 };
};

E2.p.prototype.reset = function()
{
	this.updated = true;
};

E2.p.prototype.update_input = function(slot, data)
{
	if(slot.index === 0)
	{
		this.value = data;
		this.state.value += this.value;
		this.state.value = this.state.value < this.lo ? this.lo : this.state.value > this.hi ? this.hi : this.state.value;
	}
	if(slot.index === 1)
		this.lo = data;
	if(slot.index === 2)
		this.hi = data;
};

E2.p.prototype.update_output = function(slot)
{
	return this.state.value;
};

E2.p.prototype.state_changed = function(ui)
{
	if(!ui)
	{
		this.value = 0.0;
		this.lo = 0.0;
		this.hi = 1.0;
	}
};
<|endoftext|>


<commit_before>
Ui.CanvasElement.extend('Ui.DialogGraphic', {}, {
	updateCanvas: function(ctx) {
		var w = this.getLayoutWidth();
		var h = this.getLayoutHeight();

		// shadow
		this.roundRectFilledShadow(0, 0, w, h, 2, 2, 2, 2, false, 3, new Ui.Color({ a: 0.3 }));

		// content background
		ctx.fillStyle = '#f8f8f8';
		ctx.fillRect(3, 3, w-6, h-6);
	}
});

Ui.Container.extend('Ui.Dialog', {
	dialogSelection: undefined,
	bg: undefined,
	lbox: undefined,
	vbox: undefined,
	titleLabel: undefined,
	contentBox: undefined,
	contentVBox: undefined,
	actionButtonsBox: undefined,
	actionButtons: undefined,
	cancelBox: undefined,
	buttonsBox: undefined,
	buttonsVisible: false,
	preferedWidth: 100,
	preferedHeight: 100,
	actionBox: undefined,
	contextBox: undefined,

	constructor: function(config) {
		this.addEvents('close');

		this.dialogSelection = new Ui.Selection();

		this.bg = new Ui.Rectangle({ fill: 'rgba(255,255,255,0.7)' });
		this.appendChild(this.bg);

		this.lbox = new Ui.LBox();
		this.appendChild(this.lbox);

		this.lbox.append(new Ui.DialogGraphic());

		this.vbox = new Ui.VBox({ margin: 3 });
		this.lbox.append(this.vbox);

		this.scroll = new Ui.ScrollingArea({ marginLeft: 2, marginTop: 2, marginRight: 2 });
		this.scroll.setScrollHorizontal(false);
		this.scroll.setScrollVertical(false);
		this.vbox.append(this.scroll, true);

		this.contentVBox = new Ui.VBox();
		this.scroll.setContent(this.contentVBox);

		this.contentBox = new Ui.LBox({ margin: 8 });
		this.contentVBox.append(this.contentBox, true);

		this.buttonsBox = new Ui.VBox();
		this.buttonsBox.append(new Ui.Rectangle({ height: 1, fill: '#d8d8d8' }));

		var lbox = new Ui.LBox({ height: 32 });
		this.buttonsBox.append(lbox);

		this.actionBg = new Ui.Rectangle({ fill: '#e8e8e8' });
		lbox.append(this.actionBg);

		this.contextBox = new Ui.ContextBar({ selection: this.dialogSelection });
		this.contextBox.hide();
		lbox.append(this.contextBox);

		this.actionBox = new Ui.HBox({ margin: 5, spacing: 30 });
		lbox.append(this.actionBox);

		this.cancelBox = new Ui.LBox();
		this.actionBox.append(this.cancelBox);

		this.actionButtonsBox = new Ui.HBox({ spacing: 5, uniform: true, horizontalAlign: 'right' });
		this.actionBox.append(this.actionButtonsBox, true);

		this.connect(this.dialogSelection, 'change', this.onDialogSelectionChange);

		// handle keyboard
		this.connect(this.getDrawing(), 'keydown', this.onKeyDown);
	},

	// implement a selection handler for Selectionable elements
	getSelectionHandler: function() {
		return this.dialogSelection;
	},

	setPreferedWidth: function(width) {
		this.preferedWidth = width;
		this.invalidateMeasure();
	},

	setPreferedHeight: function(height) {
		this.preferedHeight = height;
		this.invalidateMeasure();
	},

	open: function() {
		Ui.App.current.appendDialog(this);
	},

	close: function() {
		Ui.App.current.removeDialog(this);
		this.fireEvent('close', this);
	},

	setFullScrolling: function(fullScrolling) {
		this.scroll.setScrollHorizontal(fullScrolling);
		this.scroll.setScrollVertical(fullScrolling);
	},

	setTitle: function(title) {
		this.title = title;

		if(((this.title == '') || (this.title === undefined))  && (this.titleLabel !== undefined)) {
			this.contentVBox.remove(this.titleLabel);
			this.titleLabel = undefined;
		}
		else {
			if(this.titleLabel === undefined) {
				this.titleLabel = new Ui.Label({ horizontalAlign: 'left', margin: 10, fontWeight: 'bold', fontSize: 18, color: '#666666' });
				this.contentVBox.prepend(this.titleLabel);
			}
			this.titleLabel.setText(this.title);
		}
	},

	setCancelButton: function(button) {
		var old = this.cancelBox.getFirstChild();
		if((old != undefined) && Ui.Pressable.hasInstance(old))
			this.disconnect(old, 'press', this.onCancelPress);

		this.cancelBox.setContent(button);
		var newbutton = this.cancelBox.getFirstChild();
		if((newbutton != undefined) && Ui.Pressable.hasInstance(newbutton))
			this.connect(newbutton, 'press', this.onCancelPress);

		if(button != undefined) {
			if(!this.buttonsVisible) {
				this.buttonsVisible = true;
				this.vbox.append(this.buttonsBox);
			}
		}
		else {
			if(this.buttonsVisible) {
				if((this.actionButtons == undefined) || (this.actionButtons.length == 0)) {
					this.buttonsVisible = false;
					this.vbox.remove(this.buttonsBox);
				}
			}
		}
	},

	setActionButtons: function(buttons) {
		this.actionButtonsBox.setContent(buttons);
		if((buttons != undefined) && (buttons.length > 0)) {
			if(!this.buttonsVisible) {
				this.buttonsVisible = true;
				this.vbox.append(this.buttonsBox);
			}
		}
		else {
			if((this.buttonsVisible) && (this.cancelBox.getFirstChild() == undefined)) {
					this.buttonsVisible = false;
					this.vbox.remove(this.buttonsBox);
			}
		}
	},

	setContent: function(content) {
		this.contentBox.setContent(content);
	},

	getContent: function() {
		return this.contentBox.getFirstChild();
	},

	onCancelPress: function() {
		this.close();
	},

	onDialogSelectionChange: function(selection) {
		if(selection.getElements().length === 0) {
//			this.actionBg.setFill('#e8e8e8');
			this.contextBox.hide();
			this.actionBox.show();
		}
		else {
//			this.actionBg.setFill('#d8d8d8');
			this.contextBox.show();
			this.actionBox.hide();
		}
	},

	onKeyDown: function(event) {
		// delete key
		if(event.which === 46) {
		 	// selection is not empty
			if(this.dialogSelection.getElements().length !== 0) {
				if(this.dialogSelection.executeDeleteAction()) {
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}
	}

}, {
	measureCore: function(width, height) {
		this.bg.measure(width, height);
		this.lbox.measure((width < this.preferedWidth)?width:this.preferedWidth,
			(height < this.preferedHeight)?height:this.preferedHeight);
		return { width: width, height: height };
	},

	//
	// Arrange children
	//
	arrangeCore: function(width, height) {
		this.bg.arrange(0, 0, width, height);
		var usedWidth = Math.max((width < this.preferedWidth)?width:this.preferedWidth, this.lbox.getMeasureWidth());
		var usedHeight = Math.max((height < this.preferedHeight)?height:this.preferedHeight, this.lbox.getMeasureHeight());
		this.lbox.arrange((width-usedWidth)/2, (height-usedHeight)/2, usedWidth, usedHeight);
	}
});

<commit_msg>use MenuToolBar for dialog's action buttons to improve support for small screens<commit_after>
Ui.CanvasElement.extend('Ui.DialogGraphic', {}, {
	updateCanvas: function(ctx) {
		var w = this.getLayoutWidth();
		var h = this.getLayoutHeight();

		// shadow
		this.roundRectFilledShadow(0, 0, w, h, 2, 2, 2, 2, false, 3, new Ui.Color({ a: 0.3 }));

		// content background
		ctx.fillStyle = '#f8f8f8';
		ctx.fillRect(3, 3, w-6, h-6);
	}
});

Ui.Container.extend('Ui.Dialog', {
	dialogSelection: undefined,
	bg: undefined,
	lbox: undefined,
	vbox: undefined,
	titleLabel: undefined,
	contentBox: undefined,
	contentVBox: undefined,
	actionButtonsBox: undefined,
	actionButtons: undefined,
	cancelBox: undefined,
	buttonsBox: undefined,
	buttonsVisible: false,
	preferedWidth: 100,
	preferedHeight: 100,
	actionBox: undefined,
	contextBox: undefined,

	constructor: function(config) {
		this.addEvents('close');

		this.dialogSelection = new Ui.Selection();

		this.bg = new Ui.Rectangle({ fill: 'rgba(255,255,255,0.7)' });
		this.appendChild(this.bg);

		this.lbox = new Ui.LBox();
		this.appendChild(this.lbox);

		this.lbox.append(new Ui.DialogGraphic());

		this.vbox = new Ui.VBox({ margin: 3 });
		this.lbox.append(this.vbox);

		this.scroll = new Ui.ScrollingArea({ marginLeft: 2, marginTop: 2, marginRight: 2 });
		this.scroll.setScrollHorizontal(false);
		this.scroll.setScrollVertical(false);
		this.vbox.append(this.scroll, true);

		this.contentVBox = new Ui.VBox();
		this.scroll.setContent(this.contentVBox);

		this.contentBox = new Ui.LBox({ margin: 8 });
		this.contentVBox.append(this.contentBox, true);

		this.buttonsBox = new Ui.VBox();
		this.buttonsBox.append(new Ui.Rectangle({ height: 1, fill: '#d8d8d8' }));

		var lbox = new Ui.LBox({ height: 32 });
		this.buttonsBox.append(lbox);

		this.actionBg = new Ui.Rectangle({ fill: '#e8e8e8' });
		lbox.append(this.actionBg);

		this.contextBox = new Ui.ContextBar({ selection: this.dialogSelection });
		this.contextBox.hide();
		lbox.append(this.contextBox);

		this.actionBox = new Ui.HBox({ margin: 5, spacing: 30 });
		lbox.append(this.actionBox);

		this.cancelBox = new Ui.LBox();
		this.actionBox.append(this.cancelBox);

		this.actionButtonsBox = new Ui.MenuToolBar({ spacing: 5, itemsAlign: 'right', menuPosition: 'left', uniform: true });
		this.actionBox.append(this.actionButtonsBox, true);

		this.connect(this.dialogSelection, 'change', this.onDialogSelectionChange);

		// handle keyboard
		this.connect(this.getDrawing(), 'keydown', this.onKeyDown);
	},

	// implement a selection handler for Selectionable elements
	getSelectionHandler: function() {
		return this.dialogSelection;
	},

	setPreferedWidth: function(width) {
		this.preferedWidth = width;
		this.invalidateMeasure();
	},

	setPreferedHeight: function(height) {
		this.preferedHeight = height;
		this.invalidateMeasure();
	},

	open: function() {
		Ui.App.current.appendDialog(this);
	},

	close: function() {
		Ui.App.current.removeDialog(this);
		this.fireEvent('close', this);
	},

	setFullScrolling: function(fullScrolling) {
		this.scroll.setScrollHorizontal(fullScrolling);
		this.scroll.setScrollVertical(fullScrolling);
	},

	setTitle: function(title) {
		this.title = title;

		if(((this.title == '') || (this.title === undefined))  && (this.titleLabel !== undefined)) {
			this.contentVBox.remove(this.titleLabel);
			this.titleLabel = undefined;
		}
		else {
			if(this.titleLabel === undefined) {
				this.titleLabel = new Ui.Label({ horizontalAlign: 'left', margin: 10, fontWeight: 'bold', fontSize: 18, color: '#666666' });
				this.contentVBox.prepend(this.titleLabel);
			}
			this.titleLabel.setText(this.title);
		}
	},

	setCancelButton: function(button) {
		var old = this.cancelBox.getFirstChild();
		if((old != undefined) && Ui.Pressable.hasInstance(old))
			this.disconnect(old, 'press', this.onCancelPress);

		this.cancelBox.setContent(button);
		var newbutton = this.cancelBox.getFirstChild();
		if((newbutton != undefined) && Ui.Pressable.hasInstance(newbutton))
			this.connect(newbutton, 'press', this.onCancelPress);

		if(button != undefined) {
			if(!this.buttonsVisible) {
				this.buttonsVisible = true;
				this.vbox.append(this.buttonsBox);
			}
		}
		else {
			if(this.buttonsVisible) {
				if((this.actionButtons == undefined) || (this.actionButtons.length == 0)) {
					this.buttonsVisible = false;
					this.vbox.remove(this.buttonsBox);
				}
			}
		}
	},

	setActionButtons: function(buttons) {
		this.actionButtonsBox.setContent(buttons);
		if((buttons != undefined) && (buttons.length > 0)) {
			if(!this.buttonsVisible) {
				this.buttonsVisible = true;
				this.vbox.append(this.buttonsBox);
			}
		}
		else {
			if((this.buttonsVisible) && (this.cancelBox.getFirstChild() == undefined)) {
					this.buttonsVisible = false;
					this.vbox.remove(this.buttonsBox);
			}
		}
	},

	setContent: function(content) {
		this.contentBox.setContent(content);
	},

	getContent: function() {
		return this.contentBox.getFirstChild();
	},

	onCancelPress: function() {
		this.close();
	},

	onDialogSelectionChange: function(selection) {
		if(selection.getElements().length === 0) {
//			this.actionBg.setFill('#e8e8e8');
			this.contextBox.hide();
			this.actionBox.show();
		}
		else {
//			this.actionBg.setFill('#d8d8d8');
			this.contextBox.show();
			this.actionBox.hide();
		}
	},

	onKeyDown: function(event) {
		// delete key
		if(event.which === 46) {
		 	// selection is not empty
			if(this.dialogSelection.getElements().length !== 0) {
				if(this.dialogSelection.executeDeleteAction()) {
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}
	}

}, {
	measureCore: function(width, height) {
		this.bg.measure(width, height);
		this.lbox.measure((width < this.preferedWidth)?width:this.preferedWidth,
			(height < this.preferedHeight)?height:this.preferedHeight);
		return { width: width, height: height };
	},

	//
	// Arrange children
	//
	arrangeCore: function(width, height) {
		this.bg.arrange(0, 0, width, height);
		var usedWidth = Math.max((width < this.preferedWidth)?width:this.preferedWidth, this.lbox.getMeasureWidth());
		var usedHeight = Math.max((height < this.preferedHeight)?height:this.preferedHeight, this.lbox.getMeasureHeight());
		this.lbox.arrange((width-usedWidth)/2, (height-usedHeight)/2, usedWidth, usedHeight);
	}
});

<|endoftext|>


<commit_before>/*
  The code here has been adapted from the npm css module, the source code for
  which is available at http://github.com/reworkcss/css.
  It is available under an MIT license.
*/
var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g

function parse (css, options) {
  options = options || {};

  /**
   * Positional.
   */

  var lineno = 1;
  var column = 1;

  /**
   * Update lineno and column based on `str`.
   */

  function updatePosition(str) {
    var lines = str.match(/\n/g);
    if (lines) lineno += lines.length;
    var i = str.lastIndexOf('\n');
    column = ~i ? str.length - i : column + str.length;
  }

  /**
   * Mark position and patch `node.position`.
   */

  function position() {
    var start = { line: lineno, column: column };
    return function(node){
      node.position = new Position(start);
      whitespace();
      return node;
    };
  }

  /**
   * Store position information for a node
   */

  function Position(start) {
    this.start = start;
    this.end = { line: lineno, column: column };
    this.source = options.source;
  }

  /**
   * Non-enumerable source string
   */

  Position.prototype.content = css;

  /**
   * Error `msg`.
   */

  var errorsList = [];

  function error(msg) {
    var err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
    err.reason = msg;
    err.filename = options.source;
    err.line = lineno;
    err.column = column;
    err.source = css;

    if (options.silent) {
      errorsList.push(err);
    } else {
      throw err;
    }
  }

  /**
   * Parse stylesheet.
   */

  function stylesheet() {
    var rulesList = rules();

    return {
      type: 'stylesheet',
      stylesheet: {
        rules: rulesList,
        parsingErrors: errorsList
      }
    };
  }

  /**
   * Opening brace.
   */

  function open() {
    return match(/^{\s*/);
  }

  /**
   * Closing brace.
   */

  function close() {
    return match(/^}/);
  }

  /**
   * Parse ruleset.
   */

  function rules() {
    var node;
    var rules = [];
    whitespace();
    comments(rules);
    while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) {
      if (node !== false) {
        rules.push(node);
        comments(rules);
      }
    }
    return rules;
  }

  /**
   * Match `re` and return captures.
   */

  function match(re) {
    var m = re.exec(css);
    if (!m) return;
    var str = m[0];
    updatePosition(str);
    css = css.slice(str.length);
    return m;
  }

  /**
   * Parse whitespace.
   */

  function whitespace() {
    match(/^\s*/);
  }

  /**
   * Parse comments;
   */

  function comments(rules) {
    var c;
    rules = rules || [];
    while (c = comment()) {
      if (c !== false) {
        rules.push(c);
      }
    }
    return rules;
  }

  /**
   * Parse comment.
   */

  function comment() {
    var pos = position();
    if ('/' != css.charAt(0) || '*' != css.charAt(1)) return;

    var i = 2;
    while ("" != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i;
    i += 2;

    if ("" === css.charAt(i-1)) {
      return error('End of comment missing');
    }

    var str = css.slice(2, i - 2);
    column += 2;
    updatePosition(str);
    css = css.slice(i);
    column += 2;

    return pos({
      type: 'comment',
      comment: str
    });
  }

  /**
   * Parse selector.
   */

  function selector() {
    var m = match(/^([^{]+)/);
    if (!m) return;
    /* @fix Remove all comments from selectors
     * http://ostermiller.org/findcomment.html */
    return trim(m[0])
      .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
      .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
        return m.replace(/,/g, '\u200C');
      })
      .split(/\s*(?![^(]*\)),\s*/)
      .map(function(s) {
        return s.replace(/\u200C/g, ',');
      });
  }

  /**
   * Parse declaration.
   */

  function declaration() {
    var pos = position();

    // prop
    var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
    if (!prop) return;
    prop = trim(prop[0]);

    // :
    if (!match(/^:\s*/)) return error("property missing ':'");

    // val
    var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);

    var ret = pos({
      type: 'declaration',
      property: prop.replace(commentre, ''),
      value: val ? trim(val[0]).replace(commentre, '') : ''
    });

    // ;
    match(/^[;\s]*/);

    return ret;
  }

  /**
   * Parse declarations.
   */

  function declarations() {
    var decls = [];

    if (!open()) return error("missing '{'");
    comments(decls);

    // declarations
    var decl;
    while (decl = declaration()) {
      if (decl !== false) {
        decls.push(decl);
        comments(decls);
      }
    }

    if (!close()) return error("missing '}'");
    return decls;
  }

  /**
   * Parse keyframe.
   */

  function keyframe() {
    var m;
    var vals = [];
    var pos = position();

    while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
      vals.push(m[1]);
      match(/^,\s*/);
    }

    if (!vals.length) return;

    return pos({
      type: 'keyframe',
      values: vals,
      declarations: declarations()
    });
  }

  /**
   * Parse keyframes.
   */

  function atkeyframes() {
    var pos = position();
    var m = match(/^@([-\w]+)?keyframes\s*/);

    if (!m) return;
    var vendor = m[1];

    // identifier
    var m = match(/^([-\w]+)\s*/);
    if (!m) return error("@keyframes missing name");
    var name = m[1];

    if (!open()) return error("@keyframes missing '{'");

    var frame;
    var frames = comments();
    while (frame = keyframe()) {
      frames.push(frame);
      frames = frames.concat(comments());
    }

    if (!close()) return error("@keyframes missing '}'");

    return pos({
      type: 'keyframes',
      name: name,
      vendor: vendor,
      keyframes: frames
    });
  }

  /**
   * Parse supports.
   */

  function atsupports() {
    var pos = position();
    var m = match(/^@supports *([^{]+)/);

    if (!m) return;
    var supports = trim(m[1]);

    if (!open()) return error("@supports missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@supports missing '}'");

    return pos({
      type: 'supports',
      supports: supports,
      rules: style
    });
  }

  /**
   * Parse host.
   */

  function athost() {
    var pos = position();
    var m = match(/^@host\s*/);

    if (!m) return;

    if (!open()) return error("@host missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@host missing '}'");

    return pos({
      type: 'host',
      rules: style
    });
  }

  /**
   * Parse media.
   */

  function atmedia() {
    var pos = position();
    var m = match(/^@media *([^{]+)/);

    if (!m) return;
    var media = trim(m[1]);

    if (!open()) return error("@media missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@media missing '}'");

    return pos({
      type: 'media',
      media: media,
      rules: style
    });
  }

  /**
   * Parse custom-media.
   */

  function atcustommedia() {
    var pos = position();
    var m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
    if (!m) return;

    return pos({
      type: 'custom-media',
      name: trim(m[1]),
      media: trim(m[2])
    });
  }

  /**
   * Parse paged media.
   */

  function atpage() {
    var pos = position();
    var m = match(/^@page */);
    if (!m) return;

    var sel = selector() || [];

    if (!open()) return error("@page missing '{'");
    var decls = comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      decls = decls.concat(comments());
    }

    if (!close()) return error("@page missing '}'");

    return pos({
      type: 'page',
      selectors: sel,
      declarations: decls
    });
  }

  /**
   * Parse document.
   */

  function atdocument() {
    var pos = position();
    var m = match(/^@([-\w]+)?document *([^{]+)/);
    if (!m) return;

    var vendor = trim(m[1]);
    var doc = trim(m[2]);

    if (!open()) return error("@document missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@document missing '}'");

    return pos({
      type: 'document',
      document: doc,
      vendor: vendor,
      rules: style
    });
  }

  /**
   * Parse font-face.
   */

  function atfontface() {
    var pos = position();
    var m = match(/^@font-face\s*/);
    if (!m) return;

    if (!open()) return error("@font-face missing '{'");
    var decls = comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      decls = decls.concat(comments());
    }

    if (!close()) return error("@font-face missing '}'");

    return pos({
      type: 'font-face',
      declarations: decls
    });
  }

  /**
   * Parse import
   */

  var atimport = _compileAtrule('import');

  /**
   * Parse charset
   */

  var atcharset = _compileAtrule('charset');

  /**
   * Parse namespace
   */

  var atnamespace = _compileAtrule('namespace');

  /**
   * Parse non-block at-rules
   */

  function _compileAtrule(name) {
    var re = new RegExp('^@' + name + '\\s*([^;]+);');
    return function() {
      var pos = position();
      var m = match(re);
      if (!m) return;
      var ret = { type: name };
      ret[name] = m[1].trim();
      return pos(ret);
    }
  }

  /**
   * Parse at rule.
   */

  function atrule() {
    if (css[0] != '@') return;

    return atkeyframes()
      || atmedia()
      || atcustommedia()
      || atsupports()
      || atimport()
      || atcharset()
      || atnamespace()
      || atdocument()
      || atpage()
      || athost()
      || atfontface();
  }

  /**
   * Parse rule.
   */

  function rule() {
    var pos = position();
    var sel = selector();

    if (!sel) return error('selector missing');
    comments();

    return pos({
      type: 'rule',
      selectors: sel,
      declarations: declarations()
    });
  }

  return addParent(stylesheet());
};

/**
 * Trim `str`.
 */

function trim(str) {
  return str ? str.replace(/^\s+|\s+$/g, '') : '';
}

/**
 * Adds non-enumerable parent node reference to each node.
 */

function addParent(obj, parent) {
  var isNode = obj && typeof obj.type === 'string';
  var childParent = isNode ? obj : parent;

  for (var k in obj) {
    var value = obj[k];
    if (Array.isArray(value)) {
      value.forEach(function(v) { addParent(v, childParent); });
    } else if (value && typeof value === 'object') {
      addParent(value, childParent);
    }
  }

  if (isNode) {
    Object.defineProperty(obj, 'parent', {
      configurable: true,
      writable: true,
      enumerable: false,
      value: parent || null
    });
  }

  return obj;
}
<commit_msg>CSS Parser patch: Remove unneccessary functions<commit_after>/*
  The code here has been adapted from the npm css module, the source code for
  which is available at http://github.com/reworkcss/css.
  It is available under an MIT license.
*/
var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g

function parse (css, options) {
  options = options || {};

  /**
   * Positional.
   */

  var lineno = 1;
  var column = 1;

  /**
   * Update lineno and column based on `str`.
   */

  function updatePosition(str) {
    var lines = str.match(/\n/g);
    if (lines) lineno += lines.length;
    var i = str.lastIndexOf('\n');
    column = ~i ? str.length - i : column + str.length;
  }

  /**
   * Mark position and patch `node.position`.
   */

  function position() {
    var start = { line: lineno, column: column };
    return function(node){
      node.position = new Position(start);
      whitespace();
      return node;
    };
  }

  /**
   * Store position information for a node
   */

  function Position(start) {
    this.start = start;
    this.end = { line: lineno, column: column };
    this.source = options.source;
  }

  /**
   * Non-enumerable source string
   */

  Position.prototype.content = css;

  /**
   * Error `msg`.
   */

  var errorsList = [];

  function error(msg) {
    var err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
    err.reason = msg;
    err.filename = options.source;
    err.line = lineno;
    err.column = column;
    err.source = css;

    if (options.silent) {
      errorsList.push(err);
    } else {
      throw err;
    }
  }

  /**
   * Parse stylesheet.
   */

  function stylesheet() {
    var rulesList = rules();

    return {
      type: 'stylesheet',
      stylesheet: {
        rules: rulesList,
        parsingErrors: errorsList
      }
    };
  }

  /**
   * Opening brace.
   */

  function open() {
    return match(/^{\s*/);
  }

  /**
   * Closing brace.
   */

  function close() {
    return match(/^}/);
  }

  /**
   * Parse ruleset.
   */

  function rules() {
    var node;
    var rules = [];
    whitespace();
    comments(rules);
    while (css.length && css.charAt(0) != '}' && (node = rule())) {
      if (node !== false) {
        rules.push(node);
        comments(rules);
      }
    }
    return rules;
  }

  /**
   * Match `re` and return captures.
   */

  function match(re) {
    var m = re.exec(css);
    if (!m) return;
    var str = m[0];
    updatePosition(str);
    css = css.slice(str.length);
    return m;
  }

  /**
   * Parse whitespace.
   */

  function whitespace() {
    match(/^\s*/);
  }

  /**
   * Parse comments;
   */

  function comments(rules) {
    var c;
    rules = rules || [];
    while (c = comment()) {
      if (c !== false) {
        rules.push(c);
      }
    }
    return rules;
  }

  /**
   * Parse comment.
   */

  function comment() {
    var pos = position();
    if ('/' != css.charAt(0) || '*' != css.charAt(1)) return;

    var i = 2;
    while ("" != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i;
    i += 2;

    if ("" === css.charAt(i-1)) {
      return error('End of comment missing');
    }

    var str = css.slice(2, i - 2);
    column += 2;
    updatePosition(str);
    css = css.slice(i);
    column += 2;

    return pos({
      type: 'comment',
      comment: str
    });
  }

  /**
   * Parse selector.
   */

  function selector() {
    var m = match(/^([^{]+)/);
    if (!m) return;
    /* @fix Remove all comments from selectors
     * http://ostermiller.org/findcomment.html */
    return trim(m[0])
      .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
      .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
        return m.replace(/,/g, '\u200C');
      })
      .split(/\s*(?![^(]*\)),\s*/)
      .map(function(s) {
        return s.replace(/\u200C/g, ',');
      });
  }

  /**
   * Parse declaration.
   */

  function declaration() {
    var pos = position();

    // prop
    var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
    if (!prop) return;
    prop = trim(prop[0]);

    // :
    if (!match(/^:\s*/)) return error("property missing ':'");

    // val
    var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);

    var ret = pos({
      type: 'declaration',
      property: prop.replace(commentre, ''),
      value: val ? trim(val[0]).replace(commentre, '') : ''
    });

    // ;
    match(/^[;\s]*/);

    return ret;
  }

  /**
   * Parse declarations.
   */

  function declarations() {
    var decls = [];

    if (!open()) return error("missing '{'");
    comments(decls);

    // declarations
    var decl;
    while (decl = declaration()) {
      if (decl !== false) {
        decls.push(decl);
        comments(decls);
      }
    }

    if (!close()) return error("missing '}'");
    return decls;
  }

  /**
   * Parse rule.
   */

  function rule() {
    var pos = position();
    var sel = selector();

    if (!sel) return error('selector missing');
    comments();

    return pos({
      type: 'rule',
      selectors: sel,
      declarations: declarations()
    });
  }

  return addParent(stylesheet());
};

/**
 * Trim `str`.
 */

function trim(str) {
  return str ? str.replace(/^\s+|\s+$/g, '') : '';
}

/**
 * Adds non-enumerable parent node reference to each node.
 */

function addParent(obj, parent) {
  var isNode = obj && typeof obj.type === 'string';
  var childParent = isNode ? obj : parent;

  for (var k in obj) {
    var value = obj[k];
    if (Array.isArray(value)) {
      value.forEach(function(v) { addParent(v, childParent); });
    } else if (value && typeof value === 'object') {
      addParent(value, childParent);
    }
  }

  if (isNode) {
    Object.defineProperty(obj, 'parent', {
      configurable: true,
      writable: true,
      enumerable: false,
      value: parent || null
    });
  }

  return obj;
}
<|endoftext|>


<commit_before>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails oncall+relay
 */

'use strict';

jest
  .autoMockOff()
  .mock('performanceNow');

var Relay = require('Relay');
var RelayProfiler = require('RelayProfiler');
var RelayMetricsRecorder = require('RelayMetricsRecorder');
var RelayNetworkLayer = require('RelayNetworkLayer');
var RelayTestUtils = require('RelayTestUtils');

var fetchRelayQuery = require('fetchRelayQuery');
var flattenRelayQuery = require('flattenRelayQuery');
var performanceNow = require('performanceNow');

RelayProfiler.setEnableProfile(true);

describe('RelayMetricsRecorder', () => {
  var query;

  beforeEach(() => {
    jest.resetModuleRegistry();

    var {getNode} = RelayTestUtils;
    query = getNode(Relay.QL`
      query {
        node(id: "123") {
          ... on User {
            name
          }
        }
      }
    `);
  });

  function mockPerformanceNowSequence(times) {
    var index = 0;
    performanceNow.mockImplementation(() => {
      var time = times[index++];
      expect(time).not.toBe(undefined);
      return time;
    });
  }

  it('returns empty metrics until methods are called', () => {
    var recorder = new RelayMetricsRecorder();
    performanceNow.mockReturnValue(0);
    recorder.start();
    performanceNow.mockReturnValue(1000);
    recorder.stop();
    expect(recorder.getMetrics()).toEqual({
      fetchTime: 0,
      measurements: {},
      recordingTime: 1000,
      totalTime: 0,
    });
  });

  it('returns timing for executed methods', () => {
    var recorder = new RelayMetricsRecorder();
    performanceNow.mockReturnValue(0);
    recorder.start();
    mockPerformanceNowSequence([1, 1001]);
    flattenRelayQuery(query);
    performanceNow.mockReturnValue(3000);
    recorder.stop();

    expect(recorder.getMetrics()).toEqual({
      fetchTime: 0,
      measurements: {
        flattenRelayQuery: {
          aggregateTime: 1000,
          callCount: 1,
        },
      },
      recordingTime: 3000,
      totalTime: 1000,
    });
  });

  it('returns total fetch time', () => {
    var recorder = new RelayMetricsRecorder();
    RelayNetworkLayer.sendQueries = jest.genMockFunction();
    performanceNow.mockReturnValue(0);
    recorder.start();

    mockPerformanceNowSequence([1, 1001]);
    fetchRelayQuery(query);
    jest.runOnlyPendingTimers();
    var requests = RelayNetworkLayer.sendQueries.mock.calls[0][0];
    expect(requests.length).toBe(1);
    requests[0].resolve();
    jest.runAllTimers();

    performanceNow.mockReturnValue(3000);
    recorder.stop();

    expect(recorder.getMetrics()).toEqual({
      fetchTime: 1000,
      measurements: {},
      recordingTime: 3000,
      totalTime: 0,
    });
  });
});
<commit_msg>fix RelayMetricsRecorder-test with OSS jest version<commit_after>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails oncall+relay
 */

'use strict';

jest
  .autoMockOff()
  .mock('performanceNow');

var Relay = require('Relay');
var RelayProfiler = require('RelayProfiler');
var RelayMetricsRecorder = require('RelayMetricsRecorder');
var RelayNetworkLayer = require('RelayNetworkLayer');
var RelayTestUtils = require('RelayTestUtils');

var fetchRelayQuery = require('fetchRelayQuery');
var flattenRelayQuery = require('flattenRelayQuery');
var performanceNow = require('performanceNow');

RelayProfiler.setEnableProfile(true);

describe('RelayMetricsRecorder', () => {
  var query;

  beforeEach(() => {
    jest.resetModuleRegistry();

    var {getNode} = RelayTestUtils;
    query = getNode(Relay.QL`
      query {
        node(id: "123") {
          ... on User {
            name
          }
        }
      }
    `);
  });

  function mockPerformanceNowSequence(times) {
    var index = 0;
    performanceNow.mockImplementation(() => {
      var time = times[index++];
      expect(time).not.toBe(undefined);
      return time;
    });
  }

  it('returns empty metrics until methods are called', () => {
    var recorder = new RelayMetricsRecorder();
    performanceNow.mockReturnValue(0);
    recorder.start();
    performanceNow.mockReturnValue(1000);
    recorder.stop();
    expect(recorder.getMetrics()).toEqual({
      fetchTime: 0,
      measurements: {},
      recordingTime: 1000,
      totalTime: 0,
    });
  });

  it('returns timing for executed methods', () => {
    var recorder = new RelayMetricsRecorder();
    performanceNow.mockReturnValue(0);
    recorder.start();
    mockPerformanceNowSequence([1, 1001]);
    flattenRelayQuery(query);
    performanceNow.mockReturnValue(3000);
    recorder.stop();

    expect(recorder.getMetrics()).toEqual({
      fetchTime: 0,
      measurements: {
        flattenRelayQuery: {
          aggregateTime: 1000,
          callCount: 1,
        },
      },
      recordingTime: 3000,
      totalTime: 1000,
    });
  });

  it('returns total fetch time', () => {
    var recorder = new RelayMetricsRecorder();
    RelayNetworkLayer.sendQueries = jest.genMockFunction();
    performanceNow.mockReturnValue(0);
    recorder.start();

    mockPerformanceNowSequence([1, 1001]);
    fetchRelayQuery(query);
    jest.runAllTimers();
    var requests = RelayNetworkLayer.sendQueries.mock.calls[0][0];
    expect(requests.length).toBe(1);
    requests[0].resolve();
    jest.runAllTimers();

    performanceNow.mockReturnValue(3000);
    recorder.stop();

    expect(recorder.getMetrics()).toEqual({
      fetchTime: 1000,
      measurements: {},
      recordingTime: 3000,
      totalTime: 0,
    });
  });
});
<|endoftext|>


<commit_before>module.exports = function serverErrorResponse(data) {
  var req = this.req;
  var res = this.res;
  var we = req.getWe();

  res.status(500);

  if (!data) data = {};

  if (!res.locals.responseType || res.locals.responseType == 'html') {
    return res.render(data);
  }

  if (res.locals.responseType == 'json') {
    // set messages
    data.messages = res.locals.messages;
    return res.send(data);
  }

  we.log.error('Unknow responseType:', res.locals.responseType);
}<commit_msg>add log in serverError response<commit_after>var env = require('../env');
var log = require('../log')();

module.exports = function serverErrorResponse(data) {
  var req = this.req;
  var res = this.res;
  var we = req.getWe();

  res.status(500);

  if (data && env != 'prod') log.error(data);

  if (!data) data = {};

  if (!res.locals.responseType || res.locals.responseType == 'html') {
    return res.render(data);
  }

  if (res.locals.responseType == 'json') {
    // set messages
    data.messages = res.locals.messages;
    return res.send(data);
  }

  we.log.error('Unknow responseType:', res.locals.responseType);
}<|endoftext|>