<commit_before>import React, { Component } from 'react';
import moment from 'moment';
import DayPicker, { DateUtils } from '../../../src';

import '../../../src/style.css';

const overlayStyle = {
  position: 'absolute',
  background: 'white',
  boxShadow: '0 2px 5px rgba(0, 0, 0, .15)',
};

export default class InputFieldOverlay extends Component {

  constructor(props) {
    super(props);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleInputFocus = this.handleInputFocus.bind(this);
    this.handleInputBlur = this.handleInputBlur.bind(this);
    this.handleContainerMouseDown = this.handleContainerMouseDown.bind(this);
  }

  state = {
    showOverlay: false,
    value: '',
    selectedDay: null,
  };

  componentWillUnmount() {
    clearTimeout(this.clickTimeout);
  }

  input = null;
  daypicker = null;
  clickedInside = false;
  clickTimeout = null;

  handleContainerMouseDown() {
    this.clickedInside = true;
    // The input's onBlur method is called from a queue right after onMouseDown event.
    // setTimeout adds another callback in the queue, but is called later than onBlur event
    this.clickTimeout = setTimeout(() => {
      this.clickedInside = false;
    }, 0);
  }

  handleInputFocus() {
    this.setState({
      showOverlay: true,
    });
  }

  handleInputBlur() {
    const showOverlay = this.clickedInside;

    this.setState({
      showOverlay,
    });

    // Force input's focus if blur event was caused by clicking on the calendar
    if (showOverlay) {
      this.input.focus();
    }
  }

  handleInputChange(e) {
    const { value } = e.target;
    const momentDay = moment(value, 'L', true);
    if (momentDay.isValid()) {
      this.setState({
        selectedDay: momentDay.toDate(),
        value,
      }, () => {
        this.daypicker.showMonth(this.state.selectedDay);
      });
    } else {
      this.setState({ value, selectedDay: null });
    }
  }

  handleDayClick(e, day) {
    this.setState({
      value: moment(day).format('L'),
      selectedDay: day,
      showOverlay: false,
    });
    this.input.blur();
  }

