<commit_before>const Cookies        = require('js-cookie');
const moment         = require('moment');
const ClientBase     = require('./client_base');
const Login          = require('./login');
const BinarySocket   = require('./socket_base');
const getElementById = require('../common_functions').getElementById;
const isVisible      = require('../common_functions').isVisible;
const getLanguage    = require('../language').get;
const State          = require('../storage').State;
const getAppId       = require('../../config').getAppId;

const GTM = (() => {
    // const isGtmApplicable = () => (/^(1|1098)$/.test(getAppId()));
    const isGtmApplicable = () => true;

    const getCommonVariables = () => ({
        language : getLanguage(),
        pageTitle: pageTitle(),
        pjax     : State.get('is_loaded_by_pjax'),
        url      : document.URL,
        ...ClientBase.isLoggedIn() && { visitorId: ClientBase.get('loginid') },
    });

    const pushDataLayer = (data) => {
        if (isGtmApplicable() && !Login.isLoginPages()) {
            dataLayer.push({
                ...getCommonVariables(),
                ...data,
            });
        }
    };

    const pageTitle = () => {
        const t = /^.+[:-]\s*(.+)$/.exec(document.title);
        return t && t[1] ? t[1] : document.title;
    };

    const eventHandler = (get_settings) => {
        if (!isGtmApplicable()) return;
        const is_login       = localStorage.getItem('GTM_login')       === '1';
        const is_new_account = localStorage.getItem('GTM_new_account') === '1';
        if (!is_login && !is_new_account) return;

        localStorage.removeItem('GTM_login');
        localStorage.removeItem('GTM_new_account');

        const affiliate_token = Cookies.getJSON('affiliate_tracking');
        if (affiliate_token) {
            pushDataLayer({ bom_affiliate_token: affiliate_token.t });
        }

        const data = {
            visitorId         : ClientBase.get('loginid'),
            bom_currency      : ClientBase.get('currency'),
            bom_country       : get_settings.country,
            bom_country_abbrev: get_settings.country_code,
            bom_email         : get_settings.email,
            url               : window.location.href,
            bom_today         : Math.floor(Date.now() / 1000),
            event             : is_new_account ? 'new_account' : 'log_in',
        };
        if (is_new_account) {
            data.bom_date_joined = data.bom_today;
        }
        if (!ClientBase.get('is_virtual')) {
            data.bom_age       = parseInt((moment().unix() - get_settings.date_of_birth) / 31557600);
            data.bom_firstname = get_settings.first_name;
            data.bom_lastname  = get_settings.last_name;
            data.bom_phone     = get_settings.phone;
        }

        if (is_login) {
            BinarySocket.wait('mt5_login_list').then((response) => {
                (response.mt5_login_list || []).forEach((obj) => {
                    const acc_type = (ClientBase.getMT5AccountType(obj.group) || '')
                        .replace('real_vanuatu', 'financial').replace('vanuatu_', '').replace('costarica', 'gaming'); // i.e. financial_cent, demo_cent, demo_gaming, real_gaming
                    if (acc_type) {
                        data[`mt5_${acc_type}_id`] = obj.login;
                    }
                });
                pushDataLayer(data);
            });
        } else {
            pushDataLayer(data);
        }
    };

    const pushPurchaseData = (response) => {
        if (!isGtmApplicable() || ClientBase.get('is_virtual')) return;
        const buy = response.buy;
        if (!buy) return;
        const req  = response.echo_req.passthrough;
        const data = {
            event             : 'buy_contract',
            visitorId         : ClientBase.get('loginid'),
            bom_symbol        : req.symbol,
            bom_market        : getElementById('contract_markets').value,
            bom_currency      : req.currency,
            bom_contract_type : req.contract_type,
            bom_contract_id   : buy.contract_id,
            bom_transaction_id: buy.transaction_id,
            bom_buy_price     : buy.buy_price,
            bom_payout        : buy.payout,
        };
        Object.assign(data, {
            bom_amount     : req.amount,
            bom_basis      : req.basis,
            bom_expiry_type: getElementById('expiry_type').value,
        });
        if (data.bom_expiry_type === 'duration') {
            Object.assign(data, {
                bom_duration     : req.duration,
                bom_duration_unit: req.duration_unit,
            });
        }
        if (isVisible(getElementById('barrier'))) {
            data.bom_barrier = req.barrier;
        } else if (isVisible(getElementById('barrier_high'))) {
            data.bom_barrier_high = req.barrier;
            data.bom_barrier_low  = req.barrier2;
        }
        if (isVisible(getElementById('prediction'))) {
            data.bom_prediction = req.barrier;
        }

        pushDataLayer(data);
    };

    const mt5NewAccount = (response) => {
        const acc_type = response.mt5_new_account.mt5_account_type ?
            `${response.mt5_new_account.account_type}_${response.mt5_new_account.mt5_account_type}` : // financial_cent, demo_cent, ...
            `${response.mt5_new_account.account_type === 'demo' ? 'demo' : 'real'}_gaming`;           // demo_gaming, real_gaming

        const gtm_data = {
            event          : 'mt5_new_account',
            bom_email      : ClientBase.get('email'),
            bom_country    : State.getResponse('get_settings.country'),
            mt5_last_signup: acc_type,
        };

        gtm_data[`mt5_${acc_type}_id`] = response.mt5_new_account.login;

        if (/demo/.test(acc_type) && !ClientBase.get('is_virtual')) {
            gtm_data.visitorId = ClientBase.getAccountOfType('virtual').loginid;
        }

        pushDataLayer(gtm_data);
    };

    return {
        pushDataLayer,
        eventHandler,
        pushPurchaseData,
        mt5NewAccount,
        setLoginFlag: () => { if (isGtmApplicable()) localStorage.setItem('GTM_login', '1'); },
    };
})();

module.exports = GTM;
<commit_msg>remove redundant field<commit_after>const Cookies        = require('js-cookie');
const moment         = require('moment');
const ClientBase     = require('./client_base');
const Login          = require('./login');
const BinarySocket   = require('./socket_base');
const getElementById = require('../common_functions').getElementById;
const isVisible      = require('../common_functions').isVisible;
const getLanguage    = require('../language').get;
const State          = require('../storage').State;
const getAppId       = require('../../config').getAppId;

const GTM = (() => {
    // const isGtmApplicable = () => (/^(1|1098)$/.test(getAppId()));
    const isGtmApplicable = () => true;

    const getCommonVariables = () => ({
        language : getLanguage(),
        pageTitle: pageTitle(),
        pjax     : State.get('is_loaded_by_pjax'),
        url      : document.URL,
        ...ClientBase.isLoggedIn() && { visitorId: ClientBase.get('loginid') },
    });

    const pushDataLayer = (data) => {
        if (isGtmApplicable() && !Login.isLoginPages()) {
            dataLayer.push({
                ...getCommonVariables(),
                ...data,
            });
        }
    };

    const pageTitle = () => {
        const t = /^.+[:-]\s*(.+)$/.exec(document.title);
        return t && t[1] ? t[1] : document.title;
    };

    const eventHandler = (get_settings) => {
        if (!isGtmApplicable()) return;
        const is_login       = localStorage.getItem('GTM_login')       === '1';
        const is_new_account = localStorage.getItem('GTM_new_account') === '1';
        if (!is_login && !is_new_account) return;

        localStorage.removeItem('GTM_login');
        localStorage.removeItem('GTM_new_account');

        const affiliate_token = Cookies.getJSON('affiliate_tracking');
        if (affiliate_token) {
            pushDataLayer({ bom_affiliate_token: affiliate_token.t });
        }

        const data = {
            visitorId         : ClientBase.get('loginid'),
            bom_currency      : ClientBase.get('currency'),
            bom_country       : get_settings.country,
            bom_country_abbrev: get_settings.country_code,
            bom_email         : get_settings.email,
            url               : window.location.href,
            bom_today         : Math.floor(Date.now() / 1000),
            event             : is_new_account ? 'new_account' : 'log_in',
        };
        if (is_new_account) {
            data.bom_date_joined = data.bom_today;
        }
        if (!ClientBase.get('is_virtual')) {
            data.bom_age       = parseInt((moment().unix() - get_settings.date_of_birth) / 31557600);
            data.bom_firstname = get_settings.first_name;
            data.bom_lastname  = get_settings.last_name;
            data.bom_phone     = get_settings.phone;
        }

        if (is_login) {
            BinarySocket.wait('mt5_login_list').then((response) => {
                (response.mt5_login_list || []).forEach((obj) => {
                    const acc_type = (ClientBase.getMT5AccountType(obj.group) || '')
                        .replace('real_vanuatu', 'financial').replace('vanuatu_', '').replace('costarica', 'gaming'); // i.e. financial_cent, demo_cent, demo_gaming, real_gaming
                    if (acc_type) {
                        data[`mt5_${acc_type}_id`] = obj.login;
                    }
                });
                pushDataLayer(data);
            });
        } else {
            pushDataLayer(data);
        }
    };

    const pushPurchaseData = (response) => {
        if (!isGtmApplicable() || ClientBase.get('is_virtual')) return;
        const buy = response.buy;
        if (!buy) return;
        const req  = response.echo_req.passthrough;
        const data = {
            event             : 'buy_contract',
            bom_symbol        : req.symbol,
            bom_market        : getElementById('contract_markets').value,
            bom_currency      : req.currency,
            bom_contract_type : req.contract_type,
            bom_contract_id   : buy.contract_id,
            bom_transaction_id: buy.transaction_id,
            bom_buy_price     : buy.buy_price,
            bom_payout        : buy.payout,
        };
        Object.assign(data, {
            bom_amount     : req.amount,
            bom_basis      : req.basis,
            bom_expiry_type: getElementById('expiry_type').value,
        });
        if (data.bom_expiry_type === 'duration') {
            Object.assign(data, {
                bom_duration     : req.duration,
                bom_duration_unit: req.duration_unit,
            });
        }
        if (isVisible(getElementById('barrier'))) {
            data.bom_barrier = req.barrier;
        } else if (isVisible(getElementById('barrier_high'))) {
            data.bom_barrier_high = req.barrier;
            data.bom_barrier_low  = req.barrier2;
        }
        if (isVisible(getElementById('prediction'))) {
            data.bom_prediction = req.barrier;
        }

        pushDataLayer(data);
    };

    const mt5NewAccount = (response) => {
        const acc_type = response.mt5_new_account.mt5_account_type ?
            `${response.mt5_new_account.account_type}_${response.mt5_new_account.mt5_account_type}` : // financial_cent, demo_cent, ...
            `${response.mt5_new_account.account_type === 'demo' ? 'demo' : 'real'}_gaming`;           // demo_gaming, real_gaming

        const gtm_data = {
            event          : 'mt5_new_account',
            bom_email      : ClientBase.get('email'),
            bom_country    : State.getResponse('get_settings.country'),
            mt5_last_signup: acc_type,
        };

        gtm_data[`mt5_${acc_type}_id`] = response.mt5_new_account.login;

        if (/demo/.test(acc_type) && !ClientBase.get('is_virtual')) {
            gtm_data.visitorId = ClientBase.getAccountOfType('virtual').loginid;
        }

        pushDataLayer(gtm_data);
    };

    return {
        pushDataLayer,
        eventHandler,
        pushPurchaseData,
        mt5NewAccount,
        setLoginFlag: () => { if (isGtmApplicable()) localStorage.setItem('GTM_login', '1'); },
    };
})();

