<commit_before>//import React, { Component } from 'react';
import React from 'react';
import './App.css';
import Game from './Game';

class App extends React.Component {
  constructor(props){
    super(props);
    //set the games state object
    this.state = {
      countDisplayText: 0,
      activePanel: ''
    };
    this.isOn = false;
    this.isStrict = false;
    this.isGameRunning = false;
    this.isPlayerTurn = false;
    this.isSuccess = true;
    this.step = 0;
    this.aiPanelSequence = [];
    this.playerPanelSequence = [];

    //bind button  handlers to app's context
    this.handleOnButtonClick = this.handleOnButtonClick.bind(this);
    this.handleStartButtonClick = this.handleStartButtonClick.bind(this);
    this.handleStrictButtonClick = this.handleStrictButtonClick.bind(this);
    this.handlePanelClick = this.handlePanelClick.bind(this);
    this.handlePanelUnClick = this.handlePanelUnClick.bind(this);

    //create new sound object for panels
    this.panelSound = new Audio();

    //set some defaults for configuring the game
    this.stepsToWin = 20; //number of steps before winning the game.
    this.panelPlaySpeed = 1000; //speed in miliseconds (so 1000 = 1 second)
    this.debug = false;  //set to true to step on debug mode

    //some constants
    this.ERROR_MESSAGE = "!!";
  }
  render() {
    return <Game panelClicked={this.state.activePanel}
            onPanelClick={this.handlePanelClick}
            onPanelUnClick={ this.handlePanelUnClick }
            onStartClick={ this.handleStartButtonClick }
            onOnClick={ this.handleOnButtonClick }
            countDisplayText={this.state.countDisplayText}
            />;
  }
  /********************************************************************/
  /*Wrapper methods for control clicks                                */
  /********************************************************************/

  //handlePanelClick(panelClicked: object, clickEvent: object) -
  // handles activation of panels
  handlePanelClick(panelClicked, clickEvent){
    /*takes a reference 'panel' to panel object*/
    if(this.isOn){
      if(this.isPlayerTurn){
        this.activatePanel(panelClicked.props.id);
        return true;
      }
    }
    return false;
  }
  //handlePanelUnClick(clickEvent: object) - deactivate a panel when it loses focus
  // or mouse button is released
  handlePanelUnClick(panelClicked, clickEvent) {
    if(this.isOn){
      if(this.isPlayerTurn){
        this.deactivatePanel(panelClicked.props.id);
        this.updatePlayerTurn(panelClicked.props.id);
      return true;
      }
    }
    return false;
  }
  //handleOnButtonClick(clickEvent: object) - turn game on and off
  handleOnButtonClick(clickEvent){
    /*Toggles on state*/
    this.isOn = !this.isOn;
    this.isGameRunning = false;
    this.resetGame();
    return true;
  }
  //handleStartButtonClick(clickEvent: object) - start the ball rolling
  handleStartButtonClick(clickEvent){
    //button only works if the console turned on and game not currently running.
    if(this.isOn){
      if(!this.isGameRunning){
        console.log('start button clicked!');
        //toggles isGameRunning
        this.isGameRunning = true;
        //call takeTurn
        this.aiPlayerTurn();
        return true;
      } else {
        this.resetGame();
        this.aiPlayerTurn();
      }
    } else if(this.debug){
      this.isGameRunning = true;
      this.aiPlayerTurn();
      return true;
    }
    return false;

  }
  //handleStrictButtonClick(clickEvent: object) - switch on strict mode
  handleStrictButtonClick(clickEvent){
    /* toggles strict mode */
    return true;
  }
  /********************************************************************/
  /*Game Engine                                                       */
  /********************************************************************/
  //activatePanel(panelID: string) - activates panel with panelID (ex. "green")
  activatePanel(panelId){
    let newPanelId = panelId;
    this.setState((prevState, props) => ({
      activePanel: panelId
    }));
    if(this.isPlayerTurn){
      if(!this.isCorrectPanel(panelId)){
        this.handleError();
        return false;
      }
    }
    this.playPanelSound(newPanelId);
    return true;
  }
  //deactivatePanel(panelID: string) - deactivates panel with panelID (ex. "green")
  deactivatePanel(panelId){
    let newPanelId = panelId;
    this.setState((prevSate, props) => ({
      activePanel: ''
    }));
    if(this.isPlayerTurn){
      if(!this.isCorrectPanel(panelId)){
        newPanelId = "error";
      }
    }
    this.stopPanelSound(newPanelId);
  }
  //isCorrectPanel(panelId: string)
  isCorrectPanel(panelId){
    return panelId === this.playerPanelSequence[0];
  }
  //updateCountDisplayText(status: string) - updates count panel with current step and
  // can also pass optional status to update panel with.
  updateCountDisplayText(status = undefined){
    let update;
    if(status){
      update = status;
    } else{
      update = this.step;
    }
    this.setState(() => ({
      countDisplayText: update
    }));
  }
  //handleError() - handles errors on button presses
  handleError(){
    this.playPanelSound("error");
    this.updateCountDisplayText(this.ERROR_MESSAGE);
  }
  //playPanelSound(panelID: string) - plays sound associated with panel
  // use panelID = 'error' to play error sound
  playPanelSound(panelId){
    const sound1 = "media/simonSound1.mp3",
        sound2 = "media/simonSound2.mp3",
        sound3 = "media/simonSound3.mp3",
        sound4 = "media/simonSound4.mp3",
        soundError = sound4;
    let currentSound = "";

      switch(panelId){
            case "green":
              currentSound = sound1;
              break;
            case "red":
              currentSound = sound2;
              break;
            case "blue":
              currentSound = sound3;
              break;
            case "yellow":
              currentSound = sound4;
              break;
            case "error":
              currentSound = soundError; //temp sound
              break;
            default:
                console.log("WRONG ID FOR PANEL! CAN'T PLAY SOUND!");
        }

      if(currentSound != ""){
        this.panelSound.src = currentSound;
        this.panelSound.play();
      }

      //console.log('panel ' + panelId + ' turned on!');
  }
  //stopPanelSound(panelID: string) - plays sound associated with panel
  // use panelID = 'error' to play error sound
  //NOTE: currently not used because sounds do not loop
  stopPanelSound(panelId){
    //console.log('panel ' + panelId + ' turned off!');
  }
  //updatePlayerTurn(panelId: string) - main logic for evaluating player panel presses
  updatePlayerTurn(panelId){
    //1. check to see if panelId matches next item in sequence
    if(this.isCorrectPanel(panelId)){
      //2. if it does, then remove current item from sequence
      this.playerPanelSequence.shift();
      console.log("correct!");
      // 2a. check to see if sequence is over with. if it is, then switch to ai player
      //     and generate new sequence
      if(this.playerPanelSequence.length < 1){
        this.isPlayerTurn = false;
        window.setTimeout(this.aiPlayerTurn.bind(this), this.panelPlaySpeed);
      }
    //3. it does not match,
    } else {
      //3.a. signal an error and trigger ai to play sequence again
      console.log("Incorrect!");
      //need something to disable player hitting button but not disable deactivating current button???
      this.isPlayerTurn = false;
      this.playerPanelSequence = this.aiPanelSequence.slice();
      window.setTimeout(this.aiPlaySequence.bind(this), this.panelPlaySpeed);
      //console.log("Player sequence is: ");
      //console.log(this.playerPanelSequence);
      //console.log("and ai sequence is: ");
      //console.log(this.aiPanelSequence);
    }

    return true;
  }
  //aiPlayerTurn() - game loop for ai turn
  aiPlayerTurn(){
    //set player sequence to match ai sequence
    this.playerPanelSequence = this.aiPanelSequence.slice();
    //  update will add new step to sequence, make copy for player, and update step.
    this.aiUpdate();
    // play panel sequence
    this.aiPlaySequence();
    //update countDisplayText
    this.updateCountDisplayText();
    //switch back to player turn
  }
  //aiUPdate() - adds a new panel to sequence played by ai and increases step
  aiUpdate(){
    //add new step to sequence
    let newStep = this.generateRandomPanelSequence();
    this.aiPanelSequence.push(newStep);
    //now update player sequence to match it
    this.playerPanelSequence.push(newStep);
    //update step.
    this.step = ++this.step;
  }
  //aiPLaySequence(panelID: string, aiCurrentStep: int) - plays current sequence of panels
  aiPlaySequence(panelId = undefined, aiCurrentStep = undefined){
    //short circuit sequence if game switched off
    if(!this.isOn){ return true; }
    if(this.state.countDisplayText === this.ERROR_MESSAGE){
      this.updateCountDisplayText();
    }
    let sequenceToPlay = this.aiPanelSequence,
        panelToPlay;
    //if this is first time running sequence, set some state
    if(!aiCurrentStep){
      aiCurrentStep = 0;
      this.isPlayerTurn = false;
    }
    //if function called recursively
    if(panelId){
      this.deactivatePanel(panelId);
      //stop recursive call if sequence complete
      if(aiCurrentStep === this.step){
        this.isPlayerTurn = true;
        return true;
      }
    }
    aiCurrentStep += 1;
    panelToPlay = this.aiPanelSequence[aiCurrentStep-1];
    this.activatePanel(panelToPlay);
    //call next step in sequence
    window.setTimeout(this.aiPlaySequence.bind(this, panelToPlay, aiCurrentStep), this.panelPlaySpeed);
    return false;
  }
  //resetGame() - resests game state and interface
  resetGame(){
    this.panelSound.pause();
    this.aiPanelSequence = [];
    this.playerPanelSequence = [];
    this.step = 0;
    this.setState((prevState, props) => ({
      countDisplayText: 0,
      activePanel: ''
    }));
  }
  //generateRandomPanelSequence(random: int) - returns a random panelId string
  generateRandomPanelSequence(random = undefined){
  if(!random){
    random = this.getRandomIntInclusive(1, 4); //1 to 4 panels
  }
  switch(random){
    case 1:
      return 'green';
    case 2:
      return 'red';
    case 3:
      return 'blue';
    case 4:
      return 'yellow';
    default:
      console.log('ERROR!');
      return 'undefined';
    }
  }
  //getRandomIntInclusive(min: int, max: int) - returns a random number between
  // min and max that includes both.
  getRandomIntInclusive(min, max){
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }
}