  render() {
    return (

        <input
          type="text"
          ref={ (el) => { this.input = el; } }
          placeholder="DD/MM/YYYY"
          value={ this.state.value }
          onChange={ this.handleInputChange }
          onFocus={ this.handleInputFocus }
          onBlur={ this.handleInputBlur }
        />
        { this.state.showOverlay &&

              <DayPicker
                ref={ (el) => { this.daypicker = el; } }
                onDayClick={ this.handleDayClick }
                selectedDays={ day => DateUtils.isSameDay(this.state.selectedDay, day) }
              />

        }

    );
  }
}
<commit_msg>Use initialMonth prop (fix #239)<commit_after>import React, { Component } from 'react';
import moment from 'moment';
import DayPicker, { DateUtils } from '../../../src';

import '../../../src/style.css';

const overlayStyle = {
  position: 'absolute',
  background: 'white',
  boxShadow: '0 2px 5px rgba(0, 0, 0, .15)',
};

export default class InputFieldOverlay extends Component {

  constructor(props) {
    super(props);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleInputFocus = this.handleInputFocus.bind(this);
    this.handleInputBlur = this.handleInputBlur.bind(this);
    this.handleContainerMouseDown = this.handleContainerMouseDown.bind(this);
  }

  state = {
    showOverlay: false,
    value: '',
    selectedDay: null,
  };

  componentWillUnmount() {
    clearTimeout(this.clickTimeout);
  }

  input = null;
  daypicker = null;
  clickedInside = false;
  clickTimeout = null;

  handleContainerMouseDown() {
    this.clickedInside = true;
    // The input's onBlur method is called from a queue right after onMouseDown event.
    // setTimeout adds another callback in the queue, but is called later than onBlur event
    this.clickTimeout = setTimeout(() => {
      this.clickedInside = false;
    }, 0);
  }

  handleInputFocus() {
    this.setState({
      showOverlay: true,
    });
  }

  handleInputBlur() {
    const showOverlay = this.clickedInside;

    this.setState({
      showOverlay,
    });

    // Force input's focus if blur event was caused by clicking on the calendar
    if (showOverlay) {
      this.input.focus();
    }
  }

  handleInputChange(e) {
    const { value } = e.target;
    const momentDay = moment(value, 'L', true);
    if (momentDay.isValid()) {
      this.setState({
        selectedDay: momentDay.toDate(),
        value,
      }, () => {
        this.daypicker.showMonth(this.state.selectedDay);
      });
    } else {
      this.setState({ value, selectedDay: null });
    }
  }

  handleDayClick(e, day) {
    this.setState({
      value: moment(day).format('L'),
      selectedDay: day,
      showOverlay: false,
    });
    this.input.blur();
  }

  render() {
    return (

        <input
          type="text"
          ref={ (el) => { this.input = el; } }
          placeholder="DD/MM/YYYY"
          value={ this.state.value }
          onChange={ this.handleInputChange }
          onFocus={ this.handleInputFocus }
          onBlur={ this.handleInputBlur }
        />
        { this.state.showOverlay &&

              <DayPicker
                ref={ (el) => { this.daypicker = el; } }
                initialMonth={ this.state.selectedDay || undefined }
                onDayClick={ this.handleDayClick }
                selectedDays={ day => DateUtils.isSameDay(this.state.selectedDay, day) }
              />

        }

    );
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

//
// exports は辞書としての object を直接返す
//

assert = require('assert');
foo = require('./foo');  // 別ファイルで exports = しているもの

assert.deepEqual(foo, {
  x: 1,
  y: 2
});
<commit_msg>Upate a comment<commit_after>#!/usr/bin/env node

//
// exports は辞書としての object を直接返す
//

assert = require('assert');
foo = require('./foo');  // 別ファイルで exports しているモジュール

assert.deepEqual(foo, {
  x: 1,
  y: 2
});
<|endoftext|>


<commit_before>/* This is a variant of the suggestion in the jQuery FAQ:
     https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/
   We need this since election IDs now have dots in them.
 */
function escapeID(originalID) {
  return originalID.replace( /(:|\.|\[|\]|,)/g, "\\$1" );
}

/* Change the visibility of a Select2 widget; select2Element should be a
   jQuery-wrapped element */

function setSelect2Visibility(select2Element, visibility) {
  /* If visibility is false, this both disables the Select2 boxes and
   * hides them by hiding their enclosing element. Otherwise it
   * enables it and makes the enclosure visible. */
  select2Element.prop(
    'disabled',
    !visibility
  );

  if (visibility) {
    select2Element.parent().show()
  } else {
    select2Element.parent().hide();
  }
}

/* Make all the party drop-downs into Select2 widgets */

function setUpPartySelect2s() {
  $('select.party-select').not('.select2-offscreen').not('.select2-container').each(function(i) {
    var partySelect = $(this)
    var select_options = {
      width: '100%',
      placeholder: 'Select a party',
      allowClear: true
    }

    if (partySelect.attr('show_load_more')) {
      var data = {
          id: 0,
          text: 'Click to load more parties…'
      };
      var loadMoreOption = new Option(data.text, data.id, false, false);
      partySelect.append(loadMoreOption)

      select_options.matcher = function(params, data) {
        var match = partySelect.select2.defaults.defaults.matcher(params, data);
        if (match) {
          return match;
        }
        if (data.id === "0") {
          return data;
        } else {
          return null
        }
      }
      partySelect.on('select2:select', function (e) {
          var data = e.params.data;
          if (data.id == 0) {
            var initial_val = partySelect.val();
            var partyset = $(this).data('partyset');
            // partySelect.find('option[value="0"]').text('Loading…');
            data.text = "Loading…"
            partySelect.trigger('change.select2');

            $.getJSON('/all-parties.json?partyset=' + partyset, function(items) {
              $.each(items['items'], function(party_id, descs) {
                var group = $('<optgroup label="' + descs['text'] + '" />');
                if (descs['children']) {
                  $.each(descs['children'], function(child) {
                    $('<option value="'+this.id+'"/>').html(this.text).appendTo(group);
                  });

                  group.appendTo(partySelect);
                }
              });
              partySelect.find('option[value="0"]').remove();
              partySelect.select2('open');
            });

          }
      });

    }

    partySelect.select2(select_options);
  });
}

$(document).on('focus', '.select2', function (e) {
  if (e.originalEvent) {
    $(this).siblings('select').select2('open');
  }
});

/* Make all the post drop-downs into Select2 widgets */

function setUpPostSelect2s() {
  $('.post-select').each(function(i) {
    var postSelect = $(this),
      hidden = postSelect.prop('tagName') == 'INPUT' &&
         postSelect.attr('type') == 'hidden';
    /* If it's a real select box (not a hidden input) make it into a
     * Select2 box; also, don't try to reinitialize a select that's
     * already a Select2 */
    if (!(hidden || $(postSelect).data('select2'))) {
        var select_config = {
        placeholder: 'Post',
        allowClear: true,
        width: '100%'
      }
      if (postSelect.prop('show_load_more')) {
          var load_more_option = {
              id: 0,
              text: 'Load more parties…'
          }
          postSelect.append(load_more_option)
          // select_config.
      }
      postSelect.select2(select_config);
    }
    postSelect.on('change', function (e) {
      updateFields();
    });
    updateFields();
  });
}

/* Set the visibility of an input element and any label for it */

function setVisibility(plainInputElement, newVisiblity) {
  var inputElement = $(plainInputElement),
      inputElementID = escapeID(plainInputElement.id),
      labelElement = $('label[for=' + inputElementID + ']');
  inputElement.toggle(newVisiblity);
  labelElement.toggle(newVisiblity);
}

/* Update the visibility of the party and post drop-downs for a particular
   election */

function updateSelectsForElection(show, election) {
  /* Whether we should show the party and post selects is
     determined by the boolean 'show'. */
  var partySelectToShowID,
      partyPositionToShowID,
      postID = $('#id_constituency_' + escapeID(election)).val(),
      partySet;
  if (postID) {
    partySet = postIDToPartySet[postID];
  }
  if (show) {
    if (postID) {
      partySelectToShowID = 'id_party_' + partySet + '_' + election;
      partyPositionToShowID = 'id_party_list_position_' + partySet + '_' + election;
      $('.party-select-' + escapeID(election)).each(function(i) {
        setSelect2Visibility(
          $(this),
          $(this).attr('id') == partySelectToShowID
        );
      });
      $('.party-position-' + escapeID(election)).each(function(i) {
        setVisibility(this, $(this).attr('id') == partyPositionToShowID);
      });
    } else {
      /* Then just show the first party select and hide the others: */
      $('.party-select-' + escapeID(election)).each(function(i) {
        setSelect2Visibility($(this), i == 0);
      });
      $('.party-position-' + escapeID(election)).each(function(i) {
        setVisibility(this, i == 0);
      });
    }
  } else {
    $('.party-select-' + escapeID(election)).each(function(i) {
      setSelect2Visibility($(this), false);
    });
    $('.party-position-' + escapeID(election)).each(function() {
      setVisibility(this, false);
    });
  }
  setSelect2Visibility($('#id_constituency_' + escapeID(election)), show);
}

/* Make sure that the party and constituency select boxes are updated
   when you choose whether the candidate is standing in that election
   or not. */

function setUpStandingCheckbox() {
  $('#person-details select.standing-select').on('change', function() {
    updateFields();
  });
}

/* This should be called whenever the select drop-downs for party
   and post that have to be shown might have to be shown.  */

function updateFields() {
  $('#person-details select.standing-select').each(function(i) {
    var standing = $(this).val() == 'standing',
        match = /^id_standing_(.*)/.exec($(this).attr('id')),
        election = match[1];
    updateSelectsForElection(standing, election); });
}

/* This is called to display a new election form on the edit person
   page, if the dynamic "add new election" button is being used. */

function showElectionsForm() {
  $.getJSON("/api/current-elections/").done(function( data ) {
    var select_data = $.map(data, function(obj, key) {
      return { id: key, text: obj.name + ' (' + obj.election_date + ')' };
    })
    $('#add_more_elections').select2({
      data: select_data,
    }).on('select2:select', function(e) {
      var data = e.params.data;
      var url = window.location.pathname + '/single_election_form/' + data.id;
      $.get(url, function(data) {
        $('.extra_elections_forms').html(data);
        setUpStandingCheckbox();
        setUpPartySelect2s();
        setUpPostSelect2s();
        updateFields();
      });
    });
    $('.add_more_elections_field').show();
    $('#add_election_button').hide();
  });
}

function toTitleCase(str) {
    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}

suggest_correction = function(el, suggestion) {

    suggestion_el = $('Change to ' + suggestion + '?');
    suggestion_el.click(function(clicked_el) {
        var this_link = $(this);
        this_link.prev('input').val($(this_link).find('span').text());
        $('.suggested').remove();
    })
    $('.suggested').remove();
    $(el).after(suggestion_el);

};

function checkNameFormat(e) {
    var name = e.target.value;
    var upper_first_matcher = /([A-Z]+,? [A-Za-z]+)/g;
    var match = upper_first_matcher.exec(name);
    if (match) {
        var name_parts = name.split(' ');
        var last_name = name_parts.shift();
        var name = name_parts.join(' ') + ' ' + toTitleCase(last_name);
        suggest_correction(e.target, name);
    }
}

$(document).ready(function() {
  $.getJSON('/post-id-to-party-set.json', function(data) {
      window.postIDToPartySet = data;
      setUpPartySelect2s();
      setUpPostSelect2s();
      setUpStandingCheckbox();
      updateFields();
      /* Now enable the "add an extra election" button if it's present */
      $('#add_election_button').on('click', showElectionsForm);
      $('.add_more_elections_field').hide();
      $('[name=name]').on('paste keyup', checkNameFormat);
      $('[name*=-name]').on('paste keyup', checkNameFormat);
  });
});
<commit_msg>Include parties without descriptions<commit_after>/* This is a variant of the suggestion in the jQuery FAQ:
     https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/
   We need this since election IDs now have dots in them.
 */
function escapeID(originalID) {
  return originalID.replace( /(:|\.|\[|\]|,)/g, "\\$1" );
}

/* Change the visibility of a Select2 widget; select2Element should be a
   jQuery-wrapped element */

function setSelect2Visibility(select2Element, visibility) {
  /* If visibility is false, this both disables the Select2 boxes and
   * hides them by hiding their enclosing element. Otherwise it
   * enables it and makes the enclosure visible. */
  select2Element.prop(
    'disabled',
    !visibility
  );

  if (visibility) {
    select2Element.parent().show()
  } else {
    select2Element.parent().hide();
  }
}

/* Make all the party drop-downs into Select2 widgets */

function setUpPartySelect2s() {
  $('select.party-select').not('.select2-offscreen').not('.select2-container').each(function(i) {
    var partySelect = $(this)
    var select_options = {
      width: '100%',
      placeholder: 'Select a party',
      allowClear: true
    }

    if (partySelect.attr('show_load_more')) {
      var data = {
          id: 0,
          text: 'Click to load more parties…'
      };
      var loadMoreOption = new Option(data.text, data.id, false, false);
      partySelect.append(loadMoreOption)

      select_options.matcher = function(params, data) {
        var match = partySelect.select2.defaults.defaults.matcher(params, data);
        if (match) {
          return match;
        }
        if (data.id === "0") {
          return data;
        } else {
          return null
        }
      }
      partySelect.on('select2:select', function (e) {
          var data = e.params.data;
          if (data.id == 0) {
            var initial_val = partySelect.val();
            var partyset = $(this).data('partyset');
            // partySelect.find('option[value="0"]').text('Loading…');
            data.text = "Loading…"
            partySelect.trigger('change.select2');

            $.getJSON('/all-parties.json?partyset=' + partyset, function(items) {
              $.each(items['items'], function(party_id, descs) {
                var group = $('<optgroup label="' + descs.text + '" />');
                if (descs['children']) {
                  $.each(descs['children'], function(child) {
                    $('<option value="'+this.id+'"/>').html(this.text).appendTo(group);
                  });
                } else {
                    $('<option value="'+descs.id+'"/>').html(descs.text).appendTo(group);
                }
                group.appendTo(partySelect);
              });
              partySelect.find('option[value="0"]').remove();
              partySelect.select2('open');
            });

          }
      });

    }

    partySelect.select2(select_options);
  });
}

$(document).on('focus', '.select2', function (e) {
  if (e.originalEvent) {
    $(this).siblings('select').select2('open');
  }
});

/* Make all the post drop-downs into Select2 widgets */

function setUpPostSelect2s() {
  $('.post-select').each(function(i) {
    var postSelect = $(this),
      hidden = postSelect.prop('tagName') == 'INPUT' &&
         postSelect.attr('type') == 'hidden';
    /* If it's a real select box (not a hidden input) make it into a
     * Select2 box; also, don't try to reinitialize a select that's
     * already a Select2 */
    if (!(hidden || $(postSelect).data('select2'))) {
        var select_config = {
        placeholder: 'Post',
        allowClear: true,
        width: '100%'
      }
      if (postSelect.prop('show_load_more')) {
          var load_more_option = {
              id: 0,
              text: 'Load more parties…'
          }
          postSelect.append(load_more_option)
          // select_config.
      }
      postSelect.select2(select_config);
    }
    postSelect.on('change', function (e) {
      updateFields();
    });
    updateFields();
  });
}

/* Set the visibility of an input element and any label for it */

function setVisibility(plainInputElement, newVisiblity) {
  var inputElement = $(plainInputElement),
      inputElementID = escapeID(plainInputElement.id),
      labelElement = $('label[for=' + inputElementID + ']');
  inputElement.toggle(newVisiblity);
  labelElement.toggle(newVisiblity);
}

/* Update the visibility of the party and post drop-downs for a particular
   election */

function updateSelectsForElection(show, election) {
  /* Whether we should show the party and post selects is
     determined by the boolean 'show'. */
  var partySelectToShowID,
      partyPositionToShowID,
      postID = $('#id_constituency_' + escapeID(election)).val(),
      partySet;
  if (postID) {
    partySet = postIDToPartySet[postID];
  }
  if (show) {
    if (postID) {
      partySelectToShowID = 'id_party_' + partySet + '_' + election;
      partyPositionToShowID = 'id_party_list_position_' + partySet + '_' + election;
      $('.party-select-' + escapeID(election)).each(function(i) {
        setSelect2Visibility(
          $(this),
          $(this).attr('id') == partySelectToShowID
        );
      });
      $('.party-position-' + escapeID(election)).each(function(i) {
        setVisibility(this, $(this).attr('id') == partyPositionToShowID);
      });
    } else {
      /* Then just show the first party select and hide the others: */
      $('.party-select-' + escapeID(election)).each(function(i) {
        setSelect2Visibility($(this), i == 0);
      });
      $('.party-position-' + escapeID(election)).each(function(i) {
        setVisibility(this, i == 0);
      });
    }
  } else {
    $('.party-select-' + escapeID(election)).each(function(i) {
      setSelect2Visibility($(this), false);
    });
    $('.party-position-' + escapeID(election)).each(function() {
      setVisibility(this, false);
    });
  }
  setSelect2Visibility($('#id_constituency_' + escapeID(election)), show);
}

/* Make sure that the party and constituency select boxes are updated
   when you choose whether the candidate is standing in that election
   or not. */

function setUpStandingCheckbox() {
  $('#person-details select.standing-select').on('change', function() {
    updateFields();
  });
}

/* This should be called whenever the select drop-downs for party
   and post that have to be shown might have to be shown.  */

function updateFields() {
  $('#person-details select.standing-select').each(function(i) {
    var standing = $(this).val() == 'standing',
        match = /^id_standing_(.*)/.exec($(this).attr('id')),
        election = match[1];
    updateSelectsForElection(standing, election); });
}

/* This is called to display a new election form on the edit person
   page, if the dynamic "add new election" button is being used. */

function showElectionsForm() {
  $.getJSON("/api/current-elections/").done(function( data ) {
    var select_data = $.map(data, function(obj, key) {
      return { id: key, text: obj.name + ' (' + obj.election_date + ')' };
    })
    $('#add_more_elections').select2({
      data: select_data,
    }).on('select2:select', function(e) {
      var data = e.params.data;
      var url = window.location.pathname + '/single_election_form/' + data.id;
      $.get(url, function(data) {
        $('.extra_elections_forms').html(data);
        setUpStandingCheckbox();
        setUpPartySelect2s();
        setUpPostSelect2s();
        updateFields();
      });
    });
    $('.add_more_elections_field').show();
    $('#add_election_button').hide();
  });
}

function toTitleCase(str) {
    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}

suggest_correction = function(el, suggestion) {

    suggestion_el = $('Change to ' + suggestion + '?');
    suggestion_el.click(function(clicked_el) {
        var this_link = $(this);
        this_link.prev('input').val($(this_link).find('span').text());
        $('.suggested').remove();
    })
    $('.suggested').remove();
    $(el).after(suggestion_el);

};

function checkNameFormat(e) {
    var name = e.target.value;
    var upper_first_matcher = /([A-Z]+,? [A-Za-z]+)/g;
    var match = upper_first_matcher.exec(name);
    if (match) {
        var name_parts = name.split(' ');
        var last_name = name_parts.shift();
        var name = name_parts.join(' ') + ' ' + toTitleCase(last_name);
        suggest_correction(e.target, name);
    }
}

$(document).ready(function() {
  $.getJSON('/post-id-to-party-set.json', function(data) {
      window.postIDToPartySet = data;
      setUpPartySelect2s();
      setUpPostSelect2s();
      setUpStandingCheckbox();
      updateFields();
      /* Now enable the "add an extra election" button if it's present */
      $('#add_election_button').on('click', showElectionsForm);
      $('.add_more_elections_field').hide();
      $('[name=name]').on('paste keyup', checkNameFormat);
      $('[name*=-name]').on('paste keyup', checkNameFormat);
  });
});
<|endoftext|>


<commit_before>    $(function () {
        var datasets = {{ plot_data|safe }};

        // hard-code color indices to prevent them from shifting as
        // countries are turned on/off
        var i = 0;
        $.each(datasets, function(key, val) {
            val.totals.color = i;
            val.averages.color = i;
            ++i;
        });
        // insert checkboxes
	    var choiceContainer = $("#choices");
	    $.each(datasets, function(key, val) {
	        choiceContainer.append('
<input type="checkbox" name="' + key +
	                               '" checked="checked" id="id' + key + '">' +
	                               ''
	                                + key + '');
	    });
	    choiceContainer.find("input").click(plotAccordingToChoices);

        function plotAccordingToChoices() {
	        var data = [];

	        choiceContainer.find("input:checked").each(function () {
	            var key = $(this).attr("name");
	            if (key && datasets[key])
	                data.push(datasets[key].totals);
	                data.push(datasets[key].averages);
	        });

	        if (data.length > 0)
	            $.plot($("#formentry-plot"), data,
                      { xaxis: {mode: "time",
                                minTickSize: [1, "day"]},
                    yaxis: {min: 0, tickFormatter: function (v, axis) { return v + " sec" }},
                    y2axis: {min: 0, tickFormatter: function (v, axis) { return v +" forms" }},
                    legend: { show: true, container: "#trendlegend"},
                    grid: { hoverable: true },
                   });

        }
        function tooltipContents(item) {
            return item.series.label;
        }
        function showTooltip(x, y, contents) {
            $('
' + contents + '
').css( {
                position: 'absolute',
                display: 'none',
                top: y + 5,
                left: x + 5,
                border: '1px solid #fdd',
                padding: '2px',
                'background-color': '#fee',
                opacity: 0.80
            }).appendTo("body").fadeIn(200);
        }

        var previousPoint = null;
        $("#formentry-plot").on("plothover", function (event, pos, item) {
            $("#x").text(pos.x.toFixed(2));
            $("#y").text(pos.y.toFixed(2));
            if (item) {
                if (previousPoint != item.datapoint) {
                    previousPoint = item.datapoint;

                    $("#tooltip").remove();
                    var x = item.datapoint[0].toFixed(2),
                        y = item.datapoint[1].toFixed(2);
                    showTooltip(item.pageX, item.pageY,
                                tooltipContents(item));
                }
            }
            else {
                $("#tooltip").remove();
                previousPoint = null;
            }
        });
        plotAccordingToChoices();
    });
<commit_msg>Remove formentry_plot.js<commit_after><|endoftext|>


<commit_before>var Vec2      = require('pex-math/Vec2');
var Vec3      = require('pex-math/Vec3');
var Vec4      = require('pex-math/Vec4');
var Mat4      = require('pex-math/Mat4');
var Quat      = require('pex-math/Quat');
var MathUtils = require('pex-math/Utils');

var DEFAULT_RADIUS_SCALE = 1;
var DEFAULT_SPEED = 0.095;
var DEFAULT_DISTANCE_STEP = 0.25;

var TEMP_VEC2_0 = Vec2.create();
var TEMP_VEC2_1 = Vec2.create();
var TEMP_VEC2_2 = Vec2.create();
var TEMP_VEC3_0 = Vec3.create();

//http://jsperf.com/quaternion-slerp-implementations
//modified to prevent taking shortest path
function slerpLongest(a,b,t){
    var ax = a[0];
    var ay = a[1];
    var az = a[2];
    var aw = a[3];
    var bx = b[0];
    var by = b[1];
    var bz = b[2];
    var bw = b[3];

    var omega, cosom, sinom, scale0, scale1;

    cosom = ax * bx + ay * by + az * bz + aw * bw;

    if ( (1.0 - cosom) > 0.000001 ) {
        omega  = Math.acos(cosom);
        sinom  = Math.sin(omega);
        scale0 = Math.sin((1.0 - t) * omega) / sinom;
        scale1 = Math.sin(t * omega) / sinom;
    } else {
        scale0 = 1.0 - t;
        scale1 = t;
    }

    a[0] = scale0 * ax + scale1 * bx;
    a[1] = scale0 * ay + scale1 * by;
    a[2] = scale0 * az + scale1 * bz;
    a[3] = scale0 * aw + scale1 * bw;

    return a;
}

function CameraArcball(camera, windowWidth, windowHeight){
    this._camera = camera;
    this._center = null;
    this._radius = null;
    this._radiusScale = null;
    this._speed = null;

    this._boundsSize = [windowWidth,windowHeight];
    this._center     = [windowWidth * 0.5, windowHeight * 0.5];

    this.setRadiusScale(DEFAULT_RADIUS_SCALE);
    this.setSpeed(DEFAULT_SPEED);

    this._distanceStep   = DEFAULT_DISTANCE_STEP;
    this._distance       = camera.getDistance();
    this._distanceTarget = this._distance;
    this._distanceMax    = Number.MAX_VALUE;
    this._distanceMin    = Number.MIN_VALUE;

    this._posDown    = Vec2.create();
    this._posDownPtr = Vec3.create();
    this._posDragPtr = Vec3.create();

    this._orientCurr   = Quat.fromMat4(Quat.create(),Mat4.copy(camera.getViewMatrix()));
    this._orientDown   = Quat.create();
    this._orientDrag   = Quat.create();
    this._orientTarget = Quat.copy(this._orientCurr);

    this._matrix = Mat4.create();

    this._interactive = true;

    this._updateRadius();
}

CameraArcball.prototype.setLookDirection = function(direction){
    direction = Vec3.normalize(Vec3.copy(direction));
    var orientation = Quat.fromDirection(Quat.create(),direction);
    Quat.set(this._orientTarget,Quat.normalize(Quat.invert(orientation)));
};

CameraArcball.prototype.getBoundsSize = function(out){
    out = out === undefined ? Vec2.create() : out;
    return Vec2.set(out,this._boundsSize);
};

CameraArcball.prototype.setDistanceMin = function(min){
    this._distanceMin = min;
};

CameraArcball.prototype.setDistanceMax = function(max){
    this._distanceMax = max;
};

CameraArcball.prototype.setDistance = function(distance){
    this._distanceTarget = distance;
};

CameraArcball.prototype.getDistance = function(){
    return this._distance;
};

CameraArcball.prototype.setRadiusScale = function(scale){
    this._radiusScale = 1.0 / (1.0 / (scale === undefined ? DEFAULT_RADIUS_SCALE : scale) * 2);
    this._updateRadius();
};

CameraArcball.prototype.getRadiusScale = function(){
    return this._radiusScale;
};

CameraArcball.prototype.setSpeed = function(speed){
    this._speed = speed;
};

CameraArcball.prototype.getSpeed = function(){
    return this._speed;
};

CameraArcball.prototype.enable = function(){
    this._interactive = true;
};

CameraArcball.prototype.disable = function(){
    this._interactive = false;
};

CameraArcball.prototype.isEnabled = function(){
    return this._interactive;
};

CameraArcball.prototype._updateRadius = function(){
    var boundsSize = this._boundsSize;
    this._radius = Math.min(boundsSize[0],boundsSize[1]) * this._radiusScale;
};

CameraArcball.prototype._mapSphere = function(pos){
    pos = Vec2.set(TEMP_VEC2_0,pos);

    var dir = this._distance < 0 ? -1 : 1;
    pos = Vec2.sub(pos,this._center);
    pos = Vec2.scale(pos, 1.0 / this._radius);
    pos = Vec3.set3(TEMP_VEC2_1,pos[0],pos[1] * dir, 0);

    var len = Vec3.lengthSq(pos);
    if(len > 1.0){
        Vec3.normalize(pos);
    }
    else{
        pos[2] = Math.sqrt(1 - len);
    }

    return pos;
};

CameraArcball.prototype.onMouseDown = function(e){
    if(!this._interactive){
        return;
    }
    var boundsHeight = this._boundsSize[1];
    var mousePos     = Vec2.set2(TEMP_VEC2_0, e.x, e.y);
    this._posDown    = Vec2.set(this._posDown, mousePos);

    var pos = Vec2.set2(TEMP_VEC2_0, mousePos[0],boundsHeight - mousePos[1]);

    Vec3.set(this._posDownPtr, this._mapSphere(pos));
    Quat.set(this._orientDown, this._orientCurr);
    Quat.identity(this._orientDrag);
};

CameraArcball.prototype.onMouseDrag = function(e){
    if(!this._interactive){
        return;
    }

    var boundsHeight = this._boundsSize[1];
    var mousePos     = Vec2.set2(TEMP_VEC2_0, e.x, e.y);
    var pos          = Vec2.set2(TEMP_VEC2_0, mousePos[0], boundsHeight - mousePos[1]);

    var posDownPtr = this._posDownPtr;
    var posDragPtr = Vec3.set(this._posDragPtr,this._mapSphere(pos));
    var temp       = Vec3.cross(Vec3.set(Vec3.create(),posDownPtr), posDragPtr);

    Quat.set4(this._orientDrag,temp[0],temp[1],temp[2],Vec3.dot(posDownPtr,posDragPtr));
    Quat.set(this._orientTarget, this._orientDrag);
    Quat.mult(this._orientTarget, this._orientDown);
};

CameraArcball.prototype.onMouseScroll = function(e){
    if(!this._interactive){
        return;
    }
    var direction = e.dy < 0 ? -1 : e.dy > 0 ? 1 : 0;
    if(direction == 0){
        return;
    }
    this._distanceTarget += direction * -1 * this._distanceStep;
    this._distanceTarget  = Math.max(this._distanceMin, Math.min(this._distanceTarget,this._distanceMax));
};

CameraArcball.prototype.onWindowResize = function(e){
    var width  = e.width;
    var height = e.height;
    Vec2.set2(this._boundsSize,width,height);
    Vec2.set2(this._center, width * 0.5, height * 0.5);
    this._updateRadius();
};

CameraArcball.prototype.apply = function(){
    this._distance += (this._distanceTarget - this._distance) * this._speed;

    slerpLongest(this._orientCurr,this._orientTarget,this._speed);
    Mat4.fromQuat(this._matrix,this._orientCurr);

    var viewMatrix = this._camera.getViewMatrix();
    Mat4.identity(viewMatrix);
    Mat4.setTranslation3(viewMatrix,0,0,-this._distance);
    Mat4.mult(viewMatrix,this._matrix);
};

module.exports = CameraArcball;<commit_msg>CameraArcball added panning<commit_after>var Vec2      = require('pex-math/Vec2');
var Vec3      = require('pex-math/Vec3');
var Mat4      = require('pex-math/Mat4');
var Quat      = require('pex-math/Quat');

var Plane = require('pex-geom/Plane');

var DEFAULT_RADIUS_SCALE = 1;
var DEFAULT_SPEED = 0.175;
var DEFAULT_DISTANCE_STEP = 0.25;

var TEMP_VEC2_0 = Vec2.create();
var TEMP_VEC2_1 = Vec2.create();
var TEMP_VEC3_0 = Vec3.create();
var TEMP_VEC3_1 = Vec3.create();
var TEMP_MAT4_0 = Mat4.create();

var Y_AXIS = [0,1,0];
var Z_AXIS = [0,0,1];

//http://jsperf.com/quaternion-slerp-implementations
//modified to prevent taking shortest path
function slerpLongest(a,b,t){
    var ax = a[0];
    var ay = a[1];
    var az = a[2];
    var aw = a[3];
    var bx = b[0];
    var by = b[1];
    var bz = b[2];
    var bw = b[3];

    var omega, cosom, sinom, scale0, scale1;

    cosom = ax * bx + ay * by + az * bz + aw * bw;

    if ( (1.0 - cosom) > 0.000001 ) {
        omega  = Math.acos(cosom);
        sinom  = Math.sin(omega);
        scale0 = Math.sin((1.0 - t) * omega) / sinom;
        scale1 = Math.sin(t * omega) / sinom;
    } else {
        scale0 = 1.0 - t;
        scale1 = t;
    }

    a[0] = scale0 * ax + scale1 * bx;
    a[1] = scale0 * ay + scale1 * by;
    a[2] = scale0 * az + scale1 * bz;
    a[3] = scale0 * aw + scale1 * bw;

    return a;
}

function CameraArcball(camera, windowWidth, windowHeight){
    this._camera = camera;
    this._center = null;
    this._radius = null;
    this._radiusScale = null;
    this._speed = null;

    this._boundsSize = [windowWidth,windowHeight];
    this._center     = [windowWidth * 0.5, windowHeight * 0.5];

    this.setRadiusScale(DEFAULT_RADIUS_SCALE);
    this.setSpeed(DEFAULT_SPEED);

    this._zoom = false;

    this._distanceStep   = DEFAULT_DISTANCE_STEP;
    this._distance       = camera.getDistance();
    this._distancePrev   = this._distance;
    this._distanceTarget = this._distance;
    this._distanceMax    = Number.MAX_VALUE;
    this._distanceMin    = Number.MIN_VALUE;

    this._posDown    = Vec2.create();
    this._posDrag    = Vec2.create();
    this._posDownPtr = Vec3.create();
    this._posDragPtr = Vec3.create();

    this._orientCurr   = Quat.fromMat4(Quat.create(),Mat4.copy(camera.getViewMatrix()));
    this._orientDown   = Quat.create();
    this._orientDrag   = Quat.create();
    this._orientTarget = Quat.copy(this._orientCurr);

    this._pan = false;

    this._targetCameraView          = Vec3.create();
    this._targetCameraWorld         = Vec3.create();
    this._targetCameraWorldOriginal = Vec3.copy(camera.getTarget());

    this._planeTargetView   = Plane.create();
    this._planeTargetWorld  = Plane.create();

    this._planePosDownView = Vec3.create();
    this._planePosDragView = Vec3.create();

    this._planePosDownWorld = Vec3.create();
    this._planePosDragWorld = Vec3.create();

    this._matrix = Mat4.create();

    this._interactive = true;

    this._updateRadius();
}

CameraArcball.prototype.setLookDirection = function(direction){
    direction = Vec3.normalize(Vec3.copy(direction));
    var orientation = Quat.fromDirection(Quat.create(),direction);
    Quat.set(this._orientTarget,Quat.normalize(Quat.invert(orientation)));
};

CameraArcball.prototype.getBoundsSize = function(out){
    out = out === undefined ? Vec2.create() : out;
    return Vec2.set(out,this._boundsSize);
};

CameraArcball.prototype.setDistanceMin = function(min){
    this._distanceMin = min;
};

CameraArcball.prototype.setDistanceMax = function(max){
    this._distanceMax = max;
};

CameraArcball.prototype.setDistance = function(distance){
    this._distanceTarget = distance;
};

CameraArcball.prototype.getDistance = function(){
    return this._distance;
};

CameraArcball.prototype.setRadiusScale = function(scale){
    this._radiusScale = 1.0 / (1.0 / (scale === undefined ? DEFAULT_RADIUS_SCALE : scale) * 2);
    this._updateRadius();
};

CameraArcball.prototype.getRadiusScale = function(){
    return this._radiusScale;
};

CameraArcball.prototype.setSpeed = function(speed){
    this._speed = speed;
};

CameraArcball.prototype.getSpeed = function(){
    return this._speed;
};

CameraArcball.prototype.enable = function(){
    this._interactive = true;
};

CameraArcball.prototype.disable = function(){
    this._interactive = false;
};

CameraArcball.prototype.isEnabled = function(){
    return this._interactive;
};

CameraArcball.prototype._updateRadius = function(){
    var boundsSize = this._boundsSize;
    this._radius = Math.min(boundsSize[0],boundsSize[1]) * this._radiusScale;
};

CameraArcball.prototype._mapSphere = function(pos){
    pos = Vec2.set(TEMP_VEC2_0,pos);

    var dir = this._distance < 0 ? -1 : 1;
    pos = Vec2.sub(pos,this._center);
    pos = Vec2.scale(pos, 1.0 / this._radius);
    pos = Vec3.set3(TEMP_VEC2_1,pos[0],pos[1] * dir, 0);

    var len = Vec3.lengthSq(pos);
    if(len > 1.0){
        Vec3.normalize(pos);
    }
    else{
        pos[2] = Math.sqrt(1 - len);
    }

    return pos;
};

CameraArcball.prototype.onMouseDown = function(e){
    if(!this._interactive){
        return;
    }

    this._pan = e.shiftKey;

    var boundsHeight = this._boundsSize[1];
    var mousePos     = Vec2.set2(TEMP_VEC2_0, e.x, e.y);
    this._posDown    = Vec2.set(this._posDown, mousePos);

    var pos = Vec2.set2(TEMP_VEC2_0, mousePos[0],boundsHeight - mousePos[1]);

    Vec3.set(this._posDownPtr, this._mapSphere(pos));
    Quat.set(this._orientDown, this._orientCurr);
    Quat.identity(this._orientDrag);

    if(this._pan){

        Vec3.set(this._targetCameraWorld,this._camera.getTarget());
        Vec3.multMat4(Vec3.set(this._targetCameraView,this._targetCameraWorld),this._camera.getViewMatrix());

        Vec3.set(this._planeTargetView[0],this._targetCameraView);
        Vec3.set(this._planeTargetView[1],Z_AXIS);

        var invViewMatrix = Mat4.invert(Mat4.set(TEMP_MAT4_0,this._camera.getViewMatrix()));
        Vec3.multMat4(Vec3.set(this._planeTargetWorld[1],this._planeTargetView[1]),invViewMatrix);
    }
};

CameraArcball.prototype.onMouseDrag = function(e){
    if(!this._interactive){
        return;
    }

    var boundsWidth  = this._boundsSize[0];
    var boundsHeight = this._boundsSize[1];
    var mousePos     = Vec2.set2(TEMP_VEC2_0, e.x, e.y);

    this._posDrag = Vec2.set2(TEMP_VEC2_0, e.x, e.y);
    this._pan = e.shiftKey;

    if(this._pan){
        Plane.getRayIntersection(this._planeTargetView,this._camera.getViewRay(this._posDown,boundsWidth,boundsHeight),this._planePosDownView);
        Plane.getRayIntersection(this._planeTargetView,this._camera.getViewRay(this._posDrag,boundsWidth,boundsHeight),this._planePosDragView);

        var invViewMatrix = Mat4.invert(Mat4.set(TEMP_MAT4_0,this._camera.getViewMatrix()));

        Vec3.multMat4(Vec3.set(this._planePosDownWorld,this._planePosDownView),invViewMatrix);
        Vec3.multMat4(Vec3.set(this._planePosDragWorld,this._planePosDragView),invViewMatrix);

        var targetCameraWorld = Vec3.set(TEMP_VEC3_0,this._targetCameraWorld);
        var planePosDragWorld = Vec3.set(TEMP_VEC3_1,this._planePosDragWorld);
        var planePosDelta     = Vec3.sub(planePosDragWorld,this._planePosDownWorld);

        this._camera.setTarget(Vec3.sub(targetCameraWorld,planePosDelta));
    }
    else {
        var pos = Vec2.set2(TEMP_VEC2_0, mousePos[0], boundsHeight - mousePos[1]);

        var posDownPtr = this._posDownPtr;
        var posDragPtr = Vec3.set(this._posDragPtr,this._mapSphere(pos));
        var temp       = Vec3.cross(Vec3.set(Vec3.create(),posDownPtr), posDragPtr);

        Quat.set4(this._orientDrag,temp[0],temp[1],temp[2],Vec3.dot(posDownPtr,posDragPtr));
        Quat.set(this._orientTarget, this._orientDrag);
        Quat.mult(this._orientTarget, this._orientDown);
    }
};

CameraArcball.prototype.onMouseScroll = function(e){
    if(!this._interactive){
        return;
    }
    var direction = e.dy < 0 ? -1 : e.dy > 0 ? 1 : 0;
    if(direction == 0){
        return;
    }
    this._distanceTarget += direction * -1 * this._distanceStep;
    this._distanceTarget  = Math.max(this._distanceMin, Math.min(this._distanceTarget,this._distanceMax));
};

CameraArcball.prototype.onWindowResize = function(e){
    var width  = e.width;
    var height = e.height;
    Vec2.set2(this._boundsSize,width,height);
    Vec2.set2(this._center, width * 0.5, height * 0.5);
    this._updateRadius();
};

CameraArcball.prototype.apply = function(){
    this._distance += (this._distanceTarget - this._distance) * this._speed;

    slerpLongest(this._orientCurr,this._orientTarget,this._speed);
    Mat4.fromQuat(this._matrix,this._orientCurr);

    var orient = Quat.copy(this._orientCurr);
    orient[3] *= -1;

    var target   = this._camera.getTarget();
    var offset   = Vec3.multQuat(Vec3.set3(TEMP_VEC3_0,0,0,this._distance),orient);
    var position = Vec3.add(Vec3.set(TEMP_VEC3_1,target),offset);
    var up       = Vec3.multQuat(Vec3.set(TEMP_VEC3_0,Y_AXIS),orient);

    this._camera.lookAt(position,target,up);

    this._zoom = this._distance == this._distancePrev;
    this._distancePrev = this._distance;
};

CameraArcball.prototype.resetPanning = function(){
    this._camera.setTarget(this._targetCameraWorldOriginal);
    this._pan = false;
};

CameraArcball.prototype.isPanning = function(){
    return this._pan;
};

CameraArcball.prototype.isZooming = function(){
    return this._zoom;
};

module.exports = CameraArcball;<|endoftext|>


<commit_before>function poche(id) {
    try {
	var query = "?op=pluginhandler&plugin=poche&method=inthepoche&id=" + param_escape(id);

	console.log(query);

	new Ajax.Request("backend.php",	{
	    parameters: query,
	    onComplete: function(transport) {
		var ti = JSON.parse(transport.responseText);

		var share_url = ti.poche_url + "?action=add&url="+ btoa(ti.link);
		console.log(share_url);
		window.open(share_url,'_blank','menubar=no,height=390,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1');

	    } });
    } catch (e) {
	exception_error("poche", e);
    }
}

<commit_msg>Added autoclose parameter in prevision for https://github.com/inthepoche/poche/pull/290 to be merged<commit_after>function poche(id) {
    try {
	var query = "?op=pluginhandler&plugin=poche&method=inthepoche&id=" + param_escape(id);

	console.log(query);

	new Ajax.Request("backend.php",	{
	    parameters: query,
	    onComplete: function(transport) {
		var ti = JSON.parse(transport.responseText);

		var share_url = ti.poche_url + "?action=add&autoclose=true&url="+ btoa(ti.link);
		console.log(share_url);
		window.open(share_url,'_blank','menubar=no,height=390,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1');

	    } });
    } catch (e) {
	exception_error("poche", e);
    }
}

<|endoftext|>


<commit_before>const _ = require('lodash/fp')

const BitGo = require('bitgo')
const { toLegacyAddress, toCashAddress } = require('bchaddrjs')

const BN = require('../../../bn')

const E = require('../../../error')

const pjson = require('../../../../package.json')
const userAgent = 'Lamassu-Server/' + pjson.version

const NAME = 'BitGo'
const SUPPORTED_COINS = ['BTC', 'ZEC', 'LTC', 'BCH', 'DASH']
const BCH_CODES = ['BCH', 'TBCH']

function buildBitgo (account) {
  const env = account.environment === 'test' ? 'test' : 'prod'
  return new BitGo.BitGo({ accessToken: account.token.trim(), env, userAgent: userAgent })
}

function getWallet (account, cryptoCode) {
  const bitgo = buildBitgo(account)
  const coin = account.environment === 'test' ? `t${cryptoCode.toLowerCase()}` : cryptoCode.toLowerCase()

  return bitgo.coin(coin).wallets().get({ id: account[`${cryptoCode}WalletId`] })
}

function checkCryptoCode (cryptoCode) {
  if (!SUPPORTED_COINS.includes(cryptoCode)) {
    return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
  }

  return Promise.resolve()
}

function getLegacyAddress (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  return toLegacyAddress(address)
}

function getCashAddress (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  return toCashAddress(address)
}

function formatToGetStatus (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  const [part1, part2] = getLegacyAddress(address, cryptoCode).split(':')
  return part2 || part1
}

function sendCoins (account, tx, settings, operatorId) {
  const { toAddress, cryptoAtoms, cryptoCode } = tx
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => {
      const params = {
        address: getLegacyAddress(toAddress, cryptoCode),
        amount: cryptoAtoms.toNumber(),
        walletPassphrase: account[`${cryptoCode}WalletPassphrase`],
        enforceMinConfirmsForChange: false
      }
      return wallet.send(params)
    })
    .then(result => {
      let fee = parseFloat(result.transfer.feeString)
      let txid = result.transfer.txid

      return { txid: txid, fee: new BN(fee).decimalPlaces(0) }
    })
    .catch(err => {
      if (err.message === 'insufficient funds') throw new E.InsufficientFundsError()
      throw err
    })
}