module.exports = GTM;
<|endoftext|>


<commit_before>(function(){
  "use strict";

  const d = document;

  function createDiv(className) {
    const div = d.createElement('div');
    div.className = className;
    return div;
  }

  function appendDiv(node, className) {
    return node.appendChild(createDiv(className));
  }

  function createNode(text) {
    const node = createDiv('Node collapsed');
    appendDiv(node, 'Expander');
    const content = appendDiv(node, 'Content');
    content.contentEditable = 'true';
    if(text) content.textContent = text;
    appendDiv(node, 'Children');
    return node;
  }

  function expanderElement(node) { return node.firstChild; }
  function contentElement(node) { return node.children[1]; }
  function childrenElement(node) { return node.lastChild; }
  function parentNode(node) {
    node = node.parentElement;
    if(node && node.classList.contains('Children')) return node.parentElement;
    return null;
  }

  function isExpanded(node) { return node.classList.contains('expanded'); }
  function swapClass(node, oldClass, newClass) {
    node.classList.remove(oldClass);
    node.classList.add(newClass);
  }
  function expand(node) { swapClass(node, 'collapsed', 'expanded'); }
  function collapse(node) { swapClass(node, 'expanded', 'collapsed'); }
  function toggle(node) { (isExpanded(node)?collapse:expand)(node); }

  function focusContent(node) {
    if(node) contentElement(node).focus();
  }

  function lastVisibleLeaf(node) {
    while(node && isExpanded(node)) {
      var lastChild = childrenElement(node).lastChild;
      if(lastChild) node = lastChild;
    }
    return node;
  }

  function focusPrevContent(node) {
    var prev = node.previousSibling;
    if(prev) prev = lastVisibleLeaf(prev);
    else prev = parentNode(node);
    focusContent(prev);
  }

  function focusNextContent(node) {
    var next = isExpanded(node) ? childrenElement(node).firstChild : node.nextSibling;
    if(!next) {
      const parent = parentNode(node);
      if(parent) next = parent.nextSibling;
    }
    focusContent(next);
  }

  function appendSibling(node, sibling) {
    return node.insertAdjacentElement('afterEnd', sibling);
  }

  function prependSibling(node, sibling) {
    return node.insertAdjacentElement('beforeBegin', sibling);
  }

  function appendChild(node, child) {
    return childrenElement(node).appendChild(child);
  }

  function appendNewSiblingOrFirstChild(node) {
    if(isExpanded(node)) {
      const firstChild = childrenElement(node).firstChild;
      if(firstChild) {
        focusContent(prependSibling(firstChild, createNode()));
        return;
      }
    }
    focusContent(appendSibling(node, createNode()));
  }

  function indent(node) {
    const prev = node.previousSibling;
    if(prev) {
      expand(prev);
      appendChild(prev, node);
      focusContent(node);
    }
  }

  function outdent(node) {
    const parent = parentNode(node);
    if(parent) {
      appendSibling(parent, node);
      focusContent(node);
    }
  }

  function moveUp(node) {
    const prev = node.previousSibling || parentNode(node);
    if(prev) {
      prependSibling(prev, node);
      focusContent(node);
    }
  }

  function moveDown(node) {
    const next = node.nextSibling || parentNode(node);
    if(next) {
      appendSibling(next, node);
      focusContent(node);
    }
  }

  const outlinerElement = d.getElementById('outliner');
  focusContent(outlinerElement.appendChild(createNode('Test')));

  outlinerElement.addEventListener('click', e => {
    if(e.target.classList.contains('Expander')) {
      toggle(e.target.parentElement);
    }
  });

  const MOD_NONE = 0, MOD_CTRL = 1, MOD_ALT = 2, MOD_SHIFT = 4, MOD_META = 8;
  function getModKeys(e) {
    var mod = MOD_NONE;
    if(e.ctrlKey) mod += MOD_CTRL;
    if(e.altKey) mod += MOD_ALT;
    if(e.shiftKey) mod += MOD_SHIFT;
    if(e.metaKey) mod += MOD_META;
    return mod;
  }

  outlinerElement.addEventListener('keydown', e => {
    const node = e.target.parentElement;
    switch(e.key) {
      case 'Enter':
      if(getModKeys(e) == MOD_NONE) { appendNewSiblingOrFirstChild(node); e.preventDefault(); }
      break;

      case 'Tab':
      e.preventDefault();
      switch(getModKeys(e)) {
        case MOD_NONE: indent(node); break;
        case MOD_SHIFT: outdent(node); break;
      }
      break;

      case 'ArrowUp':
      switch(getModKeys(e)) {
        case MOD_ALT: moveUp(node); e.preventDefault(); break;
        case MOD_CTRL: focusPrevContent(node); e.preventDefault();break;
      }
      break;

      case 'ArrowDown':
      switch(getModKeys(e)) {
        case MOD_ALT: moveDown(node); e.preventDefault(); break;
        case MOD_CTRL: focusNextContent(node); e.preventDefault();break;
      }
      break;

      case 'ArrowLeft':
      if(getModKeys(e) == MOD_ALT) { outdent(node); e.preventDefault(); }
      break;

      case 'ArrowRight':
      if(getModKeys(e) == MOD_ALT) { indent(node); e.preventDefault(); }
      break;
    }
  });
}())<commit_msg>Bug fix<commit_after>(function(){
  "use strict";

  const d = document;

  function createDiv(className) {
    const div = d.createElement('div');
    div.className = className;
    return div;
  }

  function appendDiv(node, className) {
    return node.appendChild(createDiv(className));
  }

  function createNode(text) {
    const node = createDiv('Node collapsed');
    appendDiv(node, 'Expander');
    const content = appendDiv(node, 'Content');
    content.contentEditable = 'true';
    if(text) content.textContent = text;
    appendDiv(node, 'Children');
    return node;
  }

  function expanderElement(node) { return node.firstChild; }
  function contentElement(node) { return node.children[1]; }
  function childrenElement(node) { return node.lastChild; }
  function parentNode(node) {
    node = node.parentElement;
    if(node && node.classList.contains('Children')) return node.parentElement;
    return null;
  }

  function isExpanded(node) { return node.classList.contains('expanded'); }
  function swapClass(node, oldClass, newClass) {
    node.classList.remove(oldClass);
    node.classList.add(newClass);
  }
  function expand(node) { swapClass(node, 'collapsed', 'expanded'); }
  function collapse(node) { swapClass(node, 'expanded', 'collapsed'); }
  function toggle(node) { (isExpanded(node)?collapse:expand)(node); }

  function focusContent(node) {
    if(node) contentElement(node).focus();
  }

  function lastVisibleLeaf(node) {
    while(node && isExpanded(node)) {
      var lastChild = childrenElement(node).lastChild;
      if(lastChild) node = lastChild;
    }
    return node;
  }

  function focusPrevContent(node) {
    focusContent(lastVisibleLeaf(node.previousSibling) || parentNode(node));
  }

  function focusNextContent(node) {
    var next = isExpanded(node) ? childrenElement(node).firstChild : node.nextSibling;
    if(!next) {
      const parent = parentNode(node);
      if(parent) next = parent.nextSibling;
    }
    focusContent(next);
  }

  function appendSibling(node, sibling) {
    return node.insertAdjacentElement('afterEnd', sibling);
  }

  function prependSibling(node, sibling) {
    return node.insertAdjacentElement('beforeBegin', sibling);
  }

  function appendChild(node, child) {
    return childrenElement(node).appendChild(child);
  }

  function appendNewSiblingOrFirstChild(node) {
    if(isExpanded(node)) {
      const firstChild = childrenElement(node).firstChild;
      if(firstChild) {
        focusContent(prependSibling(firstChild, createNode()));
        return;
      }
    }
    focusContent(appendSibling(node, createNode()));
  }

  function indent(node) {
    const prev = node.previousSibling;
    if(prev) {
      expand(prev);
      appendChild(prev, node);
      focusContent(node);
    }
  }

  function outdent(node) {
    const parent = parentNode(node);
    if(parent) {
      appendSibling(parent, node);
      focusContent(node);
    }
  }

  function moveUp(node) {
    const prev = node.previousSibling || parentNode(node);
    if(prev) {
      prependSibling(prev, node);
      focusContent(node);
    }
  }

  function moveDown(node) {
    const next = node.nextSibling || parentNode(node);
    if(next) {
      appendSibling(next, node);
      focusContent(node);
    }
  }

  const outlinerElement = d.getElementById('outliner');
  focusContent(outlinerElement.appendChild(createNode('Test')));

  outlinerElement.addEventListener('click', e => {
    if(e.target.classList.contains('Expander')) {
      toggle(e.target.parentElement);
    }
  });

  const MOD_NONE = 0, MOD_CTRL = 1, MOD_ALT = 2, MOD_SHIFT = 4, MOD_META = 8;
  function getModKeys(e) {
    var mod = MOD_NONE;
    if(e.ctrlKey) mod += MOD_CTRL;
    if(e.altKey) mod += MOD_ALT;
    if(e.shiftKey) mod += MOD_SHIFT;
    if(e.metaKey) mod += MOD_META;
    return mod;
  }

  outlinerElement.addEventListener('keydown', e => {
    const node = e.target.parentElement;
    switch(e.key) {
      case 'Enter':
      if(getModKeys(e) == MOD_NONE) { appendNewSiblingOrFirstChild(node); e.preventDefault(); }
      break;

      case 'Tab':
      e.preventDefault();
      switch(getModKeys(e)) {
        case MOD_NONE: indent(node); break;
        case MOD_SHIFT: outdent(node); break;
      }
      break;

      case 'ArrowUp':
      switch(getModKeys(e)) {
        case MOD_ALT: moveUp(node); e.preventDefault(); break;
        case MOD_CTRL: focusPrevContent(node); e.preventDefault();break;
      }
      break;

      case 'ArrowDown':
      switch(getModKeys(e)) {
        case MOD_ALT: moveDown(node); e.preventDefault(); break;
        case MOD_CTRL: focusNextContent(node); e.preventDefault();break;
      }
      break;

      case 'ArrowLeft':
      if(getModKeys(e) == MOD_ALT) { outdent(node); e.preventDefault(); }
      break;

      case 'ArrowRight':
      if(getModKeys(e) == MOD_ALT) { indent(node); e.preventDefault(); }
      break;
    }
  });
}())<|endoftext|>