App.defaultProps = {
};

export default App;
<commit_msg>Add pause between steps in playback sequence<commit_after>//import React, { Component } from 'react';
import React from 'react';
import './App.css';
import Game from './Game';

class App extends React.Component {
  constructor(props){
    super(props);
    //set the games state object
    this.state = {
      countDisplayText: 0,
      activePanel: ''
    };
    this.isOn = false;
    this.isStrict = false;
    this.isGameRunning = false;
    this.isPlayerTurn = false;
    this.isSuccess = true;
    this.step = 0;
    this.aiPanelSequence = [];
    this.playerPanelSequence = [];

    //bind button  handlers to app's context
    this.handleOnButtonClick = this.handleOnButtonClick.bind(this);
    this.handleStartButtonClick = this.handleStartButtonClick.bind(this);
    this.handleStrictButtonClick = this.handleStrictButtonClick.bind(this);
    this.handlePanelClick = this.handlePanelClick.bind(this);
    this.handlePanelUnClick = this.handlePanelUnClick.bind(this);

    //create new sound object for panels
    this.panelSound = new Audio();

    //set some defaults for configuring the game
    this.stepsToWin = 20; //number of steps before winning the game.
    this.debug = false;  //set to true to step on debug mode

    //some constants
    this.ERROR_MESSAGE = "!!";
    this.PLAY_SPEED = 1000; //speed in miliseconds (so 1000 = 1 second)
  }
  render() {
    return <Game panelClicked={this.state.activePanel}
            onPanelClick={this.handlePanelClick}
            onPanelUnClick={ this.handlePanelUnClick }
            onStartClick={ this.handleStartButtonClick }
            onOnClick={ this.handleOnButtonClick }
            countDisplayText={this.state.countDisplayText}
            />;
  }
  /********************************************************************/
  /*Wrapper methods for control clicks                                */
  /********************************************************************/

  //handlePanelClick(panelClicked: object, clickEvent: object) -
  // handles activation of panels
  handlePanelClick(panelClicked, clickEvent){
    /*takes a reference 'panel' to panel object*/
    if(this.isOn){
      if(this.isPlayerTurn){
        this.activatePanel(panelClicked.props.id);
        return true;
      }
    }
    return false;
  }
  //handlePanelUnClick(clickEvent: object) - deactivate a panel when it loses focus
  // or mouse button is released
  handlePanelUnClick(panelClicked, clickEvent) {
    if(this.isOn){
      if(this.isPlayerTurn){
        this.deactivatePanel(panelClicked.props.id);
        this.updatePlayerTurn(panelClicked.props.id);
      return true;
      }
    }
    return false;
  }
  //handleOnButtonClick(clickEvent: object) - turn game on and off
  handleOnButtonClick(clickEvent){
    /*Toggles on state*/
    this.isOn = !this.isOn;
    this.isGameRunning = false;
    this.resetGame();
    return true;
  }
  //handleStartButtonClick(clickEvent: object) - start the ball rolling
  handleStartButtonClick(clickEvent){
    //button only works if the console turned on and game not currently running.
    if(this.isOn){
      if(!this.isGameRunning){
        console.log('start button clicked!');
        //toggles isGameRunning
        this.isGameRunning = true;
        //call takeTurn
        this.aiPlayerTurn();
        return true;
      } else {
        this.resetGame();
        this.aiPlayerTurn();
      }
    } else if(this.debug){
      this.isGameRunning = true;
      this.aiPlayerTurn();
      return true;
    }
    return false;

  }
  //handleStrictButtonClick(clickEvent: object) - switch on strict mode
  handleStrictButtonClick(clickEvent){
    /* toggles strict mode */
    return true;
  }
  /********************************************************************/
  /*Game Engine                                                       */
  /********************************************************************/
  //activatePanel(panelID: string) - activates panel with panelID (ex. "green")
  activatePanel(panelId){
    let newPanelId = panelId;
    this.setState((prevState, props) => ({
      activePanel: panelId
    }));
    if(this.isPlayerTurn){
      if(!this.isCorrectPanel(panelId)){
        this.handleError();
        return false;
      }
    }
    this.playPanelSound(newPanelId);
    return true;
  }
  //deactivatePanel(panelID: string) - deactivates panel with panelID (ex. "green")
  deactivatePanel(panelId){
    let newPanelId = panelId;
    this.setState((prevSate, props) => ({
      activePanel: ''
    }));
    if(this.isPlayerTurn){
      if(!this.isCorrectPanel(panelId)){
        newPanelId = "error";
      }
    }
    this.stopPanelSound(newPanelId);
  }
  //isCorrectPanel(panelId: string)
  isCorrectPanel(panelId){
    return panelId === this.playerPanelSequence[0];
  }
  //updateCountDisplayText(status: string) - updates count panel with current step and
  // can also pass optional status to update panel with.
  updateCountDisplayText(status = undefined){
    let update;
    if(status){
      update = status;
    } else{
      update = this.step;
    }
    this.setState(() => ({
      countDisplayText: update
    }));
  }
  //handleError() - handles errors on button presses
  handleError(){
    this.playPanelSound("error");
    this.updateCountDisplayText(this.ERROR_MESSAGE);
  }
  //playPanelSound(panelID: string) - plays sound associated with panel
  // use panelID = 'error' to play error sound
  playPanelSound(panelId){
    const sound1 = "media/simonSound1.mp3",
        sound2 = "media/simonSound2.mp3",
        sound3 = "media/simonSound3.mp3",
        sound4 = "media/simonSound4.mp3",
        soundError = sound4;
    let currentSound = "";

      switch(panelId){
            case "green":
              currentSound = sound1;
              break;
            case "red":
              currentSound = sound2;
              break;
            case "blue":
              currentSound = sound3;
              break;
            case "yellow":
              currentSound = sound4;
              break;
            case "error":
              currentSound = soundError; //temp sound
              break;
            default:
                console.log("WRONG ID FOR PANEL! CAN'T PLAY SOUND!");
        }

      if(currentSound != ""){
        this.panelSound.src = currentSound;
        this.panelSound.play();
      }

      //console.log('panel ' + panelId + ' turned on!');
  }
  //stopPanelSound(panelID: string) - plays sound associated with panel
  // use panelID = 'error' to play error sound
  //NOTE: currently not used because sounds do not loop
  stopPanelSound(panelId){
    //console.log('panel ' + panelId + ' turned off!');
  }
  //updatePlayerTurn(panelId: string) - main logic for evaluating player panel presses
  updatePlayerTurn(panelId){
    //1. check to see if panelId matches next item in sequence
    if(this.isCorrectPanel(panelId)){
      //2. if it does, then remove current item from sequence
      this.playerPanelSequence.shift();
      console.log("correct!");
      // 2a. check to see if sequence is over with. if it is, then switch to ai player
      //     and generate new sequence
      if(this.playerPanelSequence.length < 1){
        this.isPlayerTurn = false;
        window.setTimeout(this.aiPlayerTurn.bind(this), this.PLAY_SPEED);
      }
    //3. it does not match,
    } else {
      //3.a. signal an error and trigger ai to play sequence again
      console.log("Incorrect!");
      //need something to disable player hitting button but not disable deactivating current button???
      this.isPlayerTurn = false;
      this.playerPanelSequence = this.aiPanelSequence.slice();
      window.setTimeout(this.aiPlaySequence.bind(this), this.PLAY_SPEED);
      //console.log("Player sequence is: ");
      //console.log(this.playerPanelSequence);
      //console.log("and ai sequence is: ");
      //console.log(this.aiPanelSequence);
    }

    return true;
  }
  //aiPlayerTurn() - game loop for ai turn
  aiPlayerTurn(){
    //set player sequence to match ai sequence
    this.playerPanelSequence = this.aiPanelSequence.slice();
    //  update will add new step to sequence, make copy for player, and update step.
    this.aiUpdate();
    // play panel sequence
    this.aiPlaySequence();
    //update countDisplayText
    this.updateCountDisplayText();
    //switch back to player turn
  }
  //aiUPdate() - adds a new panel to sequence played by ai and increases step
  aiUpdate(){
    //add new step to sequence
    let newStep = this.generateRandomPanelSequence();
    this.aiPanelSequence.push(newStep);
    //now update player sequence to match it
    this.playerPanelSequence.push(newStep);
    //update step.
    this.step = ++this.step;
  }
  //aiPLaySequence(panelID: string, aiCurrentStep: int) - plays current sequence of panels
  aiPlaySequence(panelId = undefined, aiCurrentStep = undefined){
    //short circuit sequence if game switched off
    if(!this.isOn){ return true; }
    if(this.state.countDisplayText === this.ERROR_MESSAGE){
      this.updateCountDisplayText();
    }
    let sequenceToPlay = this.aiPanelSequence,
        panelToPlay;
    //if this is first time running sequence, set some state
    if(!aiCurrentStep){
      aiCurrentStep = 0;
      this.isPlayerTurn = false;
    }
    //if function called recursively
    if(panelId){
      this.deactivatePanel(panelId);
      //stop recursive call if sequence complete
      if(aiCurrentStep === this.step){
        this.isPlayerTurn = true;
        return true;
      }
      //a pause between notes
      window.setTimeout(this.aiPlaySequence.bind(this, undefined, aiCurrentStep), this.PLAY_SPEED/4);
      return true;
    }
    aiCurrentStep += 1;
    panelToPlay = this.aiPanelSequence[aiCurrentStep-1];
    this.activatePanel(panelToPlay);
    //call next step in sequence
    window.setTimeout(this.aiPlaySequence.bind(this, panelToPlay, aiCurrentStep), this.PLAY_SPEED);
    return false;
  }
  //resetGame() - resests game state and interface
  resetGame(){
    this.panelSound.pause();
    this.aiPanelSequence = [];
    this.playerPanelSequence = [];
    this.step = 0;
    this.setState((prevState, props) => ({
      countDisplayText: 0,
      activePanel: ''
    }));
  }
  //generateRandomPanelSequence(random: int) - returns a random panelId string
  generateRandomPanelSequence(random = undefined){
  if(!random){
    random = this.getRandomIntInclusive(1, 4); //1 to 4 panels
  }
  switch(random){
    case 1:
      return 'green';
    case 2:
      return 'red';
    case 3:
      return 'blue';
    case 4:
      return 'yellow';
    default:
      console.log('ERROR!');
      return 'undefined';
    }
  }
  //getRandomIntInclusive(min: int, max: int) - returns a random number between
  // min and max that includes both.
  getRandomIntInclusive(min, max){
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }
}