function balance (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => new BN(wallet._wallet.spendableBalanceString))
}

function newAddress (account, info, tx, settings, operatorId) {
  return checkCryptoCode(info.cryptoCode)
    .then(() => getWallet(account, info.cryptoCode))
    .then(wallet => {
      return wallet.createAddress()
        .then(result => {
          const address = result.address

          // If a label was provided, set the label
          if (info.label) {
            return wallet.updateAddress({ address: address, label: info.label })
              .then(() => getCashAddress(address, info.cryptoCode))
          }

          return getCashAddress(address, info.cryptoCode)
        })
    })
}

function getStatus (account, tx, requested, settings, operatorId) {
  const { toAddress, cryptoCode } = tx
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => wallet.transfers({
      type: 'receive',
      address: formatToGetStatus(toAddress, cryptoCode)
    }))
    .then(({ transfers }) => {
      const filterConfirmed = _.filter(it =>
        it.state === 'confirmed' && it.type === 'receive'
      )
      const filterPending = _.filter(it =>
        (it.state === 'confirmed' || it.state === 'unconfirmed') &&
        it.type === 'receive'
      )

      const sum = _.reduce((acc, val) => val.plus(acc), new BN(0))
      const toBn = _.map(it => new BN(it.valueString))

      const confirmed = _.compose(sum, toBn, filterConfirmed)(transfers)
      const pending = _.compose(sum, toBn, filterPending)(transfers)

      if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' }
      if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' }
      if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' }
      return { receivedCryptoAtoms: pending, status: 'notSeen' }
    })
}