<commit_before>"use strict";

import d3 from 'd3'
import React, { PropTypes } from 'react'
import Player from 'component/Player'
import getRandomColor from 'utils/getRandomColor'

export default React.createClass({

  propTypes: {
    // Функция добавляет новую точку и возвращает текущий массив точек
    points: PropTypes.func.isRequired,
    // Текущий цвет
    color: PropTypes.object.isRequired,
    // Текущее кол-во точек для соединения
    number: PropTypes.number.isRequired,
    // КолБэк на изменение цвета
    handleChangeColor: PropTypes.func.isRequired
  },

  getInitialState() {
    return {
      animationFlag: false
    }
  },

  componentDidMount() {
    this.graph = d3.select('svg')
  },

  clickHandlerSvg(e) {
    const { points, number, color } = this.props

    if (this.state.animationFlag) {
      alert('Остановите показ, чтобы начать рисовать!')
      return
    }

    points({
      x: parseInt(e.clientX - (this.graph[0][0] ? this.graph[0][0].getBoundingClientRect().left : 0)),
      y: parseInt(e.clientY - (this.graph[0][0] ? this.graph[0][0].getBoundingClientRect().top : 0)),
      color: color.rgb,
      opacity: color.opacity,
      number: points().length < number ? points().length : number
    }, () => {
      // Рисуем точки и линии
      this.drawChart()
      // Обновляем зывисимости
      this.updateDependence()
    })

  },

  drawChart(index = this.props.points().length - 1) {
    const { points } = this.props
    const dotRadius = 5
    const dotRadii = [dotRadius/5, dotRadius/1.25, dotRadius/2, dotRadius*1.25, dotRadius]
    const point = points()[index]
    const duration = 100

    // Перед началом очищаем рабочую область
    if (index === 0) this.clearGraph()

    // Рисуем кружочки
    let circle = this.graph.append('circle')
      .style('fill', point.color)
      .style('opacity', point.opacity)
      .attr('r', dotRadii[0])
      .attr('cx', point.x)
      .attr('cy', point.y)

    // Анимируем кружочки
    dotRadii.forEach((val, i) => {
      circle
        .transition()
        .duration(duration)
        .delay(i * duration)
        .attr('r', val)
    })

    // Рисуем линии
    for (let i = 0; i < point.number; i++) {
      const prevPoint = points()[index-i-1]
      this.graph.append('line')
        .style('stroke', point.color)
        .style('opacity', point.opacity)
        .style('stroke-width', dotRadius / 2)
        .attr({
          x1: prevPoint.x,
          y1: prevPoint.y,
          x2: prevPoint.x,
          y2: prevPoint.y
        })
        .transition()
        .duration(duration * 5)
        .attr({
          x2: point.x,
          y2: point.y
        })
    }
  },

  updateDependence() {
    // Для новой линии генерируем новый случайный цвет
    this.props.handleChangeColor( getRandomColor() )
  },

  clearGraph() {
    this.graph.selectAll('*').remove()
  },

  setAnimationFlag(status) {
    this.setState({ animationFlag: status })
  },

  render() {
    return (

        <svg testRef='svg' className='sd' onClick={this.clickHandlerSvg} />
        <Player
          points={this.props.points()}
          drawChart={this.drawChart}
          animationFlag={this.state.animationFlag}
          setAnimationFlag={this.setAnimationFlag}
        />

    )
  }
})<commit_msg>clear code<commit_after>"use strict";

import d3 from 'd3'
import React, { PropTypes } from 'react'
import Player from 'component/Player'
import getRandomColor from 'utils/getRandomColor'

export default React.createClass({

  propTypes: {
    // Функция добавляет новую точку и возвращает текущий массив точек
    points: PropTypes.func.isRequired,
    // Текущий цвет
    color: PropTypes.object.isRequired,
    // Текущее кол-во точек для соединения
    number: PropTypes.number.isRequired,
    // КолБэк на изменение цвета
    handleChangeColor: PropTypes.func.isRequired
  },

  getInitialState() {
    return {
      animationFlag: false
    }
  },

  componentDidMount() {
    this.graph = d3.select('svg')
  },

  clickHandlerSvg(e) {
    const { points, number, color } = this.props

    if (this.state.animationFlag) {
      alert('Остановите показ, чтобы начать рисовать!')
      return
    }

    points({
      x: parseInt(e.clientX - (this.graph[0][0] ? this.graph[0][0].getBoundingClientRect().left : 0)),
      y: parseInt(e.clientY - (this.graph[0][0] ? this.graph[0][0].getBoundingClientRect().top : 0)),
      color: color.rgb,
      opacity: color.opacity,
      number: points().length < number ? points().length : number
    }, () => {
      // Рисуем точки и линии
      this.drawChart()
      // Обновляем зывисимости
      this.updateDependence()
    })

  },

  drawChart(index = this.props.points().length - 1) {
    const { points } = this.props
    const dotRadius = 5
    const dotRadii = [dotRadius/5, dotRadius/1.25, dotRadius/2, dotRadius*1.25, dotRadius]
    const point = points()[index]
    const duration = 100

    // Перед началом очищаем рабочую область
    if (index === 0) this.clearGraph()

    // Рисуем кружочки
    let circle = this.graph.append('circle')
      .style('fill', point.color)
      .style('opacity', point.opacity)
      .attr('r', dotRadii[0])
      .attr('cx', point.x)
      .attr('cy', point.y)

    // Анимируем кружочки
    dotRadii.forEach((val, i) => {
      circle
        .transition()
        .duration(duration)
        .delay(i * duration)
        .attr('r', val)
    })

    // Рисуем линии
    for (let i = 0; i < point.number; i++) {
      const prevPoint = points()[index-i-1]
      this.graph.append('line')
        .style('stroke', point.color)
        .style('opacity', point.opacity)
        .style('stroke-width', dotRadius / 2)
        .attr({
          x1: prevPoint.x,
          y1: prevPoint.y,
          x2: prevPoint.x,
          y2: prevPoint.y
        })
        .transition()
        .duration(duration * 5)
        .attr({
          x2: point.x,
          y2: point.y
        })
    }
  },

  updateDependence() {
    // Для новой линии генерируем новый случайный цвет
    this.props.handleChangeColor( getRandomColor() )
  },

  clearGraph() {
    this.graph.selectAll('*').remove()
  },

  setAnimationFlag(status) {
    this.setState({ animationFlag: status })
  },

  render() {
    return (

        <svg testRef='svg' onClick={this.clickHandlerSvg} />
        <Player
          points={this.props.points()}
          drawChart={this.drawChart}
          animationFlag={this.state.animationFlag}
          setAnimationFlag={this.setAnimationFlag}
        />

    )
  }
})<|endoftext|>


<commit_before>import * as THREE from 'three';

import Config from '../../data/config';
import Helpers from '../../utils/helpers';

export default class SoundZone {
  constructor(main, points) {
    this.type = 'SoundZone';
    this.isActive = true;
    this.mouse = main.mouse;
    this.scene = main.scene;

    this.splinePoints = points;
    this.pointObjects;
    this.spline;
    this.shape;
    this.sound;
    this.isPlaying = false;
    this.selectedPoint;
    this.mouseOffsetX = 0, this.mouseOffsetY = 0;
    this.buffer;
    this.audio = main.audio;

    this.cursor = new THREE.Mesh(
      new THREE.SphereGeometry(10),
      new THREE.MeshBasicMaterial({ color: 0x00ccff }),
    );

    this.cursor.visible = false;
    this.renderPath();
  }

  underUser() {
    if (this.sound && !this.isPlaying) {
      this.sound.source = this.audio.context.createBufferSource();
      this.sound.source.loop = true;
      this.sound.source.connect(this.sound.volume);
      this.sound.source.buffer = this.buffer;
      this.sound.source.start(this.audio.context.currentTime);
      this.sound.volume.gain.setTargetAtTime(0.3, this.audio.context.currentTime + 0.1, 0.1);
      this.isPlaying = true;
    }
  }

  notUnderUser() {
    if (this.sound && this.isPlaying) {
      this.sound.volume.gain.setTargetAtTime(0.0, this.audio.context.currentTime, 0.05);
      this.sound.source.stop(this.audio.context.currentTime + 0.2);
      this.isPlaying = false;
    }
  }

  loadSound(soundFileName) {
    const context = this.audio.context;
    const sound = {};

    sound.volume = context.createGain();
    sound.volume.connect(this.audio.destination);

    const request = new XMLHttpRequest();
    request.open('GET', soundFileName, true);
    request.responseType = 'arraybuffer';
    request.onload = () => {
      context.decodeAudioData(request.response, (buffer) => {
        this.buffer = buffer;
      }, () => {
        alert('Decoding the audio buffer failed');
      });
    };

    request.send();
    sound.volume.gain.value = 0.0;
    this.sound = sound;
  }

  renderPath() {
    // splinePoints control the curve of the path
    const points = this.splinePoints;
    this.pointObjects = (() => {
      // setup
      const sphere = new THREE.SphereGeometry(10);
      const sphereMat = new THREE.MeshBasicMaterial( { color:0xff1169 } );

      const collider = new THREE.SphereGeometry(15);
      const colliderMat = new THREE.MeshBasicMaterial( {color:0xff1169, transparent:true, opacity:0, depthWrite: false});
      const colliderMesh = new THREE.Mesh( collider, colliderMat );

      // place a meshgroup at each point in array
      const pointObjects = [];
      points.forEach((point) => {
        const sphereMesh = new THREE.Mesh(sphere, sphereMat.clone());
        const group = new THREE.Object3D();

        group.add(sphereMesh, colliderMesh.clone());
        group.position.copy(point);
        // group.position.z = -300;

        pointObjects.push(group);
      });
      return pointObjects;
    })();

    this.spline = new THREE.CatmullRomCurve3(this.splinePoints);
    this.spline.type = 'centripetal';
    this.spline.closed = true;

    const geometry = new THREE.Geometry();
    let material = new THREE.LineBasicMaterial({
      color: 0xff1169,
      linewidth: 1,
      transparent: true,
      opacity: 0.4
    });

    geometry.vertices = this.spline.getPoints(200);
    this.spline.mesh = new THREE.Line( geometry, material );

    // fill the path
    const rotatedPoints = this.spline.getPoints(200);
    rotatedPoints.forEach(function (vertex){
      vertex.y = vertex.z;
      vertex.z = 0.0;
    });
    const shapeFill = new THREE.Shape();
    shapeFill.fromPoints(rotatedPoints);
    const shapeGeometry = new THREE.ShapeGeometry(shapeFill);
    shapeGeometry.rotateX(Math.PI/2);
    material = new THREE.MeshBasicMaterial({
      color: 0xff1169,
      transparent: true,
      opacity: 0.2,
      side: THREE.DoubleSide,
    });

    this.shape = new THREE.Mesh(shapeGeometry, material);
  }