App.defaultProps = {
};

export default App;
<|endoftext|>


<commit_before>// This is to add non contract binding data into Dapp.
// May be replaced with IPFS at some point.
let Data = [
  {
    name: 'Ethereum London November 2017',
    address: '0xda0ec6ef1288cf3829d0cd499a626a107ef3943d',
    date:'Wednesday, November 15, 2017 6:25 PM to 9:00 PM(UTC+1)',
    map_url: 'https://www.google.com/maps?f=q&hl=en&q=Huxley+Building,+Imperial+College+,+London+SW7+2AZ,+gb',
    location_text: 'Clore Lecture Theatre, Huxley Building, Imperial College , London SW7 2AZ',
    description_text: ''
  },
  {
    name: 'Devcon3 dinner for global Ethereum meetup organisers',
    address: '0x6f36d375c11f410d7dc4c170b1f14af601a4d108',
    date:'Wednesday, November 1, 2017 6:30 PM ~ (UTC-05:00)',
    map_url: 'https://www.google.co.uk/maps/place/La+Isla+Shopping+Village/@21.1108433,-86.7653545,17z/data=!3m1!4b1!4m5!3m4!1s0x8f4c285f9f1c5055:0xc2d79d4d1a890dc7!8m2!3d21.1108433!4d-86.7631658',
    location_text: 'Hotel Zone, Blvd. Kukulcan, La Isla Shopping Village Km.12, TEL. 883-0902 883-0897',
    description_text: "Cambalache steak house (price range $26 or over). Chance to chat with other Ethereum meetup organisers around the world over dinner."
  },
  {
    name: 'CodeUp #23',
    address: '0x015b631f1ea6434b1a71ed1bff5ac38b79e7f5c4',
  },
  {
    name: 'Ethereum London October 2017',
    address: '0xf618af176f6521ae0ab249133740dd173c3e43e1',
    date:'Wednesday, October 11, 2017 6:25 PM to 9:00 PM(UTC+1)',
    map_url: 'https://www.google.com/maps/place/Imperial+College+London/@51.4987997,-0.1770659,17z/data=!3m1!4b1!4m5!3m4!1s0x48760567da220a01:0x31911b371c692e86!8m2!3d51.4987997!4d-0.1748772?hl=en',
    location_text: 'Sir Alexander Fleming Building (SAF) LT1 G16',
    description_text: ''
  },
  {
    name: 'Ethereum London September 2017',
    address: '0x56812b5b1c3594af9e0b8a22d07025f5ee3debcd',
    date:'Wednesday, September 13, 2017 6:45 PM to 9:00 PM(UTC+1)',
    map_url: 'https://maps.google.com/maps?f=q&hl=en&q=Huxley+Building%2C+Imperial+College+%2C+London+SW7+2AZ%2C+gb',
    location_text: 'Clore Lecture Theatre, Huxley Building, Imperial College, London (SW7 2AZ)',
    description_text: ''
  },
  {
    name: 'CodeUp #22',
    address: '0x03738b2fd7ab1d8b3003c3e4d83864eef636bed2',
    date:'Sep 7th (Thur) 6:30 PM(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'CodeUp #21',
    address: '0x97a6ec1ea5810388b6cb513b087e55a65c4bf417',
    date:'Jun 22nd (Thur) 6:30 PM(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'Edcon Post conference lunch',
    address: '0x7b249881af36cccd1ab2e4325a8eed2a7848b263',
    date:'Feb 19th (Sun) 12:30(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Mama+Shelter+Paris/@48.8597157,2.4006691,17z/data=!4m5!3m4!1s0x47e66d8670ddcb91:0xb81d5c1e065c8167!8m2!3d48.8597122!4d2.4028631',
    location_text: 'Mama Shelter Paris (109 Rue de Bagnolet, 75020 Paris)',
    description_text: "Mama Shelter Paris is a restaurant of the hotel all the Edcon speakers stay. Their brunch buffet(42€) is a bit pricy but very high quality and quantity, according to @jdetychey"
  },
  {
    name: 'DevCon2 Pre conference dinner',
    address: '0x7473a821fffc1e75524f9b99d6d4e9a2f9c7b12e',
    date: 'Sep 18th (Sun) 7pm(UTC+8)',
    map_url: 'https://goo.gl/maps/Uty16SUcxd42',
    location_text: 'The lobby at Hyatt On the bund (199 Huangpu Road, Shanghai)',
    description_text: "After meeting at the lobby, we will head to  Lost Heaven(17 Yan An Dong Lu, Huangpu District). The table of 10 is booked under Makoto"
  },
]
module.exports = Data;
<commit_msg>Add new schedule<commit_after>// This is to add non contract binding data into Dapp.
// May be replaced with IPFS at some point.
let Data = [
  {
    name: 'CodeUp #24',
    address: null,
    date:'Nov 28th (Tues) 6:30 PM(UTC)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'Ethereum London November 2017',
    address: '0xda0ec6ef1288cf3829d0cd499a626a107ef3943d',
    date:'Wednesday, November 15, 2017 6:25 PM to 9:00 PM(UTC+1)',
    map_url: 'https://www.google.com/maps?f=q&hl=en&q=Huxley+Building,+Imperial+College+,+London+SW7+2AZ,+gb',
    location_text: 'Clore Lecture Theatre, Huxley Building, Imperial College , London SW7 2AZ',
    description_text: ''
  },
  {
    name: 'Devcon3 dinner for global Ethereum meetup organisers',
    address: '0x6f36d375c11f410d7dc4c170b1f14af601a4d108',
    date:'Wednesday, November 1, 2017 6:30 PM ~ (UTC-05:00)',
    map_url: 'https://www.google.co.uk/maps/place/La+Isla+Shopping+Village/@21.1108433,-86.7653545,17z/data=!3m1!4b1!4m5!3m4!1s0x8f4c285f9f1c5055:0xc2d79d4d1a890dc7!8m2!3d21.1108433!4d-86.7631658',
    location_text: 'Hotel Zone, Blvd. Kukulcan, La Isla Shopping Village Km.12, TEL. 883-0902 883-0897',
    description_text: "Cambalache steak house (price range $26 or over). Chance to chat with other Ethereum meetup organisers around the world over dinner."
  },
  {
    name: 'CodeUp #23',
    address: '0x015b631f1ea6434b1a71ed1bff5ac38b79e7f5c4',
    date:'Oct 18th (Tues) 6:30 PM(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'Ethereum London October 2017',
    address: '0xf618af176f6521ae0ab249133740dd173c3e43e1',
    date:'Wednesday, October 11, 2017 6:25 PM to 9:00 PM(UTC+1)',
    map_url: 'https://www.google.com/maps/place/Imperial+College+London/@51.4987997,-0.1770659,17z/data=!3m1!4b1!4m5!3m4!1s0x48760567da220a01:0x31911b371c692e86!8m2!3d51.4987997!4d-0.1748772?hl=en',
    location_text: 'Sir Alexander Fleming Building (SAF) LT1 G16',
    description_text: ''
  },
  {
    name: 'Ethereum London September 2017',
    address: '0x56812b5b1c3594af9e0b8a22d07025f5ee3debcd',
    date:'Wednesday, September 13, 2017 6:45 PM to 9:00 PM(UTC+1)',
    map_url: 'https://maps.google.com/maps?f=q&hl=en&q=Huxley+Building%2C+Imperial+College+%2C+London+SW7+2AZ%2C+gb',
    location_text: 'Clore Lecture Theatre, Huxley Building, Imperial College, London (SW7 2AZ)',
    description_text: ''
  },
  {
    name: 'CodeUp #22',
    address: '0x03738b2fd7ab1d8b3003c3e4d83864eef636bed2',
    date:'Sep 7th (Thur) 6:30 PM(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'CodeUp #21',
    address: '0x97a6ec1ea5810388b6cb513b087e55a65c4bf417',
    date:'Jun 22nd (Thur) 6:30 PM(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Simply+Business/@51.51528,-0.0904011,15z/data=!4m5!3m4!1s0x0:0x70f23f24baccffdc!8m2!3d51.51528!4d-0.0904011',
    location_text: 'Simply Business (99 Gresham St, London EC2V 7NG)',
    description_text: ''
  },
  {
    name: 'Edcon Post conference lunch',
    address: '0x7b249881af36cccd1ab2e4325a8eed2a7848b263',
    date:'Feb 19th (Sun) 12:30(UTC+1)',
    map_url: 'https://www.google.co.uk/maps/place/Mama+Shelter+Paris/@48.8597157,2.4006691,17z/data=!4m5!3m4!1s0x47e66d8670ddcb91:0xb81d5c1e065c8167!8m2!3d48.8597122!4d2.4028631',
    location_text: 'Mama Shelter Paris (109 Rue de Bagnolet, 75020 Paris)',
    description_text: "Mama Shelter Paris is a restaurant of the hotel all the Edcon speakers stay. Their brunch buffet(42€) is a bit pricy but very high quality and quantity, according to @jdetychey"
  },
  {
    name: 'DevCon2 Pre conference dinner',
    address: '0x7473a821fffc1e75524f9b99d6d4e9a2f9c7b12e',
    date: 'Sep 18th (Sun) 7pm(UTC+8)',
    map_url: 'https://goo.gl/maps/Uty16SUcxd42',
    location_text: 'The lobby at Hyatt On the bund (199 Huangpu Road, Shanghai)',
    description_text: "After meeting at the lobby, we will head to  Lost Heaven(17 Yan An Dong Lu, Huangpu District). The table of 10 is booked under Makoto"
  },
]
module.exports = Data;
<|endoftext|>