function newFunding (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => {
      return getWallet(account, cryptoCode)
        .then(wallet => {
          return wallet.createAddress()
            .then(result => {
              const fundingAddress = result.address
              return wallet.updateAddress({ address: fundingAddress, label: 'Funding Address' })
                .then(() => ({
                  fundingPendingBalance: new BN(wallet._wallet.balanceString),
                  fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalanceString),
                  fundingAddress: getCashAddress(fundingAddress, cryptoCode)
                }))
            })
        })
    })
}

function cryptoNetwork (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => account.environment === 'test' ? 'test' : 'main')
}

function checkBlockchainStatus (cryptoCode) {
  return checkCryptoCode(cryptoCode)
    .then(() => Promise.resolve('ready'))
}

module.exports = {
  NAME,
  balance,
  sendCoins,
  newAddress,
  getStatus,
  newFunding,
  cryptoNetwork,
  checkBlockchainStatus
}
<commit_msg>fix: bitgo pending and confirmed balances<commit_after>const _ = require('lodash/fp')

const BitGo = require('bitgo')
const { toLegacyAddress, toCashAddress } = require('bchaddrjs')

const BN = require('../../../bn')

const E = require('../../../error')

const pjson = require('../../../../package.json')
const userAgent = 'Lamassu-Server/' + pjson.version