  get objects() {
    return [].concat(this.pointObjects, this.spline.mesh, this.shape);
  }

  addToScene() {
    this.objects.forEach((obj) => {
      this.scene.add(obj);
    });

    this.scene.add(this.cursor);
  }

  removeFromScene() {
    this.objects.forEach((obj) => {
      this.scene.remove(obj, true);
    });
    this.scene.remove(this.cursor);
  }

  // raycast to this soundzone
  isUnderMouse(raycaster) {
    if (this.isActive) {
      return raycaster.intersectObjects(this.objects).length > 0;
    } else {
      return raycaster.intersectObject(this.shape).length > 0;
    }
  }

  objectUnderMouse(raycaster) {
    const intersects = raycaster.intersectObjects(this.objects, true);

    if (intersects.length > 0) {
      if (intersects[0].object.type === 'Line') {
        return intersects[Math.floor(intersects.length/2)];
      } else {
        return intersects[0];
      }
    }

    return null;
  }

  setMouseOffset(point) {
    this.mouseOffsetX = point.x,
      this.mouseOffsetY = point.z;
  }

  updateZone() {
    const scene = this.spline.mesh.parent;
    this.removeFromScene(scene);
    this.renderPath();
    this.addToScene(scene);
  }

  move(main) {
    if (!main.perspectiveView) {
      if (this.selectedPoint) {
        // move selected point
        const i = this.pointObjects.indexOf(this.selectedPoint);
        if (i > -1) {
          this.showCursor(false);
          this.splinePoints[i].copy(main.mouse);
          this.updateZone();
          this.selectPoint(this.pointObjects[i]);
        }
      } else {
        // move entire shape
        const dx = main.mouse.x - this.mouseOffsetX;
        const dy = main.mouse.z - this.mouseOffsetY;
        this.mouseOffsetX = main.mouse.x;
        this.mouseOffsetY = main.mouse.z;

        this.objects.forEach((obj) => {
          obj.position.x += dx;
          obj.position.z += dy;
        });

        this.splinePoints.forEach((pt) => {
          pt.x += dx;
          pt.z += dy;
        });
      }
    }
  }

  setCursor(point) {
    this.cursor.position.copy(point);
  }

  showCursor(bool) {
    if (bool === undefined) this.cursor.visible = true;
    this.cursor.visible = bool;
  }

  setActive(main) {
    this.setMouseOffset(main.mouse);
    this.isActive = true;
    this.pointObjects.forEach(obj => obj.visible = true);
    this.spline.mesh.visible = true;
  }

  setInactive() {
    this.deselectPoint();
    this.showCursor(false);
    this.isActive = false;
    this.pointObjects.forEach(obj => obj.visible = false);
    this.spline.mesh.visible = false;
  }

  select(intersect) {
    if (!intersect) return;

    // obj can be the curve, a spline point, or the shape mesh
    const obj = intersect.object;

    if (obj.type === 'Line') {
      // add a point to the line
      this.addPoint(intersect.point);
    } else if (obj.parent.type === 'Object3D') {
      // select an existing point on line
      this.selectPoint(obj.parent);
    } else {
      this.deselectPoint();
      this.setMouseOffset(intersect.point);
    }
  }

  addPoint(position) {
    let closestSplinePoint = 0;
    let prevDistToSplinePoint = -1;
    let minDistance = Number.MAX_VALUE;
    let minPoint = 1;

    // search for point on spline
    for (let t = 0; t < 1; t += 1 / 200.0) {
      const pt = this.spline.getPoint(t);

      const distToSplinePoint = this.splinePoints[closestSplinePoint].distanceToSquared(pt);
      if (distToSplinePoint > prevDistToSplinePoint) {
        closestSplinePoint += 1;

        if (closestSplinePoint >= this.splinePoints.length)
          closestSplinePoint = 0;
      }
      prevDistToSplinePoint = this.splinePoints[closestSplinePoint].distanceToSquared(pt);
      const distToPoint = pt.distanceToSquared(position);
      if (distToPoint < minDistance) {
        minDistance = distToPoint;
        minPoint = closestSplinePoint;
      }
    }

    this.splinePoints.splice(minPoint, 0, position);
    this.updateZone();
    this.selectPoint(this.pointObjects[minPoint]);
  }

  selectPoint(obj) {
    this.deselectPoint();
    this.selectedPoint = obj;
    obj.children[0].material.color.set('blue');
  }

  deselectPoint() {
    if (this.selectedPoint) {
      this.selectedPoint.children[0].material.color.set('red');
      this.selectedPoint = null;
    }
  }
}
<commit_msg>Fix remove zone point<commit_after>import * as THREE from 'three';

import Config from '../../data/config';
import Helpers from '../../utils/helpers';

export default class SoundZone {
  constructor(main, points) {
    this.type = 'SoundZone';
    this.isActive = true;
    this.mouse = main.mouse;
    this.scene = main.scene;

    this.splinePoints = points;
    this.pointObjects;
    this.spline;
    this.shape;
    this.sound;
    this.isPlaying = false;
    this.selectedPoint;
    this.mouseOffsetX = 0, this.mouseOffsetY = 0;
    this.buffer;
    this.audio = main.audio;

    this.cursor = new THREE.Mesh(
      new THREE.SphereGeometry(10),
      new THREE.MeshBasicMaterial({ color: 0x00ccff }),
    );

    this.cursor.visible = false;
    this.renderPath();
  }

  underUser() {
    if (this.sound && !this.isPlaying) {
      this.sound.source = this.audio.context.createBufferSource();
      this.sound.source.loop = true;
      this.sound.source.connect(this.sound.volume);
      this.sound.source.buffer = this.buffer;
      this.sound.source.start(this.audio.context.currentTime);
      this.sound.volume.gain.setTargetAtTime(0.3, this.audio.context.currentTime + 0.1, 0.1);
      this.isPlaying = true;
    }
  }

  notUnderUser() {
    if (this.sound && this.isPlaying) {
      this.sound.volume.gain.setTargetAtTime(0.0, this.audio.context.currentTime, 0.05);
      this.sound.source.stop(this.audio.context.currentTime + 0.2);
      this.isPlaying = false;
    }
  }

  loadSound(soundFileName) {
    const context = this.audio.context;
    const sound = {};

    sound.volume = context.createGain();
    sound.volume.connect(this.audio.destination);

    const request = new XMLHttpRequest();
    request.open('GET', soundFileName, true);
    request.responseType = 'arraybuffer';
    request.onload = () => {
      context.decodeAudioData(request.response, (buffer) => {
        this.buffer = buffer;
      }, () => {
        alert('Decoding the audio buffer failed');
      });
    };

    request.send();
    sound.volume.gain.value = 0.0;
    this.sound = sound;
  }

  renderPath() {
    // splinePoints control the curve of the path
    const points = this.splinePoints;
    this.pointObjects = (() => {
      // setup
      const sphere = new THREE.SphereGeometry(10);
      const sphereMat = new THREE.MeshBasicMaterial( { color:0xff1169 } );

      const collider = new THREE.SphereGeometry(15);
      const colliderMat = new THREE.MeshBasicMaterial( {color:0xff1169, transparent:true, opacity:0, depthWrite: false});
      const colliderMesh = new THREE.Mesh( collider, colliderMat );

      // place a meshgroup at each point in array
      const pointObjects = [];
      points.forEach((point) => {
        const sphereMesh = new THREE.Mesh(sphere, sphereMat.clone());
        const group = new THREE.Object3D();

        group.add(sphereMesh, colliderMesh.clone());
        group.position.copy(point);
        // group.position.z = -300;

        pointObjects.push(group);
      });
      return pointObjects;
    })();

    this.spline = new THREE.CatmullRomCurve3(this.splinePoints);
    this.spline.type = 'centripetal';
    this.spline.closed = true;

    const geometry = new THREE.Geometry();
    let material = new THREE.LineBasicMaterial({
      color: 0xff1169,
      linewidth: 1,
      transparent: true,
      opacity: 0.4
    });

    geometry.vertices = this.spline.getPoints(200);
    this.spline.mesh = new THREE.Line( geometry, material );

    // fill the path
    const rotatedPoints = this.spline.getPoints(200);
    rotatedPoints.forEach(function (vertex){
      vertex.y = vertex.z;
      vertex.z = 0.0;
    });
    const shapeFill = new THREE.Shape();
    shapeFill.fromPoints(rotatedPoints);
    const shapeGeometry = new THREE.ShapeGeometry(shapeFill);
    shapeGeometry.rotateX(Math.PI/2);
    material = new THREE.MeshBasicMaterial({
      color: 0xff1169,
      transparent: true,
      opacity: 0.2,
      side: THREE.DoubleSide,
    });

    this.shape = new THREE.Mesh(shapeGeometry, material);
  }

  get objects() {
    return [].concat(this.pointObjects, this.spline.mesh, this.shape);
  }

  addToScene() {
    this.objects.forEach((obj) => {
      this.scene.add(obj);
    });

    this.scene.add(this.cursor);
  }

  removeFromScene() {
    this.objects.forEach((obj) => {
      this.scene.remove(obj, true);
    });
    this.scene.remove(this.cursor);
  }

  // raycast to this soundzone
  isUnderMouse(raycaster) {
    if (this.isActive) {
      return raycaster.intersectObjects(this.objects).length > 0;
    } else {
      return raycaster.intersectObject(this.shape).length > 0;
    }
  }

  objectUnderMouse(raycaster) {
    const intersects = raycaster.intersectObjects(this.objects, true);

    if (intersects.length > 0) {
      if (intersects[0].object.type === 'Line') {
        return intersects[Math.floor(intersects.length/2)];
      } else {
        return intersects[0];
      }
    }

    return null;
  }

  setMouseOffset(point) {
    this.mouseOffsetX = point.x,
      this.mouseOffsetY = point.z;
  }

  updateZone() {
    const scene = this.spline.mesh.parent;
    this.removeFromScene(scene);
    this.renderPath();
    this.addToScene(scene);
  }