<commit_before>module.exports = function(myApp){
    var debug = require('debug')('module:storage:memory');

    if (typeof myApp.storage !== "undefined") {
        debug(':: WARN :: storage '+myApp.storage.module+' already loaded.  module not loaded...');
        return;
    }

    var storage = { module: "memory" };
    var memory = {};

    storage.initialize = function(){
        debug('initialized...');
    };

    storage.get = function(field, callback) {
        if (typeof memory[field] !== "undefined") {
            debug('get() - ' + field + ' exists');
            if (typeof callback === "function") {
                process.nextTick(function() { callback(null, memory[field]) });
            }
        } else {
            debug('get() - ' + field + ' does NOT exist');
            if (typeof callback === "function") {
                process.nextTick(function() { callback(true, undefined) });
            }
        }
        return;
    };

    storage.set = function(field, data, callback) {
        memory[field] = data;
        if (memory[field] === data) {
            debug('set() - success : ' + field);
            if (typeof callback === "function") {
                process.nextTick(function() { callback(null, memory[field]) });
            }
        } else {
            debug('set() - failed : ' + field);
            if (typeof callback === "function") {
                process.nextTick(function() { callback(true, undefined) });
            }
        }
        return;
    };

    myApp.storage = storage;
    debug('loaded...');
};
<commit_msg>Update memory.js<commit_after>module.exports = function(myApp){
    var debug = require('debug')('module:storage:memory');

    if (typeof myApp.storage !== "undefined") {
        debug(':: WARN :: storage '+myApp.storage.module+' already loaded.  module not loaded...');
        return;
    }

    var storage = { module: "memory" };
    var memory = {};

    storage.initialize = function(){
        debug('initialized...');
    };

    storage.get = function(field, callback) {
        if (typeof memory[field] !== "undefined") {
            debug('get() - ' + field + ' exists');
            if (typeof callback === "function") {
                process.nextTick(function() { callback(null, memory[field]); });
            }
        } else {
            debug('get() - ' + field + ' does NOT exist');
            if (typeof callback === "function") {
                process.nextTick(function() { callback(true, undefined); });
            }
        }
        return;
    };

    storage.set = function(field, data, callback) {
        memory[field] = data;
        if (memory[field] === data) {
            debug('set() - success : ' + field);
            if (typeof callback === "function") {
                process.nextTick(function() { callback(null, memory[field]); });
            }
        } else {
            debug('set() - failed : ' + field);
            if (typeof callback === "function") {
                process.nextTick(function() { callback(true, undefined); });
            }
        }
        return;
    };

    myApp.storage = storage;
    debug('loaded...');
};
<|endoftext|>


<commit_before>import QUnit from "qunitjs";
import {remove} from "../../../../dom/manipulate";

QUnit.module("dom/manipulate/remove()",
    {
        beforeEach: function ()
        {
            document.getElementById("qunit-fixture").innerHTML = `

            `;
        }
    }
);

QUnit.test(
    "remove() on existent element",
    function (assert)
    {
        const id = "first";
        remove(document.getElementById(id));

        assert.ok(document.getElementById("parent"), "parent still exists");
        assert.notOk(document.getElementById(id), "has no occurrence");

    }
);

QUnit.test(
    "remove() on non-existent element (fails)",
    function (assert)
    {

        assert.throws(
            () => {
                remove(null);
            },
            "function threw an error"
        );
    }
);
<commit_msg>add new unit tests and rename old to fit the new names<commit_after>import QUnit from "qunitjs";
import {remove} from "../../../../dom/manipulate";

QUnit.module("dom/manipulate/remove()",
    {
        beforeEach: () =>
        {
            document.getElementById("qunit-fixture").innerHTML = `

            `;
        },
    }
);

QUnit.test(
    "with valid node element",
    (assert) =>
    {
        const id = "first";
        remove(document.getElementById(id));

        assert.ok(document.getElementById("parent"), "parent still exists");
        assert.notOk(document.getElementById(id), "has no occurrence");
    }
);

QUnit.test(
    "with an array of elements",
    (assert) =>
    {
        const firstId = "first";
        const secondId = "second";

        remove([
            document.getElementById(firstId),
            document.getElementById(secondId)
        ]);

        assert.notOk(document.getElementById(firstId), "first element has no occurrence");
        assert.notOk(document.getElementById(secondId), "second element has no occurrence");
        assert.ok(document.getElementById("third"), "third element has not been removed");
    }
);

QUnit.test(
    "with an (query) string as an element",
    (assert) =>
    {
        assert.throws(
            () => {
                remove("#first");
            },
            "function threw an error"
        );
    }
);

QUnit.test(
    "with an empty array",
    (assert) =>
    {
        assert.throws(
            () => {
                remove([]);
            },
            "function threw an error"
        );
    }
);

QUnit.test(
    "with an invalid element",
    (assert) =>
    {
        assert.throws(
            () => {
                remove(null);
            },
            "function threw an error"
        );
    }
);
<|endoftext|>


<commit_before>var fs = require('fs');

var sensors = {};

/* Synchronously load the available sensors */
function loadSensors(sensors_file) {
    if (!fs.existsSync(sensors_file)) {
        throw "No sensors file at : " + sensors_file;
    }

    var lines = String(fs.readFileSync(sensors_file)).split('\n');
    for(var i in lines) {
        if (lines[i].charAt(0) == '#') {
            continue;
        }
        if (lines[i] === '') {
            continue;
        }

        var elements = lines[i].split('\t');
        if (elements.length != 4) {
            throw "Invalid formatting in " + sensors_file;
        }
        sensors[elements[0]] = {'id': elements[1],
                      'warning-temp': elements[2], 'alarm-temp': elements[3]};
    }
    return sensors;
}

function availableSensors() {
    return Object.keys(sensors);
}

function readSensor(name, callback) {
    var sensor = sensors[name];
    if (sensor === undefined) {
        throw "No such sensor: " + name;
    }

    var sensor_path = "/sys/bus/w1/devices/" + sensor.id + "/w1_slave";
    fs.exists(sensor_path, function(exists) {
        if (!exists) {
            throw sensor_path + " doesn't exist";
        }
        fs.readFile(sensor_path, {'encoding': 'utf8'}, function(err, data) {
            if (err) {
                throw err;
            }
            var lines = data.split('\n');
            if (lines.length < 2) {
                throw "Invalid sensor data: " + data;
            }
            if (!lines[0].match(/ YES$/)) {
                callback({'error': 'Failed to read sensor'});
                return;
            }

            var temp_pattern = /t=\d*/;
            var temp_string = temp_pattern.exec(lines[1]);
            if (temp_string === null) {
                callback({'error': 'Failed to read sensor'});
                return;
            }
            temp_string = String(temp_string).substr(2);
            var temp = parseFloat(temp_string) / 1000;
            callback({'temp': temp, 'alarm': false, 'panic': false});
        });
    });
}

exports.loadSensors = loadSensors;
exports.availableSensors = availableSensors;
exports.readSensor = readSensor;
<commit_msg>sensors: Start setup for cached sensors<commit_after>var fs = require('fs');

var sensors = {};

var cache = {};

/* Synchronously load the available sensors */
function loadSensors(sensors_file) {
    if (!fs.existsSync(sensors_file)) {
        throw "No sensors file at : " + sensors_file;
    }

    var lines = String(fs.readFileSync(sensors_file)).split('\n');
    for(var i in lines) {
        if (lines[i].charAt(0) == '#') {
            continue;
        }
        if (lines[i] === '') {
            continue;
        }

        var elements = lines[i].split('\t');
        if (elements.length != 4) {
            throw "Invalid formatting in " + sensors_file;
        }
        sensors[elements[0]] = {'id': elements[1],
                      'warning-temp': elements[2], 'alarm-temp': elements[3]};
    }
    cache.global_alarm = false;
    cache.global_panic = false;
    return sensors;
}

function availableSensors() {
    return Object.keys(sensors);
}