const NAME = 'BitGo'
const SUPPORTED_COINS = ['BTC', 'ZEC', 'LTC', 'BCH', 'DASH']
const BCH_CODES = ['BCH', 'TBCH']

function buildBitgo (account) {
  const env = account.environment === 'test' ? 'test' : 'prod'
  return new BitGo.BitGo({ accessToken: account.token.trim(), env, userAgent: userAgent })
}

function getWallet (account, cryptoCode) {
  const bitgo = buildBitgo(account)
  const coin = account.environment === 'test' ? `t${cryptoCode.toLowerCase()}` : cryptoCode.toLowerCase()

  return bitgo.coin(coin).wallets().get({ id: account[`${cryptoCode}WalletId`] })
}

function checkCryptoCode (cryptoCode) {
  if (!SUPPORTED_COINS.includes(cryptoCode)) {
    return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
  }

  return Promise.resolve()
}

function getLegacyAddress (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  return toLegacyAddress(address)
}

function getCashAddress (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  return toCashAddress(address)
}

function formatToGetStatus (address, cryptoCode) {
  if (!BCH_CODES.includes(cryptoCode)) return address

  const [part1, part2] = getLegacyAddress(address, cryptoCode).split(':')
  return part2 || part1
}

function sendCoins (account, tx, settings, operatorId) {
  const { toAddress, cryptoAtoms, cryptoCode } = tx
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => {
      const params = {
        address: getLegacyAddress(toAddress, cryptoCode),
        amount: cryptoAtoms.toNumber(),
        walletPassphrase: account[`${cryptoCode}WalletPassphrase`],
        enforceMinConfirmsForChange: false
      }
      return wallet.send(params)
    })
    .then(result => {
      let fee = parseFloat(result.transfer.feeString)
      let txid = result.transfer.txid

      return { txid: txid, fee: new BN(fee).decimalPlaces(0) }
    })
    .catch(err => {
      if (err.message === 'insufficient funds') throw new E.InsufficientFundsError()
      throw err
    })
}

function balance (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => new BN(wallet._wallet.spendableBalanceString))
}

function newAddress (account, info, tx, settings, operatorId) {
  return checkCryptoCode(info.cryptoCode)
    .then(() => getWallet(account, info.cryptoCode))
    .then(wallet => {
      return wallet.createAddress()
        .then(result => {
          const address = result.address

          // If a label was provided, set the label
          if (info.label) {
            return wallet.updateAddress({ address: address, label: info.label })
              .then(() => getCashAddress(address, info.cryptoCode))
          }

          return getCashAddress(address, info.cryptoCode)
        })
    })
}

function getStatus (account, tx, requested, settings, operatorId) {
  const { toAddress, cryptoCode } = tx
  return checkCryptoCode(cryptoCode)
    .then(() => getWallet(account, cryptoCode))
    .then(wallet => wallet.transfers({
      type: 'receive',
      address: formatToGetStatus(toAddress, cryptoCode)
    }))
    .then(({ transfers }) => {
      const filterConfirmed = _.filter(it =>
        it.state === 'confirmed' && it.type === 'receive'
      )
      const filterPending = _.filter(it =>
        (it.state === 'confirmed' || it.state === 'unconfirmed') &&
        it.type === 'receive'
      )

      const sum = _.reduce((acc, val) => val.plus(acc), new BN(0))
      const toBn = _.map(it => new BN(it.valueString))

      const confirmed = _.compose(sum, toBn, filterConfirmed)(transfers)
      const pending = _.compose(sum, toBn, filterPending)(transfers)

      if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' }
      if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' }
      if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' }
      return { receivedCryptoAtoms: pending, status: 'notSeen' }
    })
}

function newFunding (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => {
      return getWallet(account, cryptoCode)
        .then(wallet => {
          return wallet.createAddress()
            .then(result => {
              const fundingAddress = result.address
              return wallet.updateAddress({ address: fundingAddress, label: 'Funding Address' })
                .then(() => ({
                  fundingPendingBalance: new BN(wallet._wallet.balance).minus(wallet._wallet.confirmedBalance),
                  fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalance),
                  fundingAddress: getCashAddress(fundingAddress, cryptoCode)
                }))
            })
        })
    })
}

function cryptoNetwork (account, cryptoCode, settings, operatorId) {
  return checkCryptoCode(cryptoCode)
    .then(() => account.environment === 'test' ? 'test' : 'main')
}

function checkBlockchainStatus (cryptoCode) {
  return checkCryptoCode(cryptoCode)
    .then(() => Promise.resolve('ready'))
}

module.exports = {
  NAME,
  balance,
  sendCoins,
  newAddress,
  getStatus,
  newFunding,
  cryptoNetwork,
  checkBlockchainStatus
}
<|endoftext|>