  move(main) {
    if (!main.perspectiveView) {
      if (this.selectedPoint) {
        // move selected point
        const i = this.pointObjects.indexOf(this.selectedPoint);
        if (i > -1) {
          this.showCursor(false);
          this.splinePoints[i].copy(main.mouse);
          this.updateZone();
          this.selectPoint(this.pointObjects[i]);
        }
      } else {
        // move entire shape
        const dx = main.mouse.x - this.mouseOffsetX;
        const dy = main.mouse.z - this.mouseOffsetY;
        this.mouseOffsetX = main.mouse.x;
        this.mouseOffsetY = main.mouse.z;

        this.objects.forEach((obj) => {
          obj.position.x += dx;
          obj.position.z += dy;
        });

        this.splinePoints.forEach((pt) => {
          pt.x += dx;
          pt.z += dy;
        });
      }
    }
  }

  setCursor(point) {
    this.cursor.position.copy(point);
  }

  showCursor(bool) {
    if (bool === undefined) this.cursor.visible = true;
    this.cursor.visible = bool;
  }

  setActive(main) {
    this.setMouseOffset(main.mouse);
    this.isActive = true;
    this.pointObjects.forEach(obj => obj.visible = true);
    this.spline.mesh.visible = true;
  }

  setInactive() {
    this.deselectPoint();
    this.showCursor(false);
    this.isActive = false;
    this.pointObjects.forEach(obj => obj.visible = false);
    this.spline.mesh.visible = false;
  }

  select(intersect) {
    if (!intersect) return;

    // obj can be the curve, a spline point, or the shape mesh
    const obj = intersect.object;

    if (obj.type === 'Line') {
      // add a point to the line
      this.addPoint(intersect.point);
    } else if (obj.parent.type === 'Object3D') {
      // select an existing point on line
      this.selectPoint(obj.parent);
    } else {
      this.deselectPoint();
      this.setMouseOffset(intersect.point);
    }
  }

  removePoint() {
    // find point in array
    const i = this.pointObjects.indexOf(this.selectedPoint);
    this.splinePoints.splice(i, 1);
    this.deselectPoint();
    this.updateZone();
  }

  addPoint(position) {
    let closestSplinePoint = 0;
    let prevDistToSplinePoint = -1;
    let minDistance = Number.MAX_VALUE;
    let minPoint = 1;

    // search for point on spline
    for (let t = 0; t < 1; t += 1 / 200.0) {
      const pt = this.spline.getPoint(t);

      const distToSplinePoint = this.splinePoints[closestSplinePoint].distanceToSquared(pt);
      if (distToSplinePoint > prevDistToSplinePoint) {
        closestSplinePoint += 1;

        if (closestSplinePoint >= this.splinePoints.length)
          closestSplinePoint = 0;
      }
      prevDistToSplinePoint = this.splinePoints[closestSplinePoint].distanceToSquared(pt);
      const distToPoint = pt.distanceToSquared(position);
      if (distToPoint < minDistance) {
        minDistance = distToPoint;
        minPoint = closestSplinePoint;
      }
    }

    this.splinePoints.splice(minPoint, 0, position);
    this.updateZone();
    this.selectPoint(this.pointObjects[minPoint]);
  }

  selectPoint(obj) {
    this.deselectPoint();
    this.selectedPoint = obj;
    obj.children[0].material.color.set('blue');
  }

  deselectPoint() {
    if (this.selectedPoint) {
      this.selectedPoint.children[0].material.color.set('red');
      this.selectedPoint = null;
    }
  }
}
<|endoftext|>


<commit_before>import $ from 'jquery';
import lists from '../core/lists';
import dom from '../core/dom';

/**
 * Image popover module
 *  mouse events that show/hide popover will be handled by Handle.js.
 *  Handle.js will receive the events and invoke 'imagePopover.update'.
 */
export default class ImagePopover {
  constructor(context) {
    this.context = context;
    this.ui = $.summernote.ui;

    this.editable = context.layoutInfo.editable[0];
    this.options = context.options;

    this.events = {
      'summernote.disable': () => {
        this.hide();
      }
    };
  }

  shouldInitialize() {
    return !lists.isEmpty(this.options.popover.image);
  }

  initialize() {
    this.$popover = this.ui.popover({
      className: 'note-image-popover'
    }).render().appendTo(this.options.container);
    const $content = this.$popover.find('.popover-content,.note-popover-content');
    this.context.invoke('buttons.build', $content, this.options.popover.image);
  }

  destroy() {
    this.$popover.remove();
  }

  update(target) {
    if (dom.isImg(target)) {
      const pos = dom.posFromPlaceholder(target);
      const posEditor = dom.posFromPlaceholder(this.editable);
      this.$popover.css({
        display: 'block',
        left: this.options.popatmouse ? event.pageX - 20 : pos.left,
        top: this.options.popatmouse ? event.pageY : Math.min(pos.top, posEditor.top)
      });
    } else {
      this.hide();
    }
  }

  hide() {
    this.$popover.hide();
  }
}
<commit_msg>Calculate image selection to cover other layouts and content formats<commit_after>import $ from 'jquery';
import lists from '../core/lists';
import dom from '../core/dom';

/**
 * Image popover module
 *  mouse events that show/hide popover will be handled by Handle.js.
 *  Handle.js will receive the events and invoke 'imagePopover.update'.
 */
export default class ImagePopover {
  constructor(context) {
    this.context = context;
    this.ui = $.summernote.ui;

    this.editable = context.layoutInfo.editable[0];
    this.options = context.options;

    this.events = {
      'summernote.disable': () => {
        this.hide();
      }
    };
  }

  shouldInitialize() {
    return !lists.isEmpty(this.options.popover.image);
  }

  initialize() {
    this.$popover = this.ui.popover({
      className: 'note-image-popover'
    }).render().appendTo(this.options.container);
    const $content = this.$popover.find('.popover-content,.note-popover-content');
    this.context.invoke('buttons.build', $content, this.options.popover.image);
  }

  destroy() {
    this.$popover.remove();
  }

  update(target) {
    if (dom.isImg(target)) {
      const position = $(target).offset();
      const editingOffset = $(this.context.layoutInfo.editingArea).offset();
      const pos = {
        left: position.left - editingOffset.left,
        top: position.top - editingOffset.top
      };
      this.$popover.css({
        display: 'block',
        left: this.options.popatmouse ? event.pageX - 20 : pos.left,
        top: this.options.popatmouse ? event.pageY : pos.top
      });
    } else {
      this.hide();
    }
  }

  hide() {
    this.$popover.hide();
  }
}
<|endoftext|>


<commit_before>
//create the element that's going to act as a shade to the entire page and set its properties
var shade = document.createElement('div');

shade.style['z-index'] = 1000;
shade.style.width = '10000px';
shade.style.height = '10000px';
shade.style['background-color'] = 'white';
shade.style.background = 'white'; //Mozilla doesn't like background-color so we need this as well
shade.style.position = 'fixed';
shade.style.bottom = 0;

//insert the shade at the beginning of the DOM
document.body.insertBefore(shade, document.body.childNodes[0]);

//set the interval for how slow or fast you want the shade to reduce it's height
var inter = setInterval(function(){
    //if the shade is less than 10px just clear the interval and hide the shade
    if(parseFloat(shade.style.height.split('px')[0]) < 10 ){
        shade.style.visibility = 'hidden';
        window.clearInterval(inter);
        alert("That's what life in the slow lane feels like.")
    }
    //reduce the shade to 90% of it's height each interval
    shade.style.height = eval("'" + parseFloat(shade.style.height.split('px')[0]) * .9 + "px'");
},1000);

//once the dom loads set the height of the shade to the actual body height
window.onload = function(){
    shade.style.height = eval("\'"+document.documentElement.scrollHeight+"px\'");
}
<commit_msg>added option for choosing to go through the fast or slow lane. Updated code to avoid the use of eval()<commit_after>    var slow = window.prompt("Slow Lane (OK) or Fast Lane (Cancel)?","Slow Lane");
    if(slow){
        //create the element that's going to act as a shade to the entire page and set its properties
        var shade = document.createElement('div');

        shade.style['z-index'] = 1000;
        shade.style.width = '10000px';
        shade.style.height = '10000px';
        shade.style['background-color'] = 'white';
        shade.style.background = 'white'; //Mozilla doesn't like background-color so we need this as well
        shade.style.position = 'fixed';
        shade.style.bottom = 0;

        //insert the shade at the beginning of the DOM
        document.body.insertBefore(shade, document.body.childNodes[0]);

        //set the interval for how slow or fast you want the shade to reduce it's height
        var inter = setInterval(function(){
            //if the shade is less than 10px just clear the interval and hide the shade
            if(parseFloat(shade.style.height.split('px')[0]) < 10 ){
                shade.style.visibility = 'hidden';
                window.clearInterval(inter);
                alert("That's what life in the slow lane feels like.")
            }
            //reduce the shade to 90% of it's height each interval
            //shade.style.height = eval("'" + parseFloat(shade.style.height.split('px')[0]) * .98 + "px'");
            shade.style.height = parseFloat(shade.style.height.split('px')[0]) * .98 + "px";
        },100);

        //once the dom loads set the height of the shade to the actual body height
        window.onload = function(){
            shade.style.height = document.documentElement.scrollHeight+"px";
        }
    }
<|endoftext|>