function readSensorHW(name, callback) {
    var sensor = sensors[name];
    if (sensor === undefined) {
        throw "No such sensor: " + name;
    }

    var sensor_path = "/sys/bus/w1/devices/" + sensor.id + "/w1_slave";
    fs.exists(sensor_path, function(exists) {
        if (!exists) {
            throw sensor_path + " doesn't exist";
        }
        fs.readFile(sensor_path, {'encoding': 'utf8'}, function(err, data) {
            if (err) {
                throw err;
            }
            var lines = data.split('\n');
            if (lines.length < 2) {
                throw "Invalid sensor data: " + data;
            }
            if (!lines[0].match(/ YES$/)) {
                callback({'error': 'Failed to read sensor'});
                return;
            }

            var temp_pattern = /t=\d*/;
            var temp_string = temp_pattern.exec(lines[1]);
            if (temp_string === null) {
                callback({'error': 'Failed to read sensor'});
                return;
            }
            temp_string = String(temp_string).substr(2);
            var temp = parseFloat(temp_string) / 1000;
            callback({'temp': temp, 'alarm': false, 'panic': false});
        });
    });
}

function readSensorCache(name, callback) {
    var sensor = cache[name];

    if (sensor === undefined) {
        callback({'error': 'No data available for sensor ' + name});
        return;
    }

    callback(sensor);
}

exports.loadSensors = loadSensors;
exports.availableSensors = availableSensors;
exports.readSensor = readSensorCache;
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const _ = require('lodash');
const Promise = require('bluebird');
const fs = require('fs-extra');
const chalk = require('chalk');
const DataTree = require('./data-tree');
const serverUtils = require('../server-utils');

module.exports = class ReportBuilder {
    static create(srcPaths, destPath) {
        return new this(srcPaths, destPath);
    }

    constructor(srcPaths, destPath) {
        this.srcPaths = srcPaths;
        this.destPath = destPath;
    }

    async build() {
        await moveContentToReportDir({from: this.srcPaths[0], to: this.destPath});

        const srcReportsData = this._loadReportsData();
        const dataTree = DataTree.create(srcReportsData[0], this.destPath);
        const srcDataCollection = _.zipObject(this.srcPaths.slice(1), srcReportsData.slice(1));

        const mergedData = await dataTree.mergeWith(srcDataCollection);

        await this._saveDataFile(mergedData);
    }

    _loadReportsData() {
        return _(this.srcPaths)
            .map((reportPath) => {
                const srcDataPath = path.resolve(reportPath, 'data');

                try {
                    return serverUtils.require(srcDataPath);
                } catch (err) {
                    serverUtils.logger.warn(chalk.yellow(`Not found data file in passed source report path: ${reportPath}`));
                    return {skips: [], suites: []};
                }
            })
            .value();
    }

    async _copyToReportDir(files, {from, to}) {
        await Promise.map(files, async (dataName) => {
            const srcDataPath = path.resolve(from, dataName);
            const destDataPath = path.resolve(to, dataName);

            await fs.move(srcDataPath, destDataPath);
        });
    }

    async _saveDataFile(data) {
        const formattedData = serverUtils.prepareCommonJSData(data);
        const destDataPath = path.resolve(this.destPath, 'data.js');

        await fs.writeFile(destDataPath, formattedData);
    }
};

async function moveContentToReportDir({from, to}) {
    const files = await fs.readdir(path.resolve(from));

    await Promise.map(files, async (fileName) => {
        if (fileName === 'data.js') {
            return;
        }

        const srcFilePath = path.resolve(from, fileName);
        const destFilePath = path.resolve(to, fileName);

        await fs.move(srcFilePath, destFilePath, {overwrite: true});
    });
}
<commit_msg>chore(merge-reports): remove unused code<commit_after>'use strict';

const path = require('path');
const _ = require('lodash');
const Promise = require('bluebird');
const fs = require('fs-extra');
const chalk = require('chalk');
const DataTree = require('./data-tree');
const serverUtils = require('../server-utils');

module.exports = class ReportBuilder {
    static create(srcPaths, destPath) {
        return new this(srcPaths, destPath);
    }

    constructor(srcPaths, destPath) {
        this.srcPaths = srcPaths;
        this.destPath = destPath;
    }

    async build() {
        await moveContentToReportDir({from: this.srcPaths[0], to: this.destPath});

        const srcReportsData = this._loadReportsData();
        const dataTree = DataTree.create(srcReportsData[0], this.destPath);
        const srcDataCollection = _.zipObject(this.srcPaths.slice(1), srcReportsData.slice(1));

        const mergedData = await dataTree.mergeWith(srcDataCollection);

        await this._saveDataFile(mergedData);
    }

    _loadReportsData() {
        return _(this.srcPaths)
            .map((reportPath) => {
                const srcDataPath = path.resolve(reportPath, 'data');

                try {
                    return serverUtils.require(srcDataPath);
                } catch (err) {
                    serverUtils.logger.warn(chalk.yellow(`Not found data file in passed source report path: ${reportPath}`));
                    return {skips: [], suites: []};
                }
            })
            .value();
    }

    async _saveDataFile(data) {
        const formattedData = serverUtils.prepareCommonJSData(data);
        const destDataPath = path.resolve(this.destPath, 'data.js');

        await fs.writeFile(destDataPath, formattedData);
    }
};

async function moveContentToReportDir({from, to}) {
    const files = await fs.readdir(path.resolve(from));

    await Promise.map(files, async (fileName) => {
        if (fileName === 'data.js') {
            return;
        }

        const srcFilePath = path.resolve(from, fileName);
        const destFilePath = path.resolve(to, fileName);

        await fs.move(srcFilePath, destFilePath, {overwrite: true});
    });
}
<|endoftext|>


<commit_before><commit_msg>Convert null to Array<commit_after><|endoftext|>


<commit_before>/*
TODO:
otestovat
ukladat paramy do pameti uzlu??
pridat callbacky
checknout pravidla pro selecty a radia

custom classy
zmena DOMu
dogenerovani hlasek
error hlasky

definovani pravidel pro inputz pomoci trid
predani nastaveni inputu pomoci configu

fix focusout + change
parser reg rename
*/