<commit_before>describe('Staff movements', function () {
  beforeEach(function () {
    cy.request('DELETE', '/v2/test/live/test/data');
    var schDT = new Date().toISOString().split("T")[0];
    cy.request('POST',
      '/v2/test/live/test/arrival',
      {
        "Operator": "Flybe",
        "Status": "On Chocks",
        "EstDT": schDT + "T00:55:00Z",
        "ActDT": schDT + "T00:55:00Z",
        "EstChoxDT": schDT + "T01:01:00Z",
        "ActChoxDT": schDT + "T01:05:00Z",
        "Gate": "46",
        "Stand": "44R",
        "MaxPax": 78,
        "ActPax": 51,
        "TranPax": 0,
        "RunwayID": "05L",
        "BaggageReclaimId": "05",
        "FlightID": 14710007,
        "AirportID": "MAN",
        "Terminal": "T1",
        "ICAO": "SA123",
        "IATA": "SA123",
        "Origin": "AMS",
        "SchDT": schDT + "T00:15:00Z"
      });
  });

  function addMovementFor1HourAt(numStaff, hour) {
    for (let i = 0; i < numStaff; i++) {
      cy.get('.staff-adjustments > :nth-child(' + (hour + 1) + ') > :nth-child(3)').contains("+").then((el) => {
        el.click();
        cy.contains("Save").click();
      });
    }
  }

  function staffDeployedAtRow(row) {
    var selector = '#sticky-body > :nth-child(' + (row + 1) + ') > :nth-child(14)';
    return cy.get(selector);
  }

  function staffMovementsAtRow(row) {
    const selector = 'td.non-pcp:nth($index)';
    return cy.get(selector.replace('$index', row * 2 + 1));
  }

  function staffAvailableAtRow(row) {
    const selector = ':nth-child($index) > .staff-adjustments > :nth-child(1) > .deployed';
    return cy.get(selector.replace('$index', row + 1));
  }

  function staffOverTheDayAtSlot(slot) {
    const selector = '#available-staff tbody > :nth-child(2) > :nth-child(' + (slot + 1) + ')';
    return cy.get(selector);
  }

  function checkStaffNumbersOnDesksAndQueuesTabAre(numStaff) {
    [0, 1, 2, 3].map((row) => { staffMovementsAtRow(row).contains(numStaff).end() });
    staffMovementsAtRow(4).contains("0").end();

    [0, 1, 2, 3].map((row) => { staffDeployedAtRow(row).contains(numStaff).end() });
    staffDeployedAtRow(4).contains("0").end();

    [0, 1, 2, 3].map((row) => { staffAvailableAtRow(row).contains(numStaff).end() });
    staffAvailableAtRow(4).contains("0").end();
  }

  function checkStaffNumbersOnMovementsTabAre(numStaff) {
    cy.contains("Staff Movements").click().then(() => {
      [0, 1, 2, 3].map((slot) => { staffOverTheDayAtSlot(slot).contains(numStaff)});
      staffOverTheDayAtSlot(4).contains("0").end();
    }).end();
  }

  function removeXMovements(numToRemove) {
    cy.contains("Staff Movements").click().then(() => {
      for (let i = 1; i <= numToRemove; i++) {
        cy.get('.fa-remove').first().click().end();
        cy.get('.fa-remove').should('have.length', numToRemove - i).end();
      }
    }).end();
  }

  function navigateToMenuItem(itemName) {
    cy.get('.navbar-drt li').contains(itemName);
    cy.wait(500);
    cy.get('.navbar-drt li').contains(itemName).click().end();
  }

  function startAtHome() {
    return cy.visit('/v2/test/live').end();
  }

  function findAndClick(toFind) {
    cy.contains(toFind).click().end();
  }

  describe('When adding staff movements on the desks and queues page', function () {
    it("Should update the available staff when 1 staff member is added for 1 hour", function () {
      startAtHome()
      navigateToMenuItem('T1');
      findAndClick('24 hours');

      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(1);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(1);
      removeXMovements(1);
    });

    it("Should update the available staff when 1 staff member is added for 1 hour twice", function () {
      startAtHome();
      navigateToMenuItem('T1');
      findAndClick('24 hours');

      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(1);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(1);

      findAndClick('Desks & Queues');
      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(2);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(2);
      removeXMovements(2);
    });
  });
});
<commit_msg>DRT-5176 Force clicks to overcome zero width and height anchor tags<commit_after>describe('Staff movements', function () {
  beforeEach(function () {
    cy.request('DELETE', '/v2/test/live/test/data');
    var schDT = new Date().toISOString().split("T")[0];
    cy.request('POST',
      '/v2/test/live/test/arrival',
      {
        "Operator": "Flybe",
        "Status": "On Chocks",
        "EstDT": schDT + "T00:55:00Z",
        "ActDT": schDT + "T00:55:00Z",
        "EstChoxDT": schDT + "T01:01:00Z",
        "ActChoxDT": schDT + "T01:05:00Z",
        "Gate": "46",
        "Stand": "44R",
        "MaxPax": 78,
        "ActPax": 51,
        "TranPax": 0,
        "RunwayID": "05L",
        "BaggageReclaimId": "05",
        "FlightID": 14710007,
        "AirportID": "MAN",
        "Terminal": "T1",
        "ICAO": "SA123",
        "IATA": "SA123",
        "Origin": "AMS",
        "SchDT": schDT + "T00:15:00Z"
      });
  });

  function addMovementFor1HourAt(numStaff, hour) {
    for (let i = 0; i < numStaff; i++) {
      cy.get('.staff-adjustments > :nth-child(' + (hour + 1) + ') > :nth-child(3)').contains("+").then((el) => {
        el.click();
        cy.contains("Save").click();
      });
    }
  }

  function staffDeployedAtRow(row) {
    var selector = '#sticky-body > :nth-child(' + (row + 1) + ') > :nth-child(14)';
    return cy.get(selector);
  }

  function staffMovementsAtRow(row) {
    const selector = 'td.non-pcp:nth($index)';
    return cy.get(selector.replace('$index', row * 2 + 1));
  }

  function staffAvailableAtRow(row) {
    const selector = ':nth-child($index) > .staff-adjustments > :nth-child(1) > .deployed';
    return cy.get(selector.replace('$index', row + 1));
  }

  function staffOverTheDayAtSlot(slot) {
    const selector = '#available-staff tbody > :nth-child(2) > :nth-child(' + (slot + 1) + ')';
    return cy.get(selector);
  }

  function checkStaffNumbersOnDesksAndQueuesTabAre(numStaff) {
    [0, 1, 2, 3].map((row) => { staffMovementsAtRow(row).contains(numStaff).end() });
    staffMovementsAtRow(4).contains("0").end();

    [0, 1, 2, 3].map((row) => { staffDeployedAtRow(row).contains(numStaff).end() });
    staffDeployedAtRow(4).contains("0").end();

    [0, 1, 2, 3].map((row) => { staffAvailableAtRow(row).contains(numStaff).end() });
    staffAvailableAtRow(4).contains("0").end();
  }

  function checkStaffNumbersOnMovementsTabAre(numStaff) {
    cy.contains("Staff Movements").click().then(() => {
      [0, 1, 2, 3].map((slot) => { staffOverTheDayAtSlot(slot).contains(numStaff)});
      staffOverTheDayAtSlot(4).contains("0").end();
    }).end();
  }

  function removeXMovements(numToRemove) {
    cy.contains("Staff Movements").click().then(() => {
      for (let i = 1; i <= numToRemove; i++) {
        cy.get('.fa-remove').first().click().end();
        cy.get('.fa-remove').should('have.length', numToRemove - i).end();
      }
    }).end();
  }

  function navigateToMenuItem(itemName) {
    cy.get('.navbar-drt li').contains(itemName).click({ force: true }).end();
  }

  function startAtHome() {
    return cy.visit('/v2/test/live').end();
  }

  function findAndClick(toFind) {
    cy.contains(toFind).click({ force: true }).end();
  }

  describe('When adding staff movements on the desks and queues page', function () {
    it("Should update the available staff when 1 staff member is added for 1 hour", function () {
      startAtHome()
      navigateToMenuItem('T1');
      findAndClick('24 hours');

      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(1);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(1);
      removeXMovements(1);
    });

    it("Should update the available staff when 1 staff member is added for 1 hour twice", function () {
      startAtHome();
      navigateToMenuItem('T1');
      findAndClick('24 hours');

      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(1);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(1);

      findAndClick('Desks & Queues');
      addMovementFor1HourAt(1, 0);
      checkStaffNumbersOnDesksAndQueuesTabAre(2);

      findAndClick('Staff Movements');
      checkStaffNumbersOnMovementsTabAre(2);
      removeXMovements(2);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @file MenuBody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import {findDOMNode} from 'react-dom';
import PropTypes from 'prop-types';
import _ from 'lodash';

import Paper from '../Paper';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Dom from '../_vendors/Dom';
import Event from '../_vendors/Event';

export default class MenuBody extends Component {

    static Position = {

        TOP_LEFT: 'top-left',
        TOP: 'top',
        TOP_RIGHT: 'top-right',

        BOTTOM_LEFT: 'bottom-left',
        BOTTOM: 'bottom',
        BOTTOM_RIGHT: 'bottom-right',

        LEFT_TOP: 'left-top',
        LEFT: 'left',
        LEFT_BOTTOM: 'left-bottom',

        RIGHT_TOP: 'right-top',
        RIGHT: 'right',
        RIGHT_BOTTOM: 'right-bottom'

    };

    static TriggerMode = {
        TOGGLE: 'toggle',
        OPEN: 'open'
    };

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.hasMounted = false;
        this.prepareCloseTimeout = null;
        this.requestCloseTimeout = null;

        this.state = {
            visible: false
        };

        this.getMenuStyle = ::this.getMenuStyle;
        this.triggerMouseEnterHandler = ::this.triggerMouseEnterHandler;
        this.triggerMouseLeaveHandler = ::this.triggerMouseLeaveHandler;
        this.resizeHandler = ::this.resizeHandler;
        this.debounceResizeHandle = _.debounce(::this.debounceResizeHandle, 150);
        this.initializeAnimation = ::this.initializeAnimation;
        this.animate = ::this.animate;
        this.wheelHandler = ::this.wheelHandler;

    }

    calTopVerticalBottom(triggerEl, triggerOffset) {
        return triggerOffset.top + triggerEl.offsetHeight;
    }

    calTopVerticalTop(triggerOffset, menuEl) {
        return triggerOffset.top - menuEl.offsetHeight
            - parseInt(getComputedStyle(menuEl).marginTop)
            - parseInt(getComputedStyle(menuEl).marginBottom);
    }

    calTopHorizontalTop(triggerOffset) {
        return triggerOffset.top;
    }

    calTopHorizontalMiddle(triggerEl, triggerOffset, menuEl) {
        return triggerOffset.top + triggerEl.offsetHeight / 2 - menuEl.offsetHeight / 2;
    }

    calTopHorizontalBottom(triggerEl, triggerOffset, menuEl) {
        return triggerOffset.top + triggerEl.offsetHeight - menuEl.offsetHeight;
    }

    calLeftVerticalLeft(triggerOffset) {
        return triggerOffset.left;
    }

    calLeftVerticalCenter(triggerEl, triggerOffset, menuEl) {
        return triggerOffset.left + triggerEl.offsetWidth / 2 - menuEl.offsetWidth / 2;
    }

    calLeftVerticalRight(triggerEl, triggerOffset, menuEl) {
        return triggerOffset.left - (menuEl.offsetWidth - triggerEl.offsetWidth);
    }

    calLeftHorizontalLeft(triggerOffset, menuEl) {
        return triggerOffset.left - menuEl.offsetWidth
            - parseInt(getComputedStyle(menuEl).marginLeft)
            - parseInt(getComputedStyle(menuEl).marginRight);
    }

    calLeftHorizontalRight(triggerEl, triggerOffset) {
        return triggerOffset.left + triggerEl.offsetWidth;
    }

    getMenuStyle() {

        const {triggerEl, position} = this.props;

        if (!triggerEl || !this.menuEl) {
            return;
        }

        const triggerOffset = Dom.getOffset(triggerEl);
        let left, top;

        switch (position) {
            case MenuBody.Position.TOP_LEFT: {
                left = this.calLeftVerticalLeft(triggerOffset);
                top = this.calTopVerticalTop(triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.TOP: {
                left = this.calLeftVerticalCenter(triggerEl, triggerOffset, this.menuEl);
                top = this.calTopVerticalTop(triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.TOP_RIGHT: {
                left = this.calLeftVerticalRight(triggerEl, triggerOffset, this.menuEl);
                top = this.calTopVerticalTop(triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.BOTTOM_LEFT: {
                left = this.calLeftVerticalLeft(triggerOffset);
                top = this.calTopVerticalBottom(triggerEl, triggerOffset);
                break;
            }
            case MenuBody.Position.BOTTOM: {
                left = this.calLeftVerticalCenter(triggerEl, triggerOffset, this.menuEl);
                top = this.calTopVerticalBottom(triggerEl, triggerOffset);
                break;
            }
            case MenuBody.Position.BOTTOM_RIGHT: {
                left = this.calLeftVerticalRight(triggerEl, triggerOffset, this.menuEl);
                top = this.calTopVerticalBottom(triggerEl, triggerOffset);
                break;
            }
            case MenuBody.Position.LEFT_TOP: {
                left = this.calLeftHorizontalLeft(triggerOffset, this.menuEl);
                top = this.calTopHorizontalTop(triggerOffset);
                break;
            }
            case MenuBody.Position.LEFT: {
                left = this.calLeftHorizontalLeft(triggerOffset, this.menuEl);
                top = this.calTopHorizontalMiddle(triggerEl, triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.LEFT_BOTTOM: {
                left = this.calLeftHorizontalLeft(triggerOffset, this.menuEl);
                top = this.calTopHorizontalBottom(triggerEl, triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.RIGHT_TOP: {
                left = this.calLeftHorizontalRight(triggerEl, triggerOffset);
                top = this.calTopHorizontalTop(triggerOffset);
                break;
            }
            case MenuBody.Position.RIGHT: {
                left = this.calLeftHorizontalRight(triggerEl, triggerOffset);
                top = this.calTopHorizontalMiddle(triggerEl, triggerOffset, this.menuEl);
                break;
            }
            case MenuBody.Position.RIGHT_BOTTOM: {
                left = this.calLeftHorizontalRight(triggerEl, triggerOffset);
                top = this.calTopHorizontalBottom(triggerEl, triggerOffset, this.menuEl);
                break;
            }
        }

        return {left, top};

    }

    triggerMouseEnterHandler(e) {
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
    }

    triggerMouseLeaveHandler(e) {
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
        this.prepareCloseTimeout = setTimeout(() => {
            this.setState({
                visible: false
            }, () => {
                this.requestCloseTimeout && clearTimeout(this.requestCloseTimeout);
                this.requestCloseTimeout = setTimeout(() => {
                    const {onRequestClose} = this.props;
                    this.hasMounted && onRequestClose && onRequestClose();
                }, 250);
            });
        }, 100);
    }

    resizeHandler() {
        this.debounceResizeHandle();
    }

    debounceResizeHandle() {
        this.forceUpdate();
    }

    wheelHandler(e) {
        const {shouldPreventContainerScroll, onWheel} = this.props;
        shouldPreventContainerScroll && Event.preventContainerScroll(e);
        onWheel && onWheel(e);
    }

    initializeAnimation(callback) {
        setTimeout(() => {
            this.hasMounted && callback();
        }, 0);
    }

    animate() {
        this.setState({
            visible: true
        });
    }

    componentDidMount() {

        this.hasMounted = true;
        this.menuEl = findDOMNode(this.refs.menu);

        Event.addEvent(this.props.triggerEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.addEvent(this.props.triggerEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.addEvent(this.menuEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.addEvent(this.menuEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.addEvent(window, 'resize', this.resizeHandler);

    }

    componentWillAppear(callback) {
        this.initializeAnimation(callback);
    }

    componentDidAppear() {
        this.animate();
    }

    componentDidUpdate() {
        const {onRender} = this.props,
            {visible} = this.state;
        visible && onRender && onRender(this.menuEl, this.props.triggerEl);
    }

    componentWillUnmount() {

        this.hasMounted = false;
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
        this.requestCloseTimeout && clearTimeout(this.requestCloseTimeout);

        Event.removeEvent(this.props.triggerEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.removeEvent(this.props.triggerEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.removeEvent(this.menuEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.removeEvent(this.menuEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.removeEvent(window, 'resize', this.resizeHandler);

    }

    render() {

        const {children, className, style, theme, hasTriangle, triangle, position, isAnimated, depth} = this.props,
            {visible} = this.state,

            menuClassName = (visible ? '' : ' hidden') + (hasTriangle ? ' menu-has-triangle' : '')
                + (theme ? ` theme-${theme}` : '') + (position ? ` menu-position-${position}` : '')
                + (isAnimated ? ' menu-animated' : '') + (className ? ' ' + className : '');

        return (
            <Paper ref="menu"
                   className={'menu' + menuClassName}
                   style={{...this.getMenuStyle(), ...style}}
                   depth={depth}
                   onWheel={this.wheelHandler}>

                {
                    hasTriangle ?

                            {triangle}

                        :
                        null
                }

                    {children}

            </Paper>
        );

    }
};

MenuBody.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The popover alignment.The value can be Menu.Position.LEFT or Menu.Position.RIGHT.
     */
    position: PropTypes.oneOf(Util.enumerateValue(MenuBody.Position)),

    /**
     * If true, menu will have animation effects.
     */
    isAnimated: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * The status of menu-triangle.Can be open or toggle.
     */
    triggerMode: PropTypes.oneOf(Util.enumerateValue(MenuBody.TriggerMode)),

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    /**
     * The function of menu render.
     */
    onRender: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

MenuBody.defaultProps = {

    className: '',
    style: null,
    theme: Theme.DEFAULT,

    triggerEl: null,
    visible: false,
    hasTriangle: true,
    triangle:

,
    position: MenuBody.Position.BOTTOM_LEFT,
    isAnimated: true,
    triggerMode: MenuBody.TriggerMode.TOGGLE,
    depth: 6,
    shouldPreventContainerScroll: true

};<commit_msg>optimize MenuBody<commit_after>/**
 * @file MenuBody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import {findDOMNode} from 'react-dom';
import PropTypes from 'prop-types';
import _ from 'lodash';

import Paper from '../Paper';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Event from '../_vendors/Event';
import PopupCalculation from '../_vendors/PopupCalculation';

export default class MenuBody extends Component {

    static Position = {

        TOP_LEFT: 'top-left',
        TOP: 'top',
        TOP_RIGHT: 'top-right',

        BOTTOM_LEFT: 'bottom-left',
        BOTTOM: 'bottom',
        BOTTOM_RIGHT: 'bottom-right',

        LEFT_TOP: 'left-top',
        LEFT: 'left',
        LEFT_BOTTOM: 'left-bottom',

        RIGHT_TOP: 'right-top',
        RIGHT: 'right',
        RIGHT_BOTTOM: 'right-bottom'

    };

    static TriggerMode = {
        TOGGLE: 'toggle',
        OPEN: 'open'
    };

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.hasMounted = false;
        this.prepareCloseTimeout = null;
        this.requestCloseTimeout = null;

        this.state = {
            visible: false
        };

        this.triggerMouseEnterHandler = ::this.triggerMouseEnterHandler;
        this.triggerMouseLeaveHandler = ::this.triggerMouseLeaveHandler;
        this.resizeHandler = ::this.resizeHandler;
        this.debounceResizeHandle = _.debounce(::this.debounceResizeHandle, 150);
        this.initializeAnimation = ::this.initializeAnimation;
        this.animate = ::this.animate;
        this.wheelHandler = ::this.wheelHandler;

    }

    triggerMouseEnterHandler(e) {
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
    }

    triggerMouseLeaveHandler(e) {
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
        this.prepareCloseTimeout = setTimeout(() => {
            this.setState({
                visible: false
            }, () => {
                this.requestCloseTimeout && clearTimeout(this.requestCloseTimeout);
                this.requestCloseTimeout = setTimeout(() => {
                    const {onRequestClose} = this.props;
                    this.hasMounted && onRequestClose && onRequestClose();
                }, 250);
            });
        }, 100);
    }

    resizeHandler() {
        this.debounceResizeHandle();
    }

    debounceResizeHandle() {
        this.forceUpdate();
    }

    wheelHandler(e) {
        const {shouldPreventContainerScroll, onWheel} = this.props;
        shouldPreventContainerScroll && Event.preventContainerScroll(e);
        onWheel && onWheel(e);
    }

    initializeAnimation(callback) {
        setTimeout(() => {
            this.hasMounted && callback();
        }, 0);
    }

    animate() {
        this.setState({
            visible: true
        });
    }

    componentDidMount() {

        this.hasMounted = true;
        this.menuEl = findDOMNode(this.refs.menu);

        Event.addEvent(this.props.triggerEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.addEvent(this.props.triggerEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.addEvent(this.menuEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.addEvent(this.menuEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.addEvent(window, 'resize', this.resizeHandler);

    }

    componentWillAppear(callback) {
        this.initializeAnimation(callback);
    }

    componentDidAppear() {
        this.animate();
    }

    componentDidUpdate() {
        const {onRender} = this.props,
            {visible} = this.state;
        visible && onRender && onRender(this.menuEl, this.props.triggerEl);
    }

    componentWillUnmount() {

        this.hasMounted = false;
        this.prepareCloseTimeout && clearTimeout(this.prepareCloseTimeout);
        this.requestCloseTimeout && clearTimeout(this.requestCloseTimeout);

        Event.removeEvent(this.props.triggerEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.removeEvent(this.props.triggerEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.removeEvent(this.menuEl, 'mouseenter', this.triggerMouseEnterHandler);
        Event.removeEvent(this.menuEl, 'mouseleave', this.triggerMouseLeaveHandler);
        Event.removeEvent(window, 'resize', this.resizeHandler);

    }

    render() {

        const {
                children, className, style, theme, hasTriangle, triangle, position, isAnimated, depth, triggerEl
            } = this.props,
            {visible} = this.state,

            menuClassName = (visible ? '' : ' hidden') + (hasTriangle ? ' menu-has-triangle' : '')
                + (theme ? ` theme-${theme}` : '') + (position ? ` menu-position-${position}` : '')
                + (isAnimated ? ' menu-animated' : '') + (className ? ' ' + className : '');

        return (
            <Paper ref="menu"
                   className={'menu' + menuClassName}
                   style={{...PopupCalculation.getStyle(triggerEl, this.menuEl, position), ...style}}
                   depth={depth}
                   onWheel={this.wheelHandler}>

                {
                    hasTriangle ?

                            {triangle}

                        :
                        null
                }

                    {children}

            </Paper>
        );

    }
};

MenuBody.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * This is the DOM element that will be used to set the position of the popover.
     */
    triggerEl: PropTypes.object,

    /**
     * If true,the popover is visible.
     */
    visible: PropTypes.bool,

    /**
     * If true,the popover will have a triangle on the top of the DOM element.
     */
    hasTriangle: PropTypes.bool,

    triangle: PropTypes.element,

    /**
     * The popover theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The popover alignment.The value can be Menu.Position.LEFT or Menu.Position.RIGHT.
     */
    position: PropTypes.oneOf(Util.enumerateValue(MenuBody.Position)),

    /**
     * If true, menu will have animation effects.
     */
    isAnimated: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * The status of menu-triangle.Can be open or toggle.
     */
    triggerMode: PropTypes.oneOf(Util.enumerateValue(MenuBody.TriggerMode)),

    /**
     * The depth of Paper component.
     */
    depth: PropTypes.number,

    /**
     * The function of menu render.
     */
    onRender: PropTypes.func,

    /**
     * Callback function fired when the popover is requested to be closed.
     */
    onRequestClose: PropTypes.func,

    /**
     * Callback function fired when wrapper wheeled.
     */
    onWheel: PropTypes.func

};

MenuBody.defaultProps = {

    className: '',
    style: null,
    theme: Theme.DEFAULT,

    triggerEl: null,
    visible: false,
    hasTriangle: true,
    triangle:

,
    position: MenuBody.Position.BOTTOM_LEFT,
    isAnimated: true,
    triggerMode: MenuBody.TriggerMode.TOGGLE,
    depth: 6,
    shouldPreventContainerScroll: true

};<|endoftext|>


<commit_before>define('existingSession', ['collections'], function(collections) {
  'use strict';

  Template.existingSession.helpers({

    noUser: function() {
      return Session.equals('user', null);
    },

    shouldShowFullShareLink: function() {
      var query = { sessionId: Session.get('sessionId') };
      var users = collections.users.find(query).fetch();
      return users.length < 2;
    }

  });

});
<commit_msg>should return something<commit_after>define('existingSession', ['collections'], function(collections) {
  'use strict';

  Template.existingSession.helpers({

    noUser: function() {
      return Session.equals('user', null);
    },

    shouldShowFullShareLink: function() {
      var query = { sessionId: Session.get('sessionId') };
      var users = collections.users.find(query).fetch();
      return users.length < 2;
    }

  });

  return null;

});<|endoftext|>


<commit_before>const should = require('chai').should() // eslint-disable-line
const db = require('../api/db')

// created testId
let testId

before(() => {
})

describe('component', () => {
  it('should create a component', () => {
    const components = db.create('components')
    testId = components[components.length - 1].id
    testId.should.have.length(9)
  })

  it('should return an existing object using id', () => {
    const dbObject = db.find('components', testId)
    dbObject.should.not.be.empty
    dbObject.id.should.have.length(9)
  })

  it('should return a 404 upon nonexistant object using invalid id', () => {
    const dbObject = db.find('components', 'invalidId')
    dbObject.should.be.false
  })
})

after(() => {
})
<commit_msg>es6ify tests as well as switch to expect style<commit_after>import {expect} from 'chai'
import * as db from '../api/db'

// created testId
let testId

before(() => {
})

describe('component', () => {
  it('should create a component', () => {
    const components = db.create('components')
    testId = components[components.length - 1].id
    expect(testId).to.have.length(9)
  })

  it('should return an existing object using id', () => {
    const dbObject = db.find('components', testId)
    expect(dbObject).to.not.be.empty
    expect(dbObject.id).to.have.length(9)
  })

  it('should return a 404 upon nonexistant object using invalid id', () => {
    const dbObject = db.find('components', 'invalidId')
    expect(dbObject).to.be.false
  })
})

after(() => {
})
<|endoftext|>


<commit_before>"use strict"

const title = document.getElementById("title")
const msg = document.getElementById("msg")
const msg2 = document.getElementById("msg2")
const form = document.getElementById("form")
const input = document.getElementById("input")

const onePrep = () => e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    one(input.value)
}

const one = question => {
    input.value = ""
    msg.textContent = `what are some factors that affect '${question}'?`
    msg2.textContent = "they should also be yes/no, and separated with commas."
    form.onsubmit = twoPrep(question)
}

const twoPrep = question => e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    const factors = input.value.split(",").map(x => x.trim())
    if (factors.find(x => x === "") !== undefined) {
        msg2.textContent = "you can't have an empty factor."
        return
    }
    if (factors.length > 7) {
        msg2.textContent = "you can't have more than 7 factors."
        return
    }
    two(question, factors)
}

const newRow = n => {
    const row = document.createElement("div")
    for (let i = 0; i < n; i++) {
        const el = document.createElement("span")
        el.className = "green"
        el.textContent = "y"
        el.onclick = () => {
            if (el.className === "green") {
                el.className = "red"
                el.textContent = "n"
            } else {
                el.className = "green"
                el.textContent = "y"
            }
        }
        row.appendChild(el)
    }
    return row
}

const two = (question, factors) => {
    input.remove()
    msg.textContent = "enter some data."
    msg2.textContent = "click to add rows and switch between yes/no."

    const header = document.createElement("div")
    let el

    for (const x of factors) {
        el = document.createElement("span")
        el.textContent = x
        el.className = "blue"
        header.appendChild(el)
    }

    el = document.createElement("span")
    el.textContent = question
    el.className = "cyan"
    header.appendChild(el)

    form.appendChild(header)

    const footer = document.createElement("div")

    const addRowBtn = document.createElement("span")
    addRowBtn.innerHTML = "add datapoint"
    addRowBtn.className = "gray"
    addRowBtn.onclick = () => {
        form.insertBefore(newRow(factors.length + 1), footer)
    }

    const submitBtn = document.createElement("span")
    submitBtn.innerHTML = "submit data"
    submitBtn.className = "yellow"
    submitBtn.onclick = threePrep()

    footer.appendChild(addRowBtn)
    footer.appendChild(submitBtn)
    form.appendChild(footer)
}

const threePrep = () => {
    console.log("ye")
}

title.textContent = "machine learning™"
msg.textContent = "what is your question for today?"
msg2.textContent = "it should be a yes/no question."
input.focus()
form.onsubmit = onePrep()
form.style.display = "block"
<commit_msg>allow no ()<commit_after>"use strict"

const title = document.getElementById("title")
const msg = document.getElementById("msg")
const msg2 = document.getElementById("msg2")
const form = document.getElementById("form")
const input = document.getElementById("input")

const onePrep = e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    one(input.value)
}

const one = question => {
    input.value = ""
    msg.textContent = `what are some factors that affect '${question}'?`
    msg2.textContent = "they should also be yes/no, and separated with commas."
    form.onsubmit = twoPrep(question)
}

const twoPrep = question => e => {
    e.preventDefault()
    if (input.value.trim() === "") {
        msg2.textContent = "that can't be empty."
        return
    }
    const factors = input.value.split(",").map(x => x.trim())
    if (factors.find(x => x === "") !== undefined) {
        msg2.textContent = "you can't have an empty factor."
        return
    }
    if (factors.length > 7) {
        msg2.textContent = "you can't have more than 7 factors."
        return
    }
    two(question, factors)
}

const newRow = n => {
    const row = document.createElement("div")
    for (let i = 0; i < n; i++) {
        const el = document.createElement("span")
        el.className = "green"
        el.textContent = "y"
        el.onclick = () => {
            if (el.className === "green") {
                el.className = "red"
                el.textContent = "n"
            } else {
                el.className = "green"
                el.textContent = "y"
            }
        }
        row.appendChild(el)
    }
    return row
}

const two = (question, factors) => {
    input.remove()
    msg.textContent = "enter some data."
    msg2.textContent = "click to add rows and switch between yes/no."

    const header = document.createElement("div")
    let el

    for (const x of factors) {
        el = document.createElement("span")
        el.textContent = x
        el.className = "blue"
        header.appendChild(el)
    }

    el = document.createElement("span")
    el.textContent = question
    el.className = "cyan"
    header.appendChild(el)

    form.appendChild(header)

    const footer = document.createElement("div")

    const addRowBtn = document.createElement("span")
    addRowBtn.innerHTML = "add datapoint"
    addRowBtn.className = "gray"
    addRowBtn.onclick = () => {
        form.insertBefore(newRow(factors.length + 1), footer)
    }

    const submitBtn = document.createElement("span")
    submitBtn.innerHTML = "submit data"
    submitBtn.className = "yellow"
    submitBtn.onclick = threePrep()

    footer.appendChild(addRowBtn)
    footer.appendChild(submitBtn)
    form.appendChild(footer)
}

const threePrep = () => {
    console.log("ye")
}

title.textContent = "machine learning™"
msg.textContent = "what is your question for today?"
msg2.textContent = "it should be a yes/no question."
input.focus()
form.onsubmit = onePrep
form.style.display = "block"
<|endoftext|>


<commit_before>import React from 'react';
import { ScrollView, View, RefreshControl } from 'react-native';
import PropTypes from 'prop-types';
import { Spinner } from '../Spinner';
import styles from './styles';

const RefreshableMainScrollView = props => {
  const {
    children,
    header,
    loading,
    onRefresh,
    refreshing
  } = props;
  const renderSpinner = () => (
    <View style={styles.spinner}>
      <Spinner size='large' />
    </View>
  );
  const renderScrollView = () => (
    <ScrollView
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
        />
      }
    >
      {children}
    </ScrollView>
  );
  return (
    <View style={styles.container}>
      {header}
      {loading ? renderSpinner() : renderScrollView()}
    </View >
  );
};

RefreshableMainScrollView.defaultProps = {
  innerContainerStyle: [],
  refreshing: false
};

RefreshableMainScrollView.propTypes = {
  header: PropTypes.element,
  onRefresh: PropTypes.func,
  refreshing: PropTypes.bool
};

export { RefreshableMainScrollView };
<commit_msg>Fixed refreshing feature<commit_after>import React from 'react';
import { ScrollView, View, RefreshControl } from 'react-native';
import PropTypes from 'prop-types';
import { Spinner } from '../Spinner';
import styles from './styles';

const RefreshableMainScrollView = props => {
  const {
    children,
    header,
    loading,
    onRefresh,
    refreshing
  } = props;
  const renderSpinner = () => (
    <View style={styles.spinner}>
      <Spinner size='large' />
    </View>
  );
  return (
    <View style={styles.container}>
      {header}
      <ScrollView
        refreshControl={
          <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh}
          />
        }
        contentContainerStyle={[styles.body, loading && { flex: 1 }]}
      >
        {loading ? renderSpinner() : children}
      </ScrollView>
    </View >
  );
};

RefreshableMainScrollView.defaultProps = {
  innerContainerStyle: [],
  refreshing: false
};

RefreshableMainScrollView.propTypes = {
  header: PropTypes.element,
  onRefresh: PropTypes.func,
  refreshing: PropTypes.bool
};

export { RefreshableMainScrollView };
<|endoftext|>