<commit_before>
    var orgs = [
        {"name": "bradleyjeck/epanetReader",
         "type": "repo"},
        {"name": "wasdev",
          "type": "org",
          "link": "http://wasdev.github.io/"},
        {"name": "acmeair",
          "type": "org"},
        {"name": "kimchi-project",
          "type": "org"},
        {"name": "OpenSocial",
          "type": "org"},
        {"name": "softlayer",
          "type": "org"},
        {"name": "cloudant",
          "type": "org"},
        {"name": "cloudant-labs",
          "type": "org"},
        {"name": "node-red",
          "type": "org"},
        {"name": "ibmjstart",
          "type": "org"},
        {"name": "ibm-js",
          "type": "org"},
        {"name": "IBMStreams",
          "type": "org"},
        {"name": "ibm-bioinformatics",
          "type":"user"},
        {"name": "ld4apps",
          "type":"org"},
        {"name": "wsadminlib",
          "type": "user"},
        {"name": "apimanagement",
          "type": "org"},
        {"name": "Watson-Explorer",
          "type": "org"},
        {"name": "ot4i/event-filter-pattern",
          "type": "repo"},
        {"name": "ot4i/mqtt-client-connector",
          "type": "repo"},
        {"name": "beloglazov/hamcrest-querydsl",
          "type": "repo"},
        {"name": "beloglazov/couchdb-scala",
          "type": "repo"},
        {"name": "andrewlow/node",
          "type": "repo"},
        {"name": "andrewlow/v8ppc",
          "type": "repo"},
        {"name": "andrewlow/v8z",
          "type": "repo"},
        {"name": "ibm-rtvs",
          "type": "user"},
        {"name": "bigfix",
          "type": "org"},
        {"name": "Open-I-Beam",
          "type": "org"},
        {"name": "fog/fog-softlayer",
          "type": "repo"},
        {"name": "y-omura/TransProg",
          "type": "repo"},
        {"name": "IBM-Bluemix",
          "type": "org"},
        {"name": "watson-developer-cloud",
          "type": "org"},
        {"name": "IBM-Watson",
          "type": "org"},
        {"name": "ibm-research",
          "type": "org"},
        {"name": "nadgowdas/cargo",
           "type": "repo"},
        {"name": "digexp",
          "type": "org"},
        {"name": "andybalaam/git-history-data",
          "type": "repo"},
        {"name": "ibm-cds-labs",
          "type": "org"},
        {"name": "OpenWhisk",
          "type": "org"},
        {"name": "IBM-DBWKL",
          "type": "org"},
        {"name": "apache/incubator-systemml",
          "type": "repo"},
        {"name": "node-red/node-red",
          "type": "repo"},
        {"name": "Brunel-Visualization/Brunel",
          "type": "repo"},
        {"name": "J9Java/panama-layout-prototype",
         "type": "repo" },
        {"name": "xdevops/ibm-containers-emulator",
         "type": "repo"},
        {"name": "ibmalchemy",
         "type": "org"},
        {"name": "jasnell/activitystrea.ms",
         "type": "repo"},
        {"name": "openstack/storlets",
         "type": "repo"},
        {"name": "maximilien/i18n4go",
         "type": "repo"},
        {"name": "ibm-et",
         "type": "org"},
        {"name": "RuntimeTools/appmetrics",
         "type": "repo"},
        {"name": "gaiandb/gaiandb",
         "type": "repo"},
        {"name": "cloudviz/agentless-system-crawler",
        "type": "repo"},
        {"name": "shmul/mule",
         "type": "repo"},
        {"name": "ibmstorage",
         "type": "org"},
        {"name": "djwillia/solo5",
        "type": "repo"},
        {"name": "quarks-edge",
         "type": "org"},
        {"name": "jamiejennings/rosie-pattern-language",
         "type": "repo"},
        {"name": "openblockchain",
         "type": "org"},
        {"name": "aruniyengar/storage-client-library",
         "type": "repo"},
        {"name": "IBM-MIL",
        "type": "org"},
        {"name": "cognitive-catalyst",
        "type": "org"},
        {"name": "ibm-design",
        "type": "org"},
        {"name": "presence-insights",
        "type": "org"},
        {"name": "ibm-bluemix-mobile-services",
         "type": "org"},
        {"name": "ibm-security-innovation",
        "type": "org"},
        {"name": "cicsdev",
        "type": "org"},
        {"name": "strongloop/node-foreman",
         "type": "repo"},
        {"name": "strongloop/strongloop",
          "type": "repo"},
        {"name": "strongloop/strong-task-emitter",
          "type": "repo"},
        {"name": "strongloop/strong-config-loader",
          "type": "repo"},
        {"name": "strongloop/strong-module-loader",
          "type": "repo"},
        {"name": "strongloop/loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-workspace",
          "type": "repo"},
        {"name": "strongloop/strong-mq",
          "type": "repo"},
        {"name": "strongloop/strong-remoting",
          "type": "repo"},
        {"name": "strongloop/loopback-datasource-juggler",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-rest",
          "type": "repo"},
        {"name": "strongloop/loopback-component-push",
          "type": "repo"},
        {"name": "strongloop/loopback-component-storage",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-mongodb",
          "type": "repo"},
        {"name": "strongloop/loopback-oracle-installer",
          "type": "repo"},
        {"name": "strongloop/strong-cluster-control",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-mysql",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-jsonrpc",
          "type": "repo"},
        {"name": "strongloop/loopback-ios-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-android-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-android",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-postgresql",
          "type": "repo"},
        {"name": "strongloop/loopback-component-explorer",
          "type": "repo"},
        {"name": "strongloop/strong-install",
          "type": "repo"},
        {"name": "strongloop/strongloop-buildpacks",
          "type": "repo"},
        {"name": "strongloop/loopback-example-access-control",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-ios",
          "type": "repo"},
        {"name": "strongloop/strong-supervisor",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-angular",
          "type": "repo"},
        {"name": "strongloop/grunt-loopback-sdk-angular",
          "type": "repo"},
        {"name": "strongloop/loopback-example-ssl",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-angular-cli",
          "type": "repo"},
        {"name": "strongloop/strong-oracle",
          "type": "repo"},
        {"name": "strongloop/loopback-example-offline-sync",
          "type": "repo"},
        {"name": "strongloop/loopback-example-database",
          "type": "repo"},
        {"name": "strongloop/strong-registry",
          "type": "repo"},
        {"name": "strongloop/loopback-example-passport",
          "type": "repo"},
        {"name": "strongloop/addr2js",
          "type": "repo"},
        {"name": "strongloop/generator-loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-component-passport",
          "type": "repo"},
        {"name": "strongloop/loopback-connector",
          "type": "repo"},
        {"name": "strongloop/loopback-boot",
          "type": "repo"},
        {"name": "strongloop/strong-build",
          "type": "repo"},
        {"name": "strongloop/strong-agent-statsd",
          "type": "repo"},
        {"name": "strongloop/strong-pm",
          "type": "repo"},
        {"name": "strongloop/strong-log-transformer",
          "type": "repo"},
        {"name": "strongloop/strong-logger",
          "type": "repo"},
        {"name": "strongloop/strong-cached-install",
          "type": "repo"},
        {"name": "strongloop/strong-control-channel",
          "type": "repo"},
        {"name": "strongloop/strong-service-upstart",
          "type": "repo"},
        {"name": "strongloop/strong-service-install",
          "type": "repo"},
        {"name": "strongloop/strong-deploy",
          "type": "repo"},
        {"name": "strongloop/async-tracker",
          "type": "repo"},
        {"name": "strongloop/loopback-swagger",
          "type": "repo"},
        {"name": "strongloop/strong-npm-ls",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-remote",
          "type": "repo"},
        {"name": "strongloop/strong-tools",
          "type": "repo"},
        {"name": "strongloop/strong-wait-till-listening",
          "type": "repo"},
        {"name": "strongloop/strong-statsd",
          "type": "repo"},
        {"name": "strongloop/loopback-phase",
          "type": "repo"},
        {"name": "strongloop/loopback-example-app-logic",
          "type": "repo"},
        {"name": "strongloop/loopback-getting-started-intermediate",
          "type": "repo"},
        {"name": "strongloop/strong-service-systemd",
          "type": "repo"},
        {"name": "strongloop/loopback-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-example-user-management",
          "type": "repo"},
        {"name": "strongloop/loopback-example-middleware",
          "type": "repo"},
        {"name": "strongloop/loopback-example",
          "type": "repo"},
        {"name": "strongloop/loopback-example-angular",
          "type": "repo"},
        {"name": "strongloop/loopback-example-relations",
          "type": "repo"},
        {"name": "strongloop/strong-tunnel",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub",
          "type": "repo"},
        {"name": "strongloop/modern-syslog",
          "type": "repo"},
        {"name": "strongloop/strong-start",
          "type": "repo"},
        {"name": "strongloop/strong-url-defaults",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-mqtt",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-connection-mqtt",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-example",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-bridge",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-redis",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-test",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-primus",
          "type": "repo"},
        {"name": "strongloop/express-example-app",
          "type": "repo"},
        {"name": "strongloop/strong-runner",
          "type": "repo"},
        {"name": "strongloop/strong-spawn-npm",
          "type": "repo"},
        {"name": "strongloop/loopback-example-isomorphic",
          "type": "repo"},
        {"name": "strongloop/strong-docker-build",
          "type": "repo"},
        {"name": "strongloop/loopback-example-pubsub",
          "type": "repo"},
        {"name": "strongloop/cache-http",
          "type": "repo"},
        {"name": "strongloop/loopback-filters",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-sqlite3",
          "type": "repo"},
        {"name": "strongloop/angular-live-set",
          "type": "repo"},
        {"name": "strongloop/strong-deploy-receivers",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-xamarin",
          "type": "repo"},
        {"name": "strongloop/loopback-example-xamarin",
          "type": "repo"},
        {"name": "strongloop/loopback-example-angular-live-set",
          "type": "repo"},
        {"name": "strongloop/loopback-example-mixins",
          "type": "repo"},
        {"name": "strongloop/loopback-acl-route",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-ios-codegen",
          "type": "repo"},
        {"name": "strongloop/eslint-config-strongloop",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-db2",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-cloudant",
          "type": "repo"},
        {"name": "strongloop/loopback-api-definition",
          "type": "repo"},
        {"name": "strongloop/strong-pack",
          "type": "repo"},
        {"name": "strongloop/strong-globalize",
          "type": "repo"},
        {"name": "strongloop/eslint-config-loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-example-connector",
          "type": "repo"},
        {"name": "strongloop/loopback-example-storage",
          "type": "repo"}
    ];