(function($) {

	$.bValidator = {

		defaults: {
		},

		validations: {},

		transformations: {},

		//settings: {},

		init: function(form, settings) {
			var plugin = this;
			plugin.destruct(form);

			form.data('bValidator', settings);

			var inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.each(function (){
				$(this).on('focusin.bValidator', function() {
					plugin.focus($(this));
				});

				$(this).on('focusout.bValidator', function() {
					plugin.validate($(this));
				});

				$(this).on('change.bValidator', function() {
					plugin.validate($(this));
				});

				plugin.initInput($(this));
			});

			//plugin.settings: $.extend({}, defaults, options);

			form.on('submit.bValidator', function(e) {
				var settings = $(this).data('bValidator');
				var bValid = true;
				var inputs = $('input[data-bvString], input[data-bvStrict], textarea', $(this));

				inputs.each(function() {
					if(!plugin.validate($(this))) bValid = false;
				});

				if(!bValid) {
					settings.onSubmitFail.call( this, e );
					e.preventDefault();
				} else {
					inputs.each(function() {
						plugin.focus($(this));
					});
					//console.log(settings);
					settings.beforeSubmit.call( this, this, e );
				}
			});

		},

		getConfig: function(elem) {
			conf = {};
			// switch value - erase inputs with this value. Fill value of empty inputs on focus out
			conf['switchVal'] = (elem.attr('data-bvSwitch') == undefined ? '' : elem.attr('data-bvSwitch'));
			// prepended value
			conf['prepend'] = (elem.attr('data-bvPrepend') == undefined ? '' : elem.attr('data-bvPrepend'));
			// key string
			conf['string'] = (elem.attr('data-bvString') == undefined ? '.*' : elem.attr('data-bvString'));
			// appended value
			conf['append'] = (elem.attr('data-bvAppend') == undefined ? '' : elem.attr('data-bvAppend'));
			// string transformation
			conf['transform'] = (elem.attr('data-bvTransform') == undefined ? '' : elem.attr('data-bvTransform'));
			// pattern for regexp
			var pattern = '('+conf['prepend']+')?'+'('+conf['string']+')('+conf['append']+')?'+'';
			var re = new RegExp(pattern, 'i');
			// new string value
			conf['newString'] = elem.val().match(re)[2];
			// string which fill for empty inputs
			conf['empty'] = (elem.attr('data-bvEmpty') == undefined ? '' : elem.attr('data-bvEmpty'));
			// rules for real validation
			conf['strict'] = (elem.attr('data-bvStrict') == undefined ? '' : elem.attr('data-bvStrict'));

			return conf;
		},

		initInput: function(elem) {
			conf = this.getConfig(elem);

			conf['prepend'] = conf['prepend'].replace(/\\|\?/g,'');
			conf['append'] = conf['append'].replace(/\\|\?/g,'');
			if(!elem.val() || elem.val() == conf['empty'] || conf['newString'] == '') {
				if(conf['empty'] == '' && conf['switchVal'] == '') elem.val(conf['prepend']+conf['append']);
				else if(conf['switchVal'] == '') elem.val(conf['empty']);
				else elem.val(conf['switchVal']);
				//elem.addClass('grey');
			}
			else {
				if(conf['transform']) conf['newString'] = this.transform(conf['newString'], conf['transform']);
				elem.val(conf['prepend']+conf['newString']+conf['append']);
				//elem.removeClass('grey');
			}
			return conf;
		},

		focus: function(elem) {
			conf = this.getConfig(elem);

			if(elem.val() == conf['switchVal']) elem.val('');
			else elem.val($.trim(conf['newString']));
			//elem.removeClass('grey');
			//this.clean(elem);
		},

		isValid: function(value, rule, elem) {

			if(typeof value === 'undefined') {
				var conf = this.initInput(elem);
				var value = conf['newString'];
			}

			if(typeof rule === 'undefined') {
				var conf = this.initInput(elem);
				var rule = conf['strict'];
			}

			var plugin = this;

			var result = false;

			var ruleEscaped = rule.replace(/({{((?!}}).)*}})/g, '{{NOPARSE}}');

			var ruleReplacements = rule.match(/({{((?!}}).)*}})/g);

			var rulesOr = ruleEscaped.split('|');

			//rulesAnd.each();

			$.each(rulesOr, function(indexOr, ruleOr) {

				var rulesAnd = ruleOr.split('&');

				var resultAnd = true;

				$.each(rulesAnd, function(indexAnd, ruleAnd) {

					var args = ruleAnd.split(':');

					for (var i = 0; i < args.length; i++) {
						if(args[i].match(/\{\{NOPARSE\}\}/) !== null) {
							var replacement = ruleReplacements.shift();
							args[i] = args[i].replace('{{NOPARSE}}', replacement.slice(2, -2));
						}
					};

					/*console.log(args);
					console.log(value);
					console.log(rule);
					console.log(elem);*/

					/*if(typeof this.validations[rule] === 'undefined') {
						if(value.match(rule) == null) {
							resultAnd = false;
							return;
						}
					} else {*/
						//console.log(args);

						if(!plugin.validations[args[0]].func(value, args, elem)) {
							resultAnd = false;
							return;
						}
					//}

				});

				if(resultAnd == true) {
					result = true;
					return;
				}

				/*var args = ruleOr.split(':');

				if(plugin.validations[args[0]].func(value, args)) {
					result = true;
					return;
				}
				console.log(args);*/
				//console.log(val);

				//console.log(rulesAnd);

			});

			//console.log(rulesAnd);

			return result;

			/*if(rule.indexOf("\\|") != -1) {
				if(typeof this.validations[rule] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[rule].func(value);
			} else {
				var args = rule.split('|');
				if(typeof this.validations[args[0]] === 'undefined') {
					return (value.match(rule) != null);
				}
				return this.validations[args[0]].func(value, args);
			}*/
		},

		validate: function(elem) {
			this.clean(elem);
			conf = this.initInput(elem);

			if(this.isValid(conf['newString'], conf['strict'], elem)) return this.valid(elem);
			else return this.invalid(elem);
		},

		validation: function() {
			this.validations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		transform: function(value, method) {
			return this.transformations[method].func(value);
		},

		transformation: function() {
			this.transformations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		clean: function(elem) {
			elem.removeClass('error').removeClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).removeClass('error').removeClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').removeClass('error').removeClass('valid');
			//elem.parents('.row').removeClass('error').removeClass('valid');
		},

		valid: function(elem) {
			elem.addClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('valid');

			//elem.parents('.row').addClass('valid');
			//elem.parents('.row').find('.error-message').addClass('hidden');
			return true;
		},

		invalid: function(elem) {
			elem.addClass('error');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('error');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('error');

			//elem.parents('.row').addClass('error');
			//elem.parents('.row').find('.error-message').removeClass('hidden');
			return false;
		},

		destruct: function(form) {
			form.unbind('.bValidator');

			var inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.unbind('.bValidator');

			form.removeData('bValidator');
		}

	}

	$.fn.bValidator = function(options, args) {

		if(typeof options == 'string' && options == 'isValid') {
			var valid = true;
			this.each(function() {
				if(typeof args === 'undefined') {
					args = Array();
				}
				if(!$.bValidator.isValid(undefined, args[0], $(this))) {
					valid =  false;
					return;
				}
			});
			return valid;
		}

		var settings = $.extend({
			beforeSubmit: function() {},
			onSubmitFail: function() {}
		}, options );

		return this.each(function() {
			if(typeof options == 'string') {
				switch(options) {
					case 'validate':
						return $.bValidator.validate($(this));
						break;
					case 'destruct':
						return $.bValidator.destruct($(this));
						break;
					}
			} else {
				$this = $(this);
				//if($this.is('form')) $.bValidator.init($this, settings);
				//else $.bValidator.init($this.find('form'), settings);

				if(!$this.is('form')) $this = $this.find('form');

				return $this.each(function() {
					$.bValidator.init($(this), settings);
				});
			}
			//if (undefined == $(this).data('bValidator')) {
				//var plugin = new $.bValidator.init();
				//$(this).data('bValidator', plugin);
			//}
		});

	}

})(jQuery);

jQuery.bValidator
.validation('number', function(value, args) {
	valid = (value.match(/^[0-9]+$/) != null);
	if(!valid) return false;
	if(typeof args[1] != 'undefined') {
		intVal = parseInt(value);
		if(args[1] != '') {
			if(intVal < args[1]) return false;
		}
		if(typeof args[2] != 'undefined') {
			if(args[2] != '') {
				if(intVal > args[2]) return false;
			}
		}
	}
	return true;
})
.validation('empty', function(value) {
	return (value == '');
})
.validation('if', function(value, args, elem) {
	// arg[0] = rule name -> if
	// arg[1] = name of other input
	// arg[2] = name of other input rule
	// arg[3] = name of current input rule
	var input = elem.parents('form').find('[name="'+args[1]+'"]');
	if(input.bValidator('isValid', Array(args[2]))) {
		return (elem.bValidator('isValid', Array(args[3])));
	} else return true;

})
.validation('same', function(value, args) {
	return (value == $('form [name="'+args[1]+'"]').val());
})
.validation('reg', function(value, args) {
	return (value.match(args[1]) != null);
})
.validation('string', function(value) {
	return (value.match(/^.+$/) != null);
})
.validation('email', function(value) {
	return (value.match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) != null && value.length != 0);
})
.validation('zip', function(value) {
	return (value.match(/^[0-9]{5}$/) != null);
})
.validation('city', function(value) {
	return (value.match(/^.{2,}$/) != null);
})
.validation('date-d.m.yy', function(value) {
	return (value.match(/^[0123]?[0-9]\.[01]?[0-9]\.[12][09][0-9][0-9]$/) != null);
})
.validation('nin', function(value) {
	return (value.match(/^[0-9]{6}\/[0-9]{3,4}$/) != null);
})
.validation('false', function(value) {
	return false;
})
.validation('true', function(value) {
	return true;
})
.validation('checked', function(value, args, elem) {
	return $(elem).prop('checked');
})
.validation('phone', function(value) {
	var same = 0;
	var inc = 0;
	var i;

	var pnumber = value;

	if(!pnumber.match(/^[0-9]{9}$/)) {
		return false;
	}

	for(i = 4;i < 9;i++) {
	if(i != 3 && pnumber.charAt(i) == pnumber.charAt(i - 1)) {
		same++;
	}
	if(parseInt(pnumber.charAt(i)) == (parseInt(pnumber.charAt(i - 1)) + 1) || (pnumber.charAt(i) == '0' && pnumber.charAt(i - 1) == '9')) {
		inc++;
	}
	}
	if(same >= 4 || inc >= 5) {
	return false;
	}
	return true;
})
.transformation('noSpaces', function(value) {
	return value.replace(/ /g,'');
});<commit_msg>comments<commit_after>/*
url: https://github.com/jBenes/bSlider

TODO:
otestovat
ukladat paramy do pameti uzlu??
pridat callbacky
checknout pravidla pro selecty a radia

custom classy
zmena DOMu
dogenerovani hlasek
error hlasky

definovani pravidel pro inputz pomoci trid
predani nastaveni inputu pomoci configu

fix focusout + change
parser reg rename
*/