<commit_msg>Update orgs.js<commit_after>
    var orgs = [
        {"name": "bradleyjeck/epanetReader",
         "type": "repo"},
        {"name": "wasdev",
          "type": "org",
          "link": "http://wasdev.github.io/"},
        {"name": "acmeair",
          "type": "org"},
        {"name": "kimchi-project",
          "type": "org"},
        {"name": "OpenSocial",
          "type": "org"},
        {"name": "softlayer",
          "type": "org"},
        {"name": "cloudant",
          "type": "org"},
        {"name": "cloudant-labs",
          "type": "org"},
        {"name": "node-red",
          "type": "org"},
        {"name": "ibmjstart",
          "type": "org"},
        {"name": "ibm-js",
          "type": "org"},
        {"name": "IBMStreams",
          "type": "org"},
        {"name": "ibm-bioinformatics",
          "type":"user"},
        {"name": "ld4apps",
          "type":"org"},
        {"name": "wsadminlib",
          "type": "user"},
        {"name": "apimanagement",
          "type": "org"},
        {"name": "Watson-Explorer",
          "type": "org"},
        {"name": "ot4i/event-filter-pattern",
          "type": "repo"},
        {"name": "ot4i/mqtt-client-connector",
          "type": "repo"},
        {"name": "beloglazov/hamcrest-querydsl",
          "type": "repo"},
        {"name": "beloglazov/couchdb-scala",
          "type": "repo"},
        {"name": "andrewlow/node",
          "type": "repo"},
        {"name": "andrewlow/v8ppc",
          "type": "repo"},
        {"name": "andrewlow/v8z",
          "type": "repo"},
        {"name": "ibm-rtvs",
          "type": "user"},
        {"name": "bigfix",
          "type": "org"},
        {"name": "Open-I-Beam",
          "type": "org"},
        {"name": "fog/fog-softlayer",
          "type": "repo"},
        {"name": "y-omura/TransProg",
          "type": "repo"},
        {"name": "IBM-Bluemix",
          "type": "org"},
        {"name": "watson-developer-cloud",
          "type": "org"},
        {"name": "IBM-Watson",
          "type": "org"},
        {"name": "ibm-research",
          "type": "org"},
        {"name": "nadgowdas/cargo",
           "type": "repo"},
        {"name": "digexp",
          "type": "org"},
        {"name": "andybalaam/git-history-data",
          "type": "repo"},
        {"name": "ibm-cds-labs",
          "type": "org"},
        {"name": "OpenWhisk",
          "type": "org"},
        {"name": "IBM-DBWKL",
          "type": "org"},
        {"name": "apache/incubator-systemml",
          "type": "repo"},
        {"name": "node-red/node-red",
          "type": "repo"},
        {"name": "Brunel-Visualization/Brunel",
          "type": "repo"},
        {"name": "J9Java/panama-layout-prototype",
         "type": "repo" },
        {"name": "xdevops/ibm-containers-emulator",
         "type": "repo"},
        {"name": "ibmalchemy",
         "type": "org"},
        {"name": "jasnell/activitystrea.ms",
         "type": "repo"},
        {"name": "openstack/storlets",
         "type": "repo"},
        {"name": "maximilien/i18n4go",
         "type": "repo"},
        {"name": "ibm-et",
         "type": "org"},
        {"name": "RuntimeTools/appmetrics",
         "type": "repo"},
        {"name": "gaiandb/gaiandb",
         "type": "repo"},
        {"name": "cloudviz/agentless-system-crawler",
        "type": "repo"},
        {"name": "shmul/mule",
         "type": "repo"},
        {"name": "ibmstorage",
         "type": "org"},
        {"name": "djwillia/solo5",
        "type": "repo"},
        {"name": "quarks-edge",
         "type": "org"},
        {"name": "jamiejennings/rosie-pattern-language",
         "type": "repo"},
        {"name": "openblockchain",
         "type": "org"},
        {"name": "aruniyengar/storage-client-library",
         "type": "repo"},
        {"name": "IBM-MIL",
        "type": "org"},
        {"name": "cognitive-catalyst",
        "type": "org"},
        {"name": "ibm-design",
        "type": "org"},
        {"name": "presence-insights",
        "type": "org"},
        {"name": "ibm-bluemix-mobile-services",
         "type": "org"},
        {"name": "ibm-security-innovation",
        "type": "org"},
        {"name": "cicsdev",
        "type": "org"},
        {"name": "strongloop/node-foreman",
         "type": "repo"},
        {"name": "strongloop/strongloop",
          "type": "repo"},
        {"name": "strongloop/strong-task-emitter",
          "type": "repo"},
        {"name": "strongloop/strong-config-loader",
          "type": "repo"},
        {"name": "strongloop/strong-module-loader",
          "type": "repo"},
        {"name": "strongloop/loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-workspace",
          "type": "repo"},
        {"name": "strongloop/strong-mq",
          "type": "repo"},
        {"name": "strongloop/strong-remoting",
          "type": "repo"},
        {"name": "strongloop/loopback-datasource-juggler",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-rest",
          "type": "repo"},
        {"name": "strongloop/loopback-component-push",
          "type": "repo"},
        {"name": "strongloop/loopback-component-storage",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-mongodb",
          "type": "repo"},
        {"name": "strongloop/loopback-oracle-installer",
          "type": "repo"},
        {"name": "strongloop/strong-cluster-control",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-mysql",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-jsonrpc",
          "type": "repo"},
        {"name": "strongloop/loopback-ios-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-android-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-android",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-postgresql",
          "type": "repo"},
        {"name": "strongloop/loopback-component-explorer",
          "type": "repo"},
        {"name": "strongloop/strong-install",
          "type": "repo"},
        {"name": "strongloop/strongloop-buildpacks",
          "type": "repo"},
        {"name": "strongloop/loopback-example-access-control",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-ios",
          "type": "repo"},
        {"name": "strongloop/strong-supervisor",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-angular",
          "type": "repo"},
        {"name": "strongloop/grunt-loopback-sdk-angular",
          "type": "repo"},
        {"name": "strongloop/loopback-example-ssl",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-angular-cli",
          "type": "repo"},
        {"name": "strongloop/strong-oracle",
          "type": "repo"},
        {"name": "strongloop/loopback-example-offline-sync",
          "type": "repo"},
        {"name": "strongloop/loopback-example-database",
          "type": "repo"},
        {"name": "strongloop/strong-registry",
          "type": "repo"},
        {"name": "strongloop/loopback-example-passport",
          "type": "repo"},
        {"name": "strongloop/addr2js",
          "type": "repo"},
        {"name": "strongloop/generator-loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-component-passport",
          "type": "repo"},
        {"name": "strongloop/loopback-connector",
          "type": "repo"},
        {"name": "strongloop/loopback-boot",
          "type": "repo"},
        {"name": "strongloop/strong-build",
          "type": "repo"},
        {"name": "strongloop/strong-agent-statsd",
          "type": "repo"},
        {"name": "strongloop/strong-pm",
          "type": "repo"},
        {"name": "strongloop/strong-log-transformer",
          "type": "repo"},
        {"name": "strongloop/strong-logger",
          "type": "repo"},
        {"name": "strongloop/strong-cached-install",
          "type": "repo"},
        {"name": "strongloop/strong-control-channel",
          "type": "repo"},
        {"name": "strongloop/strong-service-upstart",
          "type": "repo"},
        {"name": "strongloop/strong-service-install",
          "type": "repo"},
        {"name": "strongloop/strong-deploy",
          "type": "repo"},
        {"name": "strongloop/async-tracker",
          "type": "repo"},
        {"name": "strongloop/loopback-swagger",
          "type": "repo"},
        {"name": "strongloop/strong-npm-ls",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-remote",
          "type": "repo"},
        {"name": "strongloop/strong-tools",
          "type": "repo"},
        {"name": "strongloop/strong-wait-till-listening",
          "type": "repo"},
        {"name": "strongloop/strong-statsd",
          "type": "repo"},
        {"name": "strongloop/loopback-phase",
          "type": "repo"},
        {"name": "strongloop/loopback-example-app-logic",
          "type": "repo"},
        {"name": "strongloop/loopback-getting-started-intermediate",
          "type": "repo"},
        {"name": "strongloop/strong-service-systemd",
          "type": "repo"},
        {"name": "strongloop/loopback-getting-started",
          "type": "repo"},
        {"name": "strongloop/loopback-example-user-management",
          "type": "repo"},
        {"name": "strongloop/loopback-example-middleware",
          "type": "repo"},
        {"name": "strongloop/loopback-example",
          "type": "repo"},
        {"name": "strongloop/loopback-example-angular",
          "type": "repo"},
        {"name": "strongloop/loopback-example-relations",
          "type": "repo"},
        {"name": "strongloop/strong-tunnel",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub",
          "type": "repo"},
        {"name": "strongloop/modern-syslog",
          "type": "repo"},
        {"name": "strongloop/strong-start",
          "type": "repo"},
        {"name": "strongloop/strong-url-defaults",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-mqtt",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-connection-mqtt",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-example",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-bridge",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-redis",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-test",
          "type": "repo"},
        {"name": "strongloop/strong-pubsub-primus",
          "type": "repo"},
        {"name": "strongloop/express-example-app",
          "type": "repo"},
        {"name": "strongloop/strong-runner",
          "type": "repo"},
        {"name": "strongloop/strong-spawn-npm",
          "type": "repo"},
        {"name": "strongloop/loopback-example-isomorphic",
          "type": "repo"},
        {"name": "strongloop/strong-docker-build",
          "type": "repo"},
        {"name": "strongloop/loopback-example-pubsub",
          "type": "repo"},
        {"name": "strongloop/cache-http",
          "type": "repo"},
        {"name": "strongloop/loopback-filters",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-sqlite3",
          "type": "repo"},
        {"name": "strongloop/angular-live-set",
          "type": "repo"},
        {"name": "strongloop/strong-deploy-receivers",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-xamarin",
          "type": "repo"},
        {"name": "strongloop/loopback-example-xamarin",
          "type": "repo"},
        {"name": "strongloop/loopback-example-angular-live-set",
          "type": "repo"},
        {"name": "strongloop/loopback-example-mixins",
          "type": "repo"},
        {"name": "strongloop/loopback-acl-route",
          "type": "repo"},
        {"name": "strongloop/loopback-sdk-ios-codegen",
          "type": "repo"},
        {"name": "strongloop/eslint-config-strongloop",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-db2",
          "type": "repo"},
        {"name": "strongloop/loopback-connector-cloudant",
          "type": "repo"},
        {"name": "strongloop/loopback-api-definition",
          "type": "repo"},
        {"name": "strongloop/strong-pack",
          "type": "repo"},
        {"name": "strongloop/strong-globalize",
          "type": "repo"},
        {"name": "strongloop/eslint-config-loopback",
          "type": "repo"},
        {"name": "strongloop/loopback-example-connector",
          "type": "repo"},
        {"name": "strongloop/strong-db-watcher",
          "type": "repo"},
        {"name": "strongloop/ephemeral-npm",
          "type": "repo"},
        {"name": "strongloop/loopback-example-storage",
          "type": "repo"}
    ];
<|endoftext|>


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

import Icon from "./Icon";
import DSLExpression from "../structs/DSLExpression";
import Util from "../utils/Util";

const DEBOUNCE_TIMEOUT = 250;

const METHODS_TO_BIND = [
  "handleBlur",
  "handleChange",
  "handleDebounceUpdate",
  "handleFocus",
  "handleInputClear"
];

/**
 * This is a very simple, low-level input field for DSL expressions, with
 * embedded clear and dropdown buttons.
 *
 * WARNING: This component is stateless, meaning that the hosting component is
 *          responsible for updating the `expression` property on a change event
 *
 * @example
Using the DSLInputField

 *
 * <DSLInputField
 *
 *   dropdownVisible={this.state.dropdownVisible}
 *   onDropdownClick={this.handleDropdownToggle}
 *
 *   expression={this.state.expression}
 *   onChange={this.handleChange}
 *
 *   />
 */
class DSLInputField extends React.Component {
  constructor() {
    super(...arguments);

    this.state = {
      expression: this.props.expression,
      focus: false
    };

    this.debounceTimer = null;

    METHODS_TO_BIND.forEach(method => {
      this[method] = this[method].bind(this);
    });

    this.handleDebounceUpdate = Util.debounce(
      this.handleDebounceUpdate,
      DEBOUNCE_TIMEOUT
    );
  }