(function($) {

	$.bValidator = {

		defaults: {
		},

		validations: {},

		transformations: {},

		//settings: {},

		/**
		 * Bings input and form actions, initialises input values, stores settings into form node
		 *
		 * @param form element
		 * @param json settings
		 * @return void
		 */
		init: function(form, settings) {
			var plugin = this;
			// clear plugin bindings and data in order not to have double bindings
			plugin.destruct(form);
			// store settings to form node
			form.data('bValidator', settings);
			// choose elements which should be validated
			var inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.each(function (){
				// bind focus in function
				$(this).on('focusin.bValidator', function() {
					plugin.focus($(this));
				});
				// bind focus out
				$(this).on('focusout.bValidator', function() {
					plugin.validate($(this));
				});
				// bind change - for checkboxes, selects.
				// TODO: exclude these elements from focus out, now we have double bindings for text based inputs
				$(this).on('change.bValidator', function() {
					plugin.validate($(this));
				});
				// initialize elements - apply transformations, pendings
				plugin.initInput($(this));
			});

			//plugin.settings: $.extend({}, defaults, options);

			// bind before submit validations
			form.on('submit.bValidator', function(e) {
				// obtain settings from form node
				var settings = $(this).data('bValidator');
				// assume that form is valid
				var bValid = true;
				// choose elements which should be validated
				var inputs = $('input[data-bvString], input[data-bvStrict], textarea', $(this));
				// validate all inputs
				inputs.each(function() {
					// if input is invalid, remember it for breaking submitting form later
					if(!plugin.validate($(this))) bValid = false;
				});
				// if form is invalid
				if(!bValid) {
					// call submitFail callback
					settings.onSubmitFail.call( this, e );
					// and forbit submitting form
					e.preventDefault();
				/// if form is valid
				} else {
					// for each input apply focus action -> pendigs are stripped
					inputs.each(function() {
						plugin.focus($(this));
					});
					// and call beforeSubmit callback
					settings.beforeSubmit.call( this, this, e );
				}
			});

		},

		/**
		 * Parses input value, gets input config based on attributes
		 *
		 * @param input element
		 * @return input config
		 */
		getConfig: function(elem) {
			conf = {};
			// switch value - erase inputs with this value. Fill value of empty inputs on focus out
			conf['switchVal'] = (elem.attr('data-bvSwitch') == undefined ? '' : elem.attr('data-bvSwitch'));
			// prepended value
			conf['prepend'] = (elem.attr('data-bvPrepend') == undefined ? '' : elem.attr('data-bvPrepend'));
			// key string
			conf['string'] = (elem.attr('data-bvString') == undefined ? '.*' : elem.attr('data-bvString'));
			// appended value
			conf['append'] = (elem.attr('data-bvAppend') == undefined ? '' : elem.attr('data-bvAppend'));
			// string transformation
			conf['transform'] = (elem.attr('data-bvTransform') == undefined ? '' : elem.attr('data-bvTransform'));
			// pattern for regexp
			var pattern = '('+conf['prepend']+')?'+'('+conf['string']+')('+conf['append']+')?'+'';
			var re = new RegExp(pattern, 'i');
			// new string value
			conf['newString'] = elem.val().match(re)[2];
			// string which fill for empty inputs
			conf['empty'] = (elem.attr('data-bvEmpty') == undefined ? '' : elem.attr('data-bvEmpty'));
			// rules for real validation
			conf['strict'] = (elem.attr('data-bvStrict') == undefined ? '' : elem.attr('data-bvStrict'));

			return conf;
		},

		/**
		 * Initialise input value - applies transformations, switchval, default val, pendings
		 *
		 * @param input element
		 * @return input config
		 */
		initInput: function(elem) {
			// get input clean value, input config
			conf = this.getConfig(elem);
			// fix prepend escape chars
			conf['prepend'] = conf['prepend'].replace(/\\|\?/g,'');
			// fix append escape chars
			conf['append'] = conf['append'].replace(/\\|\?/g,'');
			// if element value is empty
			if(!elem.val() || elem.val() == conf['empty'] || conf['newString'] == '') {
				// and if both switchval and empty val are empty, add pendings
				if(conf['empty'] == '' && conf['switchVal'] == '') elem.val(conf['prepend']+conf['append']);
				// else if switchval is empty, apply Empty value
				else if(conf['switchVal'] == '') elem.val(conf['empty']);
				// otherwise add switchval value
				else elem.val(conf['switchVal']);
				//elem.addClass('grey');
			}
			// if value is not empty
			else {
				// apply transformation
				if(conf['transform']) conf['newString'] = this.transform(conf['newString'], conf['transform']);
				// and set value with pendings
				elem.val(conf['prepend']+conf['newString']+conf['append']);
				//elem.removeClass('grey');
			}
			return conf;
		},

		focus: function(elem) {
			conf = this.getConfig(elem);

			if(elem.val() == conf['switchVal']) elem.val('');
			else elem.val($.trim(conf['newString']));
			//elem.removeClass('grey');
			//this.clean(elem);
		},

		isValid: function(value, rule, elem) {

			if(typeof value === 'undefined') {
				var conf = this.initInput(elem);
				var value = conf['newString'];
			}

			if(typeof rule === 'undefined') {
				var conf = this.initInput(elem);
				var rule = conf['strict'];
			}

			var plugin = this;

			var result = false;

			var ruleEscaped = rule.replace(/({{((?!}}).)*}})/g, '{{NOPARSE}}');

			var ruleReplacements = rule.match(/({{((?!}}).)*}})/g);

			var rulesOr = ruleEscaped.split('|');

			//rulesAnd.each();

			$.each(rulesOr, function(indexOr, ruleOr) {

				var rulesAnd = ruleOr.split('&');

				var resultAnd = true;

				$.each(rulesAnd, function(indexAnd, ruleAnd) {

					var args = ruleAnd.split(':');

					for (var i = 0; i < args.length; i++) {
						if(args[i].match(/\{\{NOPARSE\}\}/) !== null) {
							var replacement = ruleReplacements.shift();
							args[i] = args[i].replace('{{NOPARSE}}', replacement.slice(2, -2));
						}
					};

					if(!plugin.validations[args[0]].func(value, args, elem)) {
						resultAnd = false;
						return;
					}

				});

				if(resultAnd == true) {
					result = true;
					return;
				}

			});

			return result;

		},

		validate: function(elem) {
			this.clean(elem);
			conf = this.initInput(elem);

			if(this.isValid(conf['newString'], conf['strict'], elem)) return this.valid(elem);
			else return this.invalid(elem);
		},

		validation: function() {
			this.validations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		transform: function(value, method) {
			return this.transformations[method].func(value);
		},

		transformation: function() {
			this.transformations[arguments[0]] = {
				func: arguments[1],
			};

			return this;
		},

		clean: function(elem) {
			elem.removeClass('error').removeClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).removeClass('error').removeClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').removeClass('error').removeClass('valid');
			//elem.parents('.row').removeClass('error').removeClass('valid');
		},

		valid: function(elem) {
			elem.addClass('valid');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('valid');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('valid');

			//elem.parents('.row').addClass('valid');
			//elem.parents('.row').find('.error-message').addClass('hidden');
			return true;
		},

		invalid: function(elem) {
			elem.addClass('error');
			elem.parents('.row').find('.bverror-'+elem.attr('name')).addClass('error');
			elem.parents('.row').find('label[for="'+elem.attr('name')+'"]').addClass('error');

			//elem.parents('.row').addClass('error');
			//elem.parents('.row').find('.error-message').removeClass('hidden');
			return false;
		},

		destruct: function(form) {
			form.unbind('.bValidator');

			var inputs = $('input[data-bvString], input[data-bvStrict], textarea', form);
			inputs.unbind('.bValidator');

			form.removeData('bValidator');
		}

	}

	$.fn.bValidator = function(options, args) {

		if(typeof options == 'string' && options == 'isValid') {
			var valid = true;
			this.each(function() {
				if(typeof args === 'undefined') {
					args = Array();
				}
				if(!$.bValidator.isValid(undefined, args[0], $(this))) {
					valid =  false;
					return;
				}
			});
			return valid;
		}

		var settings = $.extend({
			beforeSubmit: function() {},
			onSubmitFail: function() {}
		}, options );

		return this.each(function() {
			if(typeof options == 'string') {
				switch(options) {
					case 'validate':
						return $.bValidator.validate($(this));
						break;
					case 'destruct':
						return $.bValidator.destruct($(this));
						break;
					}
			} else {
				$this = $(this);
				//if($this.is('form')) $.bValidator.init($this, settings);
				//else $.bValidator.init($this.find('form'), settings);

				if(!$this.is('form')) $this = $this.find('form');

				return $this.each(function() {
					$.bValidator.init($(this), settings);
				});
			}
			//if (undefined == $(this).data('bValidator')) {
				//var plugin = new $.bValidator.init();
				//$(this).data('bValidator', plugin);
			//}
		});

	}

})(jQuery);

jQuery.bValidator
.validation('number', function(value, args) {
	valid = (value.match(/^[0-9]+$/) != null);
	if(!valid) return false;
	if(typeof args[1] != 'undefined') {
		intVal = parseInt(value);
		if(args[1] != '') {
			if(intVal < args[1]) return false;
		}
		if(typeof args[2] != 'undefined') {
			if(args[2] != '') {
				if(intVal > args[2]) return false;
			}
		}
	}
	return true;
})
.validation('empty', function(value) {
	return (value == '');
})
.validation('if', function(value, args, elem) {
	// arg[0] = rule name -> if
	// arg[1] = name of other input
	// arg[2] = name of other input rule
	// arg[3] = name of current input rule
	var input = elem.parents('form').find('[name="'+args[1]+'"]');
	if(input.bValidator('isValid', Array(args[2]))) {
		return (elem.bValidator('isValid', Array(args[3])));
	} else return true;

})
.validation('same', function(value, args) {
	return (value == $('form [name="'+args[1]+'"]').val());
})
.validation('reg', function(value, args) {
	return (value.match(args[1]) != null);
})
.validation('string', function(value) {
	return (value.match(/^.+$/) != null);
})
.validation('email', function(value) {
	return (value.match(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/) != null && value.length != 0);
})
.validation('zip', function(value) {
	return (value.match(/^[0-9]{5}$/) != null);
})
.validation('city', function(value) {
	return (value.match(/^.{2,}$/) != null);
})
.validation('date-d.m.yy', function(value) {
	return (value.match(/^[0123]?[0-9]\.[01]?[0-9]\.[12][09][0-9][0-9]$/) != null);
})
.validation('nin', function(value) {
	return (value.match(/^[0-9]{6}\/[0-9]{3,4}$/) != null);
})
.validation('false', function(value) {
	return false;
})
.validation('true', function(value) {
	return true;
})
.validation('checked', function(value, args, elem) {
	return $(elem).prop('checked');
})
.validation('phone', function(value) {
	var same = 0;
	var inc = 0;
	var i;

	var pnumber = value;

	if(!pnumber.match(/^[0-9]{9}$/)) {
		return false;
	}

	for(i = 4;i < 9;i++) {
	if(i != 3 && pnumber.charAt(i) == pnumber.charAt(i - 1)) {
		same++;
	}
	if(parseInt(pnumber.charAt(i)) == (parseInt(pnumber.charAt(i - 1)) + 1) || (pnumber.charAt(i) == '0' && pnumber.charAt(i - 1) == '9')) {
		inc++;
	}
	}
	if(same >= 4 || inc >= 5) {
	return false;
	}
	return true;
})
.transformation('noSpaces', function(value) {
	return value.replace(/ /g,'');
});<|endoftext|>


<commit_before>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2015 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		sass: {
			core: {
				files: {
					'css/reveal.css': 'css/reveal.scss',
				}
			},
			themes: {
				files: {
                    'css/theme/ajf.css': 'css/theme/source/ajf.scss',
				}
			}
		},

		autoprefixer: {
			dist: {
				src: 'css/reveal.css'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false,
					define: false,
					exports: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.',
                    livereload: true,
                    open: true
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
            options: {
                livereload: true
            },
			js: {
				files: [ 'Gruntfile.js', 'js/reveal.js' ],
				tasks: 'js'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'css-themes'
			},
			css: {
				files: [ 'css/reveal.scss' ],
				tasks: 'css-core'
			},
            html: {
                files: [ 'index.html']
            }
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-autoprefixer' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'css', 'js' ] );

	// JS task
	grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] );

	// Theme CSS
	grunt.registerTask( 'css-themes', [ 'sass:themes' ] );

	// Core framework CSS
	grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] );

	// All CSS
	grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<commit_msg>Mods to remove dev tests that aren't needed for presso<commit_after>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2015 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		sass: {
			core: {
				files: {
					'css/reveal.css': 'css/reveal.scss',
				}
			},
			themes: {
				files: {
                    'css/theme/ajf.css': 'css/theme/source/ajf.scss',
				}
			}
		},

		autoprefixer: {
			dist: {
				src: 'css/reveal.css'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false,
					define: false,
					exports: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.',
                    livereload: true,
                    open: true
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
            options: {
                livereload: true
            },
			js: {
				files: [ 'Gruntfile.js', 'js/reveal.js' ],
				tasks: 'js'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'css-themes'
			},
			css: {
				files: [ 'css/reveal.scss' ],
				tasks: 'css-core'
			},
            html: {
                files: [ 'index.html']
            }
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-autoprefixer' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'css', 'js' ] );

	// JS task
	grunt.registerTask( 'js', [ 'jshint', 'uglify' ] );

	// Theme CSS
	grunt.registerTask( 'css-themes', [ 'sass:themes' ] );

	// Core framework CSS
	grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] );

	// All CSS
	grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint' ] );

};
<|endoftext|>


<commit_before>import Cookies from 'js-cookie'

export function fetch(method, url, req_body) {
  return new Promise((resolve, reject) => {
    const request = new XMLHttpRequest()
    request.open(method, url, true)
    request.setRequestHeader('X-CSRFToken', Cookies.get('csrftoken'))
    request.addEventListener('load', () => resolve(request.responseText))
    request.addEventListener('error', () => reject('Request Error: ', request.response))
    request.send(req_body)
  })
}

export function calculateSimilarity(item_answers, user_answers) {
    let points = 0,
        answers_count = 0,
        answers = user_answers

    // Similarity is 0% if there is no data about item answers
    if (!item_answers)
        return 0

    for (let answer_id in item_answers) {
        if (answers[answer_id] && answers[answer_id].answer) {
            let answer_points = Math.abs((answers[answer_id].answer + Number(item_answers[answer_id])) / 4)
            if (answers[answer_id].important) {
                answers_count += 2
                answer_points *= 2
            } else {
                answers_count++
            }
            points += answer_points
        }
    }

    return Math.round((points / answers_count)*100)
}

export function sortResults(results) {
    // Filter out old/inactive/renamed fractions which have 0 members.
    results.fractions = results.fractions.filter((fraction) => fraction.members_amount > 0)
    // Filter out MF fraction, we don't want to show it in results
    results.fractions = results.fractions.filter((fraction) => fraction.short_title !== 'MG')

    // Calculate fractions similarity
    results.fractions = results.fractions.map((fraction) => {
        fraction.similarity = calculateSimilarity(fraction.answers, results.user_answers || results.answers)
        return fraction
    })

    // Filter out not active mps (they don't have fraction)
    results.mps = results.mps.filter((mp) => mp.fraction_id)

    // Calculate mps similarity
    results.mps = results.mps.map((mp) => {
        mp.similarity = calculateSimilarity(mp.answers, results.user_answers || results.answers)
        return mp
    })

    // Sort fractions and mps by similarity (desc)
    function compare (a, b) {
        if (a.similarity > b.similarity)
            return -1

        if (a.similarity < b.similarity)
            return 1

        return 0
    }
    results.fractions.sort(compare)
    results.mps.sort(compare)

    return results
}
<commit_msg>Lambad looks better without ()<commit_after>import Cookies from 'js-cookie'

export function fetch(method, url, req_body) {
  return new Promise((resolve, reject) => {
    const request = new XMLHttpRequest()
    request.open(method, url, true)
    request.setRequestHeader('X-CSRFToken', Cookies.get('csrftoken'))
    request.addEventListener('load', () => resolve(request.responseText))
    request.addEventListener('error', () => reject('Request Error: ', request.response))
    request.send(req_body)
  })
}

export function calculateSimilarity(item_answers, user_answers) {
    let points = 0,
        answers_count = 0,
        answers = user_answers

    // Similarity is 0% if there is no data about item answers
    if (!item_answers)
        return 0

    for (let answer_id in item_answers) {
        if (answers[answer_id] && answers[answer_id].answer) {
            let answer_points = Math.abs((answers[answer_id].answer + Number(item_answers[answer_id])) / 4)
            if (answers[answer_id].important) {
                answers_count += 2
                answer_points *= 2
            } else {
                answers_count++
            }
            points += answer_points
        }
    }

    return Math.round((points / answers_count)*100)
}

export function sortResults(results) {
    // Filter out old/inactive/renamed fractions which have 0 members.
    results.fractions = results.fractions.filter(fraction => fraction.members_amount > 0)
    // Filter out MF fraction, we don't want to show it in results
    results.fractions = results.fractions.filter(fraction => fraction.short_title !== 'MG')

    // Calculate fractions similarity
    results.fractions = results.fractions.map((fraction) => {
        fraction.similarity = calculateSimilarity(fraction.answers, results.user_answers || results.answers)
        return fraction
    })

    // Filter out not active mps (they don't have fraction)
    results.mps = results.mps.filter((mp) => mp.fraction_id)

    // Calculate mps similarity
    results.mps = results.mps.map((mp) => {
        mp.similarity = calculateSimilarity(mp.answers, results.user_answers || results.answers)
        return mp
    })

    // Sort fractions and mps by similarity (desc)
    function compare (a, b) {
        if (a.similarity > b.similarity)
            return -1

        if (a.similarity < b.similarity)
            return 1

        return 0
    }
    results.fractions.sort(compare)
    results.mps.sort(compare)

    return results
}
<|endoftext|>


<commit_before>/*globals module*/
module.exports = (function (edm) {
  "use strict";

  var Edm = edm;

  // TODO Write a converter for metadata.xml to this schema structure.
  return {
    getEntitySets: function () {
      return this.schema.entityContainer.entitySets;
    },
    getEntitySetNames: function () {
      return Object.keys(this.schema.entityContainer.entitySets);
    },
    getTypeForEntitySet: function (entitySet) {
      var schema = this.schema,
          entitySets = schema.entityContainer.entitySets,
          entityTypeKey = entitySets[entitySet].entityType,
          entityType = schema.entityTypes[this.removeNameSpace(entityTypeKey)];

      entityType.typeName = entityTypeKey;
      return entityType;
    },
    removeNameSpace: function (name) {
      return name.split(".").pop();
    },
    schema: {
      namespace: "ODataDemo",
      entityTypes: {
        Product: {
          key: "ID",
          properties: {
            ID: {
              type: Edm.Int32,
              nullable: false
            },
            Name: {
              type: Edm.String,
              nullable: true
            }
          },
          navigationProperties: {

          }
        },
        Category: {
          key: "ID",
          properties: {
            ID: {
              type: Edm.Int32,
              nullable: false
            },
            Name: {
              type: Edm.String,
              nullable: true
            }
          },
          navigationProperties: {

          }
        }
      },
      entityContainer: {
        name: "DemoService",
        metadata: {
          IsDefaultEntityContainer: true
        },
        entitySets: {
          Products: {
            entityType: "ODataDemo.Product"
          },
          Categories: {
            entityType: "ODataDemo.Category"
          }
        }
      }
    }

  };

})({
  Int32: "Int32",
  String: "String"
});
<commit_msg>refactoring<commit_after>/*globals module*/
module.exports = (function (edm) {
  "use strict";

  var Edm = edm,
      schema = {
        namespace: "ODataDemo",
        entityTypes: {
          Product: {
            key: "ID",
            properties: {
              ID: {
                type: Edm.Int32,
                nullable: false
              },
              Name: {
                type: Edm.String,
                nullable: true
              }
            },
            navigationProperties: {

            }
          },
          Category: {
            key: "ID",
            properties: {
              ID: {
                type: Edm.Int32,
                nullable: false
              },
              Name: {
                type: Edm.String,
                nullable: true
              }
            },
            navigationProperties: {

            }
          }
        },
        entityContainer: {
          name: "DemoService",
          metadata: {
            IsDefaultEntityContainer: true
          },
          entitySets: {
            Products: {
              entityType: "ODataDemo.Product"
            },
            Categories: {
              entityType: "ODataDemo.Category"
            }
          }
        }
      };

  // TODO Write a converter for metadata.xml to this schema structure.
  return {
    getEntitySets: function () {
      return schema.entityContainer.entitySets;
    },
    getEntitySetNames: function () {
      return Object.keys(this.getEntitySets());
    },
    getTypeForEntitySet: function (entitySet) {
      var entitySets = this.getEntitySets(),
          entityTypeKey = entitySets[entitySet].entityType,
          entityType = schema.entityTypes[this.removeNameSpace(entityTypeKey)];

      entityType.typeName = entityTypeKey;
      return entityType;
    },
    removeNameSpace: function (name) {
      return name.split(".").pop();
    }
  };
})({
  Int32: "Int32",
  String: "String"
});
<|endoftext|>


<commit_before><commit_msg>Add work done in class<commit_after><|endoftext|>