  /**
   * Import component property updates.
   *
   * @override
   */
  componentWillReceiveProps(nextProps) {
    const { expression } = nextProps;

    if (expression !== this.state.expression) {
      this.setState({ expression });
    }
  }

  /**
   * Focus to the input field every time the focus state switches to `true`
   *
   * @override
   */
  componentDidUpdate(prevProps, prevState) {
    const { focus } = this.state;

    if (prevState.focus !== focus && focus && this.inputField) {
      this.inputField.focus();
    }
  }

  /**
   * Reset field state to unfocused when the user blurs from the field
   */
  handleBlur() {
    this.setState({
      focus: false
    });
    this.props.onBlur();
  }

  /**
   * Callback with the new text on every keystroke
   *
   * @param {SyntheticEvent} event - The change event
   */
  handleChange(event) {
    this.setState({
      expression: new DSLExpression(event.target.value)
    });

    this.handleDebounceUpdate();
  }

  /**
   * Forward property change update after the debounce timer expired
   */
  handleDebounceUpdate() {
    this.props.onChange(this.state.expression);
  }

  /**
   * Switch to focused state (that triggers .focus to the input field) when
   * the user focuses on the overall component
   */
  handleFocus() {
    this.setState({
      focus: true
    });
    this.props.onFocus();
  }

  /**
   * Callback with empty text  when user clears the input
   */
  handleInputClear() {
    this.props.onChange(new DSLExpression());
  }

  /**
   * Return the "X" button when we have some input
   *
   * @returns {Node|null} The button contents or null if empty
   */
  getClearButton() {
    if (!this.state.expression.defined) {
      return null;
    }

    const { expression } = this.state;
    const { inverseStyle } = this.props;
    let color = "purple";

    if (inverseStyle) {
      color = "white";
    }

    if (expression.hasErrors) {
      color = "red";
    }

    return (

        <Icon
          family="system"
          id="close"
          size="mini"
          className="clickable"
          color={color}
          onClick={this.handleInputClear}
        />

    );
  }

  /**
   * Return the "v" button for showing the filter dropdown
   *
   * @returns {Node|null} The button contents or null if empty
   */
  getDropdownButton() {
    let color = "grey";
    const {
      dropdownVisible,
      hasDropdown,
      inverseStyle,
      onDropdownClick
    } = this.props;

    if (!hasDropdown) {
      return null;
    }

    if (inverseStyle) {
      color = "white";
    }

    if (dropdownVisible) {
      color = "purple";
    }

    return (

        <Icon
          family="system"
          id="funnel"
          size="mini"
          className="clickable"
          color={color}
          onClick={onDropdownClick}
        />

    );
  }

  /**
   * Return input field with it's proper style
   *
   * @returns {Node} The input field
   */
  getInputField() {
    const { expression } = this.state;
    const { inverseStyle, placeholder } = this.props;

    const inputClasses = classNames({
      "form-control filter-input-text": true,
      "form-control-inverse": inverseStyle
    });

    return (
      <input
        className={inputClasses}
        placeholder={placeholder}
        onChange={this.handleChange}
        onFocus={this.handleFocus}
        ref={ref => (this.inputField = ref)}
        type="text"
        value={expression.value}
      />
    );
  }

  render() {
    const { className, inputContainerClass, inverseStyle } = this.props;
    const { expression, focus } = this.state;

    let iconColor = "grey";
    const iconSearchClasses = classNames({
      active: focus
    });

    if (!inverseStyle && (focus || expression.defined)) {
      iconColor = "purple";
    }

    if (expression.hasErrors) {
      iconColor = "red";
    }

    const inputContainerClasses = classNames(
      {
        focus,
        "form-control form-control-group": true,
        "form-control-inverse": inverseStyle
      },
      inputContainerClass
    );

    const formGroupClasses = classNames(
      {
        "form-group": true,
        "form-group-danger": expression.hasErrors
      },
      className
    );

    return (

            <Icon
              family="system"
              id="search"
              size="mini"
              className={iconSearchClasses}
              color={iconColor}
              onClick={this.handleFocus}
            />

          {this.getInputField()}
          {this.getClearButton()}
          {this.getDropdownButton()}

    );
  }
}

DSLInputField.defaultProps = {
  className: {},
  dropdownVisible: false,
  hasDropdown: true,
  inverseStyle: false,
  onChange() {},
  onBlur() {},
  onDropdownClick() {},
  onFocus() {},
  placeholder: "Filter"
};

DSLInputField.propTypes = {
  className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  dropdownVisible: PropTypes.bool,
  hasDropdown: PropTypes.bool,
  inverseStyle: PropTypes.bool,
  onChange: PropTypes.func,
  onBlur: PropTypes.func,
  onDropdownClick: PropTypes.func,
  onFocus: PropTypes.func,
  placeholder: PropTypes.string,
  expression: PropTypes.instanceOf(DSLExpression).isRequired
};

module.exports = DSLInputField;
<commit_msg>fix(DSLInputField): adjust change event handling<commit_after>import classNames from "classnames";
import PropTypes from "prop-types";
import React from "react";

import Icon from "./Icon";
import DSLExpression from "../structs/DSLExpression";

const METHODS_TO_BIND = [
  "handleBlur",
  "handleChange",
  "handleFocus",
  "handleInputClear"
];

/**
 * This is a very simple, low-level input field for DSL expressions, with
 * embedded clear and dropdown buttons.
 *
 * WARNING: This component is stateless, meaning that the hosting component is
 *          responsible for updating the `expression` property on a change event
 *
 * @example
Using the DSLInputField

 *
 * <DSLInputField
 *
 *   dropdownVisible={this.state.dropdownVisible}
 *   onDropdownClick={this.handleDropdownToggle}
 *
 *   expression={this.state.expression}
 *   onChange={this.handleChange}
 *
 *   />
 */
class DSLInputField extends React.Component {
  constructor() {
    super(...arguments);

    this.state = {
      expression: this.props.expression,
      focus: false
    };

    METHODS_TO_BIND.forEach(method => {
      this[method] = this[method].bind(this);
    });
  }

  /**
   * Import component property updates.
   *
   * @override
   */
  componentWillReceiveProps(nextProps) {
    const { expression } = nextProps;

    if (expression !== this.state.expression) {
      this.setState({ expression });
    }
  }

  /**
   * Focus to the input field every time the focus state switches to `true`
   *
   * @override
   */
  componentDidUpdate(prevProps, prevState) {
    const { focus } = this.state;

    if (prevState.focus !== focus && focus && this.inputField) {
      this.inputField.focus();
    }
  }

  /**
   * Reset field state to unfocused when the user blurs from the field
   */
  handleBlur() {
    this.setState({
      focus: false
    });
    this.props.onBlur();
  }

  /**
   * Callback with the new text on every keystroke
   *
   * @param {SyntheticEvent} event - The change event
   */
  handleChange(event) {
    this.setState(
      {
        expression: new DSLExpression(event.target.value)
      },
      () => this.props.onChange(this.state.expression)
    );
  }

  /**
   * Switch to focused state (that triggers .focus to the input field) when
   * the user focuses on the overall component
   */
  handleFocus() {
    this.setState({
      focus: true
    });
    this.props.onFocus();
  }

  /**
   * Callback with empty text  when user clears the input
   */
  handleInputClear() {
    this.props.onChange(new DSLExpression());
  }

  /**
   * Return the "X" button when we have some input
   *
   * @returns {Node|null} The button contents or null if empty
   */
  getClearButton() {
    if (!this.state.expression.defined) {
      return null;
    }

    const { expression } = this.state;
    const { inverseStyle } = this.props;
    let color = "purple";

    if (inverseStyle) {
      color = "white";
    }

    if (expression.hasErrors) {
      color = "red";
    }

    return (

        <Icon
          family="system"
          id="close"
          size="mini"
          className="clickable"
          color={color}
          onClick={this.handleInputClear}
        />

    );
  }

  /**
   * Return the "v" button for showing the filter dropdown
   *
   * @returns {Node|null} The button contents or null if empty
   */
  getDropdownButton() {
    let color = "grey";
    const {
      dropdownVisible,
      hasDropdown,
      inverseStyle,
      onDropdownClick
    } = this.props;

    if (!hasDropdown) {
      return null;
    }

    if (inverseStyle) {
      color = "white";
    }

    if (dropdownVisible) {
      color = "purple";
    }

    return (

        <Icon
          family="system"
          id="funnel"
          size="mini"
          className="clickable"
          color={color}
          onClick={onDropdownClick}
        />

    );
  }

  /**
   * Return input field with it's proper style
   *
   * @returns {Node} The input field
   */
  getInputField() {
    const { expression } = this.state;
    const { inverseStyle, placeholder } = this.props;

    const inputClasses = classNames({
      "form-control filter-input-text": true,
      "form-control-inverse": inverseStyle
    });

    return (
      <input
        className={inputClasses}
        placeholder={placeholder}
        onChange={this.handleChange}
        onFocus={this.handleFocus}
        ref={ref => (this.inputField = ref)}
        type="text"
        value={expression.value}
      />
    );
  }

  render() {
    const { className, inputContainerClass, inverseStyle } = this.props;
    const { expression, focus } = this.state;

    let iconColor = "grey";
    const iconSearchClasses = classNames({
      active: focus
    });

    if (!inverseStyle && (focus || expression.defined)) {
      iconColor = "purple";
    }

    if (expression.hasErrors) {
      iconColor = "red";
    }

    const inputContainerClasses = classNames(
      {
        focus,
        "form-control form-control-group": true,
        "form-control-inverse": inverseStyle
      },
      inputContainerClass
    );

    const formGroupClasses = classNames(
      {
        "form-group": true,
        "form-group-danger": expression.hasErrors
      },
      className
    );

    return (

            <Icon
              family="system"
              id="search"
              size="mini"
              className={iconSearchClasses}
              color={iconColor}
              onClick={this.handleFocus}
            />

          {this.getInputField()}
          {this.getClearButton()}
          {this.getDropdownButton()}

    );
  }
}

DSLInputField.defaultProps = {
  className: {},
  dropdownVisible: false,
  hasDropdown: true,
  inverseStyle: false,
  onChange() {},
  onBlur() {},
  onDropdownClick() {},
  onFocus() {},
  placeholder: "Filter"
};

DSLInputField.propTypes = {
  className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  dropdownVisible: PropTypes.bool,
  hasDropdown: PropTypes.bool,
  inverseStyle: PropTypes.bool,
  onChange: PropTypes.func,
  onBlur: PropTypes.func,
  onDropdownClick: PropTypes.func,
  onFocus: PropTypes.func,
  placeholder: PropTypes.string,
  expression: PropTypes.instanceOf(DSLExpression).isRequired
};

module.exports = DSLInputField;
<|endoftext|>