<commit_before>var Vesponsive = (function(root, undefined) {
  "use strict";
  // Private
  var _this;
  var toArray = Array.prototype.slice;
  var listener = window.addEventListener;

  function init(opts) {
    // Return if on old IE
    if('attachEvent' in window) {
      return false;
    }

    _this = this;
    _this.opts = opts;
    _this.elems = [];
    addListeners();
  };

  function addListeners() {
    // Listen
    listener('DOMContentLoaded', setElems);
    listener('resize', resizeHandler);
  };

  function setElems() {
    var elems = _this.opts.elems;

    elems.forEach(function(elem, i) {
      var node = DOM.getElem(elem.selector);
      var receiverNode = DOM.getElem(elem.receiverSelector);
      if(!node || !receiverNode) {
        return;
      }
      _this.elems.push({
        node:             Array.isArray(node) ? node[0] : node,
        breakPoint:       elem.breakpoint,
        receiver:         Array.isArray(receiverNode) ? receiverNode[0] : receiverNode,
        isMoved:          false,
        origPrevSibling:  elem.previousElementSibling,
        origParent:       elem.parentNode,
        priority:         i,
        DOMmethod:        elem.position,
        additionalClass:  elem.additionalClass
      });
    });
    // Set init positions
    resizeHandler();
  };

  function resizeHandler() {
    var elems = _this.elems;
    var width = window.innerWidth;

    elems.forEach(function(elem, i) {
      if(!elem.node || !elem.receiver) {

        return;
      }

      var breakPoint = parseInt( elem.breakPoint, 10);

      if( !elem.isMoved && width <= breakPoint ) {
        elem.isMoved = true;
        if(elem.additionalClass && elem.additionalClass.length) {
          DOM.addClass(elem.node, elem.additionalClass);
        }
        DOM[elem.DOMmethod](elem.receiver, elem.node);
      } else if( elem.isMoved && width > breakPoint ) {
        elem.isMoved = false;
        if(elem.origPrevSibling) {
          DOM.insertAfter(elem.origPrevSibling, elem.node);
        } else {
          DOM.prependChild(elem.origParent, elem.node);
        }
        if(elem.additionalClass && elem.additionalClass.length) {
          DOM.removeClass(elem.node, elem.additionalClass);
        }
      }
    });
  }

  // Helpers
  var DOM = {
    /*
    * Returns the DOM-node based on selector
    */
    getElem: function(selector) {
      if(~selector.indexOf('#') && !~selector.indexOf('>')) {
        return document.getElementById(selector.substr(1));
      } else {
        return toArray.call(document.querySelectorAll(selector)) || [];
      }
    },

    /*
    * Append newNode into referenceNode
    */
    append: function(referenceNode, newNode) {
      referenceNode.appendChild(newNode);
    },

    /*
    * Perpend newNode into referenceNode
    */
    prepend: function(referenceNode, newNode) {
        referenceNode.insertBefore( newNode, referenceNode.firstChild);
    },

    /*
    * Insert newNode after referenceNode
    */
    after: function(referenceNode, newNode) {
        referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
    },

    /*
    * Insert newNode before referenceNode
    */
    before: function(referenceNode, newNode) {
      referenceNode.parentNode.insertBefore(newNode, referenceNode);
    },

    addClass: function(node, name) {
      if(node.className.indexOf(name) !== -1) {
        return;
      }
      var pre = node.className.length > 0 ? ' ' : '';
      node.className += pre + name;
    },

    removeClass: function(node, name) {
      node.className = node.className.replace(name, '');
    }
  };

  // Public
  return {
    init: init,
    version: '1.0'
  };

})(window);<commit_msg>fix undefined calls<commit_after>var Vesponsive = (function(root, undefined) {
  "use strict";
  // Private
  var _this;
  var toArray = Array.prototype.slice;
  var listener = window.addEventListener;

  function init(opts) {
    // Return if on old IE
    if('attachEvent' in window) {
      return false;
    }

    _this = this;
    _this.opts = opts;
    _this.elems = [];
    addListeners();
  };

  function addListeners() {
    // Listen
    listener('DOMContentLoaded', setElems);
    listener('resize', resizeHandler);
  };

  function setElems() {
    var elems = _this.opts.elems;

    elems.forEach(function(elem, i) {
      var node = DOM.getElem(elem.selector);
      var receiverNode = DOM.getElem(elem.receiverSelector);
      if(!node || !receiverNode) {
        return;
      }

      if (Array.isArray(node)) {
        node = node[0];
      }

      _this.elems.push({
        node:             node,
        breakPoint:       elem.breakpoint,
        receiver:         Array.isArray(receiverNode) ? receiverNode[0] : receiverNode,
        isMoved:          false,
        origPrevSibling:  node.previousElementSibling,
        origParent:       node.parentNode,
        priority:         i,
        DOMmethod:        elem.position,
        additionalClass:  elem.additionalClass
      });
    });
    // Set init positions
    resizeHandler();
  };

  function resizeHandler() {
    var elems = _this.elems;
    var width = window.innerWidth;

    elems.forEach(function(elem, i) {
      if(!elem.node || !elem.receiver) {

        return;
      }

      var breakPoint = parseInt( elem.breakPoint, 10);

      if( !elem.isMoved && width <= breakPoint ) {
        elem.isMoved = true;
        if(elem.additionalClass && elem.additionalClass.length) {
          DOM.addClass(elem.node, elem.additionalClass);
        }
        DOM[elem.DOMmethod](elem.receiver, elem.node);
      } else if( elem.isMoved && width > breakPoint ) {
        elem.isMoved = false;
        if(elem.origPrevSibling) {
          DOM.after(elem.origPrevSibling, elem.node);
        } else {
          DOM.prepend(elem.origParent, elem.node);
        }
        if(elem.additionalClass && elem.additionalClass.length) {
          DOM.removeClass(elem.node, elem.additionalClass);
        }
      }
    });
  }

  // Helpers
  var DOM = {
    /*
    * Returns the DOM-node based on selector
    */
    getElem: function(selector) {
      if(~selector.indexOf('#') && !~selector.indexOf('>')) {
        return document.getElementById(selector.substr(1));
      } else {
        return toArray.call(document.querySelectorAll(selector)) || [];
      }
    },

    /*
    * Append newNode into referenceNode
    */
    append: function(referenceNode, newNode) {
      referenceNode.appendChild(newNode);
    },

    /*
    * Perpend newNode into referenceNode
    */
    prepend: function(referenceNode, newNode) {
        referenceNode.insertBefore( newNode, referenceNode.firstChild);
    },

    /*
    * Insert newNode after referenceNode
    */
    after: function(referenceNode, newNode) {
        referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
    },

    /*
    * Insert newNode before referenceNode
    */
    before: function(referenceNode, newNode) {
      referenceNode.parentNode.insertBefore(newNode, referenceNode);
    },

    addClass: function(node, name) {
      if(node.className.indexOf(name) !== -1) {
        return;
      }
      var pre = node.className.length > 0 ? ' ' : '';
      node.className += pre + name;
    },

    removeClass: function(node, name) {
      node.className = node.className.replace(name, '');
    }
  };

  // Public
  return {
    init: init,
    version: '1.0'
  };

})(window);<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Listingmenu = new keystone.List('Listingmenu', {
	autokey: { from: 'name', path: 'key' }
});

Listingmenu.add({
	softwareProducts:{type:String},
	consulting: {type: String},
	msp: {type: String},
	specialiseAnyalise: {type: String},
	technologyResale: {type: String},
	companyProfile:{type:String},
	mangementTeam:{type:String},
	differentiators:{type:String},
	careers:{type:String},
	contactUs:{type:String},
	partners:{type:String}
});

/**
	Registration
	============
*/
Listingmenu.addPattern('standard meta');
Listingmenu.register();<commit_msg>added files<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Listingmenu = new keystone.List('Listingmenu', {
	autokey: { from: 'name', path: 'key' }
});

Listingmenu.add({
	softwareProducts:{type:String},
	consulting: {type: String},
	datawarehouse:{type:String},
	visualbusiness:{type:String},
	predictivemodeling:{type:String},
	comparativebenchmarking:{type:String},
	geospaticalanalytics:{type:String},
	ecommerceportal:{type:String},
	businessprocessstrategy:{type:String},
	informationreporting:{type:String},
	socialmedia:{type:String},
	msp: {type: String},
	specialiseAnyalise: {type: String},
	technologyResale: {type: String},
	companyProfile:{type:String},
	mangementTeam:{type:String},
	differentiators:{type:String},
	careers:{type:String},
	contactUs:{type:String},
	partners:{type:String}
});

/**
	Registration
	============
*/
Listingmenu.addPattern('standard meta');
Listingmenu.register();<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
/**
 * @module ogs.vgl
 */

/*jslint devel: true, forin: true, newcap: true, plusplus: true*/
/*jslint white: true, continue:true, indent: 2*/

/*global vglModule, gl, ogs, vec4, Float32Array, inherit, $*/
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/**
 * Create a new instance of class mapper
 *
 * @class
 * @returns {vglModule.mapper}
 */
//////////////////////////////////////////////////////////////////////////////
vglModule.mapper = function() {
  'use strict';

  if (!(this instanceof vglModule.mapper)) {
    return new vglModule.mapper();
  }
  vglModule.boundingObject.call(this);

  /** @private */
  var m_dirty = true,
      m_color = [ 0.0, 1.0, 1.0 ],
      m_geomData = null,
      m_buffers = [],
      m_bufferVertexAttributeMap = {},
      m_glCompileTimestamp = vglModule.timestamp();

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Compute bounds of the data
   */
  ////////////////////////////////////////////////////////////////////////////
  this.computeBounds = function() {
    if (m_geomData === null || typeof m_geomData === 'undefined') {
      this.resetBounds();
      return;
    }

    var computeBoundsTimestamp = this.computeBoundsTimestamp(),
        boundsDirtyTimestamp = this.boundsDirtyTimestamp(),
        geomBounds = null;

    if (boundsDirtyTimestamp.getMTime() > computeBoundsTimestamp.getMTime()) {
      geomBounds = m_geomData.bounds();

      this.setBounds(geomBounds[0], geomBounds[1], geomBounds[2],
        geomBounds[3], geomBounds[4], geomBounds[5]) ;

      computeBoundsTimestamp.modified();
    }
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Get solid color of the geometry
   */
  ////////////////////////////////////////////////////////////////////////////
  this.color = function() {
    return m_color;
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Set solid color of the geometry. Default is white [1.0, 1.0, 1.0]
   *
   * @param r Red component of the color [0.0 - 1.0]
   * @param g Green component of the color [0.0 - 1.0]
   * @param b Blue component of the color [0.0 - 1.0]
   */
  ////////////////////////////////////////////////////////////////////////////
  this.setColor = function(r, g, b) {
    m_color[0] = r;
    m_color[1] = g;
    m_color[2] = b;

    this.modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Return stored geometry data if any
   */
  ////////////////////////////////////////////////////////////////////////////
  this.geometryData = function() {
    return m_geomData;
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Connect mapper to its geometry data
   */
  ////////////////////////////////////////////////////////////////////////////
  this.setGeometryData = function(geom) {
    if (m_geomData !== geom) {
      m_geomData = geom;

      this.modified();
      this.boundsDirtyTimestamp().modified();
    }
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Render the mapper
   */
  ////////////////////////////////////////////////////////////////////////////
  this.render = function(renderState) {
    if (this.getMTime() > m_glCompileTimestamp.getMTime()) {
      setupDrawObjects(renderState);
    }

    // Fixed vertex color
    gl.vertexAttrib3fv(vglModule.vertexAttributeKeys.Color, this.color());

    // TODO Use renderState
    var bufferIndex = 0,
        j = 0, i, noOfPrimitives = null, primitive = null;

    for (i in m_bufferVertexAttributeMap) {
      if (m_bufferVertexAttributeMap.hasOwnProperty(i)) {
        gl.bindBuffer(gl.ARRAY_BUFFER, m_buffers[bufferIndex]);
        for (j = 0; j < m_bufferVertexAttributeMap[i].length; ++j) {
          renderState.m_material
              .bindVertexData(renderState, m_bufferVertexAttributeMap[i][j]);
        }
        ++bufferIndex;
      }
    }

    noOfPrimitives = m_geomData.numberOfPrimitives();
    for (j = 0; j < noOfPrimitives; ++j) {
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, m_buffers[bufferIndex++]);
      primitive = m_geomData.primitive(j);//
      gl.drawElements(primitive.primitiveType(), primitive.numberOfIndices(),
                      primitive.indicesValueType(), 0);
    }
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Delete cached VBO if any
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function deleteVertexBufferObjects() {
    var i;
    for (i = 0; i < m_buffers.length; ++i) {
      gl.deleteBuffer(m_buffers[i]);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Create new VBO for all its geometryData sources and primitives
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function createVertexBufferObjects() {
    if (m_geomData) {
      var numberOfSources = m_geomData.numberOfSources(),
          i, j, k, bufferId = null, keys, ks, numberOfPrimitives;

      for (i = 0; i < numberOfSources; ++i) {
        bufferId = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
        gl.bufferData(gl.ARRAY_BUFFER,
          new Float32Array(m_geomData.source(i).data()), gl.STATIC_DRAW);

        keys = m_geomData.source(i).keys();
        ks = [];

        for (j = 0; j < keys.length; ++j) {
          ks.push(keys[j]);
        }

        m_bufferVertexAttributeMap[i] = ks;
        m_buffers[i] = bufferId;
      }

      numberOfPrimitives = m_geomData.numberOfPrimitives();
      for (k = 0; k < numberOfPrimitives; ++k) {
        bufferId = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferId);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, m_geomData.primitive(k)
            .indices(), gl.STATIC_DRAW);
        m_buffers[i++] = bufferId;
      }

      m_glCompileTimestamp.modified();
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Clear cache related to buffers
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function cleanUpDrawObjects() {
    m_bufferVertexAttributeMap = {};
    m_buffers = [];
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Setup draw objects; Delete old ones and create new ones
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function setupDrawObjects() {
    // Delete buffer objects from past if any.
    deleteVertexBufferObjects();

    // Clear any cache related to buffers
    cleanUpDrawObjects();

    // Now construct the new ones.
    createVertexBufferObjects();

    m_dirty = false;
  }

  return this;
};

inherit(vglModule.mapper, vglModule.boundingObject);
<commit_msg>Fixed mapper<commit_after>//////////////////////////////////////////////////////////////////////////////
/**
 * @module ogs.vgl
 */

/*jslint devel: true, forin: true, newcap: true, plusplus: true*/
/*jslint white: true, continue:true, indent: 2*/

/*global vglModule, gl, ogs, vec4, Float32Array, inherit, $*/
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
/**
 * Create a new instance of class mapper
 *
 * @class
 * @returns {vglModule.mapper}
 */
//////////////////////////////////////////////////////////////////////////////
vglModule.mapper = function() {
  'use strict';

  if (!(this instanceof vglModule.mapper)) {
    return new vglModule.mapper();
  }
  vglModule.boundingObject.call(this);

  /** @private */
  var m_dirty = true,
      m_color = [ 0.0, 1.0, 1.0 ],
      m_geomData = null,
      m_buffers = [],
      m_bufferVertexAttributeMap = {},
      m_glCompileTimestamp = vglModule.timestamp();

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Delete cached VBO if any
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function deleteVertexBufferObjects() {
    var i;
    for (i = 0; i < m_buffers.length; ++i) {
      gl.deleteBuffer(m_buffers[i]);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Create new VBO for all its geometryData sources and primitives
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function createVertexBufferObjects() {
    if (m_geomData) {
      var numberOfSources = m_geomData.numberOfSources(),
          i, j, k, bufferId = null, keys, ks, numberOfPrimitives;

      for (i = 0; i < numberOfSources; ++i) {
        bufferId = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
        gl.bufferData(gl.ARRAY_BUFFER,
          new Float32Array(m_geomData.source(i).data()), gl.STATIC_DRAW);

        keys = m_geomData.source(i).keys();
        ks = [];

        for (j = 0; j < keys.length; ++j) {
          ks.push(keys[j]);
        }

        m_bufferVertexAttributeMap[i] = ks;
        m_buffers[i] = bufferId;
      }

      numberOfPrimitives = m_geomData.numberOfPrimitives();
      for (k = 0; k < numberOfPrimitives; ++k) {
        bufferId = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferId);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, m_geomData.primitive(k)
            .indices(), gl.STATIC_DRAW);
        m_buffers[i++] = bufferId;
      }

      m_glCompileTimestamp.modified();
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Clear cache related to buffers
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function cleanUpDrawObjects() {
    m_bufferVertexAttributeMap = {};
    m_buffers = [];
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Setup draw objects; Delete old ones and create new ones
   *
   * @private
   */
  ////////////////////////////////////////////////////////////////////////////
  function setupDrawObjects() {
    // Delete buffer objects from past if any.
    deleteVertexBufferObjects();

    // Clear any cache related to buffers
    cleanUpDrawObjects();

    // Now construct the new ones.
    createVertexBufferObjects();

    m_dirty = false;
  }

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Compute bounds of the data
   */
  ////////////////////////////////////////////////////////////////////////////
  this.computeBounds = function() {
    if (m_geomData === null || typeof m_geomData === 'undefined') {
      this.resetBounds();
      return;
    }

    var computeBoundsTimestamp = this.computeBoundsTimestamp(),
        boundsDirtyTimestamp = this.boundsDirtyTimestamp(),
        geomBounds = null;

    if (boundsDirtyTimestamp.getMTime() > computeBoundsTimestamp.getMTime()) {
      geomBounds = m_geomData.bounds();

      this.setBounds(geomBounds[0], geomBounds[1], geomBounds[2],
        geomBounds[3], geomBounds[4], geomBounds[5]) ;

      computeBoundsTimestamp.modified();
    }
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Get solid color of the geometry
   */
  ////////////////////////////////////////////////////////////////////////////
  this.color = function() {
    return m_color;
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Set solid color of the geometry. Default is white [1.0, 1.0, 1.0]
   *
   * @param r Red component of the color [0.0 - 1.0]
   * @param g Green component of the color [0.0 - 1.0]
   * @param b Blue component of the color [0.0 - 1.0]
   */
  ////////////////////////////////////////////////////////////////////////////
  this.setColor = function(r, g, b) {
    m_color[0] = r;
    m_color[1] = g;
    m_color[2] = b;

    this.modified();
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Return stored geometry data if any
   */
  ////////////////////////////////////////////////////////////////////////////
  this.geometryData = function() {
    return m_geomData;
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Connect mapper to its geometry data
   */
  ////////////////////////////////////////////////////////////////////////////
  this.setGeometryData = function(geom) {
    if (m_geomData !== geom) {
      m_geomData = geom;

      this.modified();
      this.boundsDirtyTimestamp().modified();
    }
  };

  ////////////////////////////////////////////////////////////////////////////
  /**
   * Render the mapper
   */
  ////////////////////////////////////////////////////////////////////////////
  this.render = function(renderState) {
    if (this.getMTime() > m_glCompileTimestamp.getMTime()) {
      setupDrawObjects(renderState);
    }

    // Fixed vertex color
    gl.vertexAttrib3fv(vglModule.vertexAttributeKeys.Color, this.color());

    // TODO Use renderState
    var bufferIndex = 0,
        j = 0, i, noOfPrimitives = null, primitive = null;

    for (i in m_bufferVertexAttributeMap) {
      if (m_bufferVertexAttributeMap.hasOwnProperty(i)) {
        gl.bindBuffer(gl.ARRAY_BUFFER, m_buffers[bufferIndex]);
        for (j = 0; j < m_bufferVertexAttributeMap[i].length; ++j) {
          renderState.m_material
              .bindVertexData(renderState, m_bufferVertexAttributeMap[i][j]);
        }
        ++bufferIndex;
      }
    }

    noOfPrimitives = m_geomData.numberOfPrimitives();
    for (j = 0; j < noOfPrimitives; ++j) {
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, m_buffers[bufferIndex++]);
      primitive = m_geomData.primitive(j);//
      gl.drawElements(primitive.primitiveType(), primitive.numberOfIndices(),
                      primitive.indicesValueType(), 0);
    }
  };

  return this;
};

inherit(vglModule.mapper, vglModule.boundingObject);
<|endoftext|>


<commit_before>const moment               = require('moment');
const Tick                 = require('./tick');
const updatePurchaseStatus = require('./update_values').updatePurchaseStatus;
const ViewPopupUI          = require('../user/view_popup/view_popup.ui');
const BinarySocket         = require('../../base/socket');
const CommonFunctions      = require('../../../_common/common_functions');
const localize             = require('../../../_common/localize').localize;

const TickDisplay = (() => {
    let number_of_ticks,
        display_symbol,
        contract_start_ms,
        contract_category,
        set_barrier,
        barrier,
        abs_barrier,
        display_decimals,
        show_contract_result,
        contract_sentiment,
        price,
        payout,
        ticks_needed,
        x_indicators,
        chart,
        Highcharts,
        applicable_ticks,
        contract_barrier,
        contract_start_moment,
        counter,
        spots_list,
        tick_underlying,
        tick_count,
        tick_longcode,
        tick_display_name,
        tick_date_start,
        absolute_barrier,
        tick_shortcode,
        tick_init,
        subscribe,
        responseID,
        sell_spot_time;

    let id_render = 'tick_chart';

    const initialize = (data, options) => {
        // setting up globals
        number_of_ticks      = parseInt(data.number_of_ticks);
        display_symbol       = data.display_symbol;
        contract_start_ms    = parseInt(data.contract_start) * 1000;
        contract_category    = data.contract_category;
        set_barrier          = !contract_category.match('digits');
        barrier              = data.barrier;
        abs_barrier          = data.abs_barrier;
        display_decimals     = data.display_decimals || 2;
        show_contract_result = data.show_contract_result;
        if (options.id_render) {
            id_render = options.id_render;
        }

        if (data.show_contract_result) {
            contract_sentiment = data.contract_sentiment;
            price              = parseFloat(data.price);
            payout             = parseFloat(data.payout);
        }

        const minimize = data.show_contract_result;
        const end_time = parseInt(data.contract_start) + parseInt((number_of_ticks + 2) * 5);

        setXIndicators();
        CommonFunctions.requireHighstock((Highstock) => {
            Highcharts = Highstock;
            initializeChart({
                minimize,
                plot_from: data.previous_tick_epoch * 1000,
                plot_to  : new Date(end_time * 1000).getTime(),
                width    : data.width ? data.width : undefined,
            }, options);
        });
    };

    const setXIndicators = () => {
        const exit_tick_index = number_of_ticks - 1;
        if (contract_category.match('asian')) {
            ticks_needed = number_of_ticks;
            x_indicators = {
                _0: { label: 'Entry Spot', id: 'start_tick' },
            };
            x_indicators[`_${exit_tick_index}`] = {
                label: 'Exit Spot',
                id   : 'exit_tick',
            };
        } else if (contract_category.match('callput') || contract_category.match('touchnotouch')) {
            ticks_needed = number_of_ticks + 1;
            x_indicators = {
                _0: { label: 'Entry Spot', id: 'entry_tick' },
            };
            x_indicators[`_${number_of_ticks}`] = {
                label: 'Exit Spot',
                id   : 'exit_tick',
            };
        } else if (contract_category.match('digits')) {
            ticks_needed = number_of_ticks;
            x_indicators = {
                _0: { label: 'Tick 1', id: 'start_tick' },
            };
            x_indicators[`_${exit_tick_index}`] = {
                label: `Tick ${number_of_ticks}`,
                id   : 'last_tick',
            };
        } else {
            x_indicators = {};
        }
    };

    const initializeChart = (config, data) => {
        chart = new Highcharts.Chart({
            chart: {
                type           : 'line',
                renderTo       : id_render,
                width          : config.width || (config.minimize ? 394 : null),
                height         : config.minimize ? 143 : null,
                backgroundColor: null,
                events         : { load: plot(config.plot_from, config.plot_to) },
                marginLeft     : 50,
            },
            credits: { enabled: false },
            tooltip: {
                formatter() {
                    const new_y = this.y.toFixed(display_decimals);
                    const mom   = moment.utc(applicable_ticks[this.x].epoch * 1000).format('dddd, MMM D, HH:mm:ss');
                    return `${mom}<br/>${display_symbol} ${new_y}`;
                },
            },
            xAxis: {
                type  : 'linear',
                min   : 0,
                max   : number_of_ticks + 1,
                labels: { enabled: false },
            },
            yAxis: {
                opposite: false,
                labels  : {
                    align: 'left',
                    x    : 0,
                },
                title: '',
            },
            series: [{
                data: [],
            }],
            title    : '',
            exporting: { enabled: false, enableImages: false },
            legend   : { enabled: false },
        });
        Highcharts.setOptions({
            lang: { thousandsSep: ',' },
        });
        if (data) {
            dispatch(data);
        }
    };

    const applyChartBackgroundColor = (tick) => {
        if (!show_contract_result) return;

        const chart_container = $(`#${id_render}`);

        const winning = contract_sentiment === 'up' && tick.quote > contract_barrier
            || contract_sentiment === 'down' && tick.quote < contract_barrier;

        chart_container.css('background-color', winning
            ? 'rgba(46,136,54,0.198039)'
            : 'rgba(204,0,0,0.098039)');
    };

    const addBarrier = () => {
        if (!set_barrier) {
            return;
        }

        const barrier_type = contract_category.match('asian') ? 'asian' : 'static';

        if (barrier_type === 'static') {
            const first_quote = applicable_ticks[0].quote;
            let barrier_quote = first_quote;

            if (barrier) {
                let final_barrier = barrier_quote + parseFloat(barrier);
                // sometimes due to rounding issues, result is 1.009999 while it should
                // be 1.01
                final_barrier = Number(`${Math.round(`${final_barrier}e${display_decimals}`)}e-${display_decimals}`);
                barrier_quote = final_barrier;
            } else if (abs_barrier) {
                barrier_quote = parseFloat(abs_barrier);
            }

            chart.yAxis[0].addPlotLine({
                id    : 'tick-barrier',
                value : barrier_quote,
                label : { text: `Barrier (${barrier_quote})`, align: 'center' },
                color : 'green',
                width : 2,
                zIndex: 2,
            });
            contract_barrier = barrier_quote;
            set_barrier      = false;
        }

        if (barrier_type === 'asian') {
            let total = 0;
            for (let i = 0; i < applicable_ticks.length; i++) {
                total += parseFloat(applicable_ticks[i].quote);
            }
            // round calculated barrier
            const calc_barrier = (total / applicable_ticks.length).toFixed(parseInt(display_decimals) + 1);

            chart.yAxis[0].removePlotLine('tick-barrier');
            chart.yAxis[0].addPlotLine({
                id   : 'tick-barrier',
                value: calc_barrier,
                color: 'green',
                label: {
                    text : `Average (${calc_barrier})`,
                    align: 'center',
                },
                width : 2,
                zIndex: 2,
            });
            contract_barrier = calc_barrier;
        }
        if (contract_barrier) {
            CommonFunctions.elementInnerHtml(CommonFunctions.getElementById('contract_purchase_barrier'), `${localize('Barrier')}: ${contract_barrier}`);
        }
    };

    const add = (indicator) => {
        chart.xAxis[0].addPlotLine({
            value : indicator.index,
            id    : indicator.id,
            label : { text: indicator.label, x: /start_tick|entry_tick/.test(indicator.id) ? -15 : 5 },
            color : '#e98024',
            width : 2,
            zIndex: 2,
            dashStyle: indicator.dashStyle || '',
        });
    };

    const evaluateContractOutcome = () => {
        if (!contract_barrier) {
            return; // can't do anything without barrier
        }

        const exit_tick_index = applicable_ticks.length - 1;
        const exit_spot       = applicable_ticks[exit_tick_index].quote;

        if (contract_sentiment === 'up' && exit_spot > contract_barrier
            || contract_sentiment === 'down' && exit_spot < contract_barrier) {
            win();
        } else {
            lose();
        }
    };

    const win = () => {
        updatePurchaseStatus(payout, price, localize('This contract won'));
    };

    const lose = () => {
        updatePurchaseStatus(0, -price, localize('This contract lost'));
    };

    const plot = () => {
        contract_start_moment = moment(contract_start_ms).utc();
        counter               = 0;
        applicable_ticks      = [];
    };

    const dispatch = (data) => {
        const tick_chart = CommonFunctions.getElementById(id_render);

        if (!CommonFunctions.isVisible(tick_chart) || !data || (!data.tick && !data.history)) {
            return;
        }

        if (subscribe && data.tick && document.getElementById('sell_content_wrapper')) {
            responseID = data.tick.id;
            ViewPopupUI.storeSubscriptionID(responseID);
        }

        let epoches,
            spots2,
            chart_display_decimals;
        if (document.getElementById('sell_content_wrapper')) {
            if (data.tick) {
                Tick.details(data);
                if (!chart_display_decimals) {
                    chart_display_decimals = data.tick.quote.split('.')[1].length || 2;
                }
            } else if (data.history) {
                if (!chart_display_decimals) {
                    chart_display_decimals = data.history.prices[0].split('.')[1].length || 2;
                }
            }
            if (!tick_init) {
                let category = 'callput';
                if (/asian/i.test(tick_shortcode)) {
                    category = 'asian';
                } else if (/digit/i.test(tick_shortcode)) {
                    category = 'digits';
                }
                initialize({
                    symbol              : tick_underlying,
                    number_of_ticks     : tick_count,
                    contract_category   : category,
                    longcode            : tick_longcode,
                    display_symbol      : tick_display_name,
                    contract_start      : tick_date_start,
                    abs_barrier         : absolute_barrier,
                    display_decimals    : chart_display_decimals,
                    show_contract_result: 0,
                }, data);
                spots_list = {};
                tick_init  = 'initialized';
                return;
            }
        }
        if (data.tick) {
            spots2  = Tick.spots();
            epoches = Object.keys(spots2).sort((a, b) => a - b);
        } else if (data.history) {
            epoches = data.history.times;
        }

        const has_finished = applicable_ticks && ticks_needed && applicable_ticks.length >= ticks_needed;
        const has_sold = sell_spot_time
            && applicable_ticks
            && applicable_ticks.find(({ epoch }) => epoch === sell_spot_time) !== undefined;

        if (!has_finished && !has_sold) {
            for (let d = 0; d < epoches.length; d++) {
                let tick;
                if (data.tick) {
                    tick = {
                        epoch: parseInt(epoches[d]),
                        quote: parseFloat(spots2[epoches[d]]),
                    };
                } else if (data.history) {
                    tick = {
                        epoch: parseInt(data.history.times[d]),
                        quote: parseFloat(data.history.prices[d]),
                    };
                }

                if (contract_start_moment && tick.epoch > contract_start_moment.unix() && !spots_list[tick.epoch]) {
                    if (!chart || !chart.series) return;
                    chart.series[0].addPoint([counter, tick.quote], true, false);
                    applicable_ticks.push(tick);
                    spots_list[tick.epoch] = tick.quote;
                    const indicator_key    = `_${counter}`;

                    if (tick.epoch === sell_spot_time && !x_indicators[indicator_key]) {
                        x_indicators[indicator_key] = {
                            index: counter,
                            dashStyle: 'Dash',
                        }
                    }

                    if (typeof x_indicators[indicator_key] !== 'undefined') {
                        x_indicators[indicator_key].index = counter;
                        add(x_indicators[indicator_key]);
                    }

                    addBarrier();
                    applyChartBackgroundColor(tick);
                    counter++;
                }
            }
        }
    };

    const updateChart = (data, contract) => {
        subscribe = 'false';
        if (data.is_sold && applicable_ticks) {
            sell_spot_time = +contract.sell_spot_time;

            const index = applicable_ticks.findIndex(({ epoch }) => epoch === sell_spot_time);
            const indicator_key = `_${index}`;

            if (!x_indicators[indicator_key]) {
                x_indicators[indicator_key] = {
                    index,
                    dashStyle: 'Dash',
                };
                add(x_indicators[indicator_key]);
            }
        } else if (contract) {
            tick_underlying   = contract.underlying;
            tick_count        = contract.tick_count;
            tick_longcode     = contract.longcode;
            tick_display_name = contract.display_name;
            tick_date_start   = contract.date_start;
            absolute_barrier  = contract.barrier;
            tick_shortcode    = contract.shortcode;
            tick_init         = '';
            sell_spot_time    = +contract.sell_spot_time;
            const request     = {
                ticks_history: contract.underlying,
                start        : contract.date_start,
                end          : 'latest',
            };
            if (contract.current_spot_time < contract.date_expiry) {
                request.subscribe = 1;
                subscribe         = 'true';
            } else if (contract.sell_time < contract.date_expiry) {
                request.end = contract.sell_time;
            } else {
                request.end = contract.date_expiry;
            }
            BinarySocket.send(request, { callback: dispatch });
        } else {
            dispatch(data);
        }
    };

    return {
        updateChart,
        init      : initialize,
        resetSpots: () => { spots_list = {}; },
    };
})();

module.exports = TickDisplay;
<commit_msg>fix eslint<commit_after>const moment               = require('moment');
const Tick                 = require('./tick');
const ViewPopupUI          = require('../user/view_popup/view_popup.ui');
const BinarySocket         = require('../../base/socket');
const CommonFunctions      = require('../../../_common/common_functions');
const localize             = require('../../../_common/localize').localize;

const TickDisplay = (() => {
    let number_of_ticks,
        display_symbol,
        contract_start_ms,
        contract_category,
        set_barrier,
        barrier,
        abs_barrier,
        display_decimals,
        show_contract_result,
        contract_sentiment,
        ticks_needed,
        x_indicators,
        chart,
        Highcharts,
        applicable_ticks,
        contract_barrier,
        contract_start_moment,
        counter,
        spots_list,
        tick_underlying,
        tick_count,
        tick_longcode,
        tick_display_name,
        tick_date_start,
        absolute_barrier,
        tick_shortcode,
        tick_init,
        subscribe,
        responseID,
        sell_spot_time;

    let id_render = 'tick_chart';

    const initialize = (data, options) => {
        // setting up globals
        number_of_ticks      = parseInt(data.number_of_ticks);
        display_symbol       = data.display_symbol;
        contract_start_ms    = parseInt(data.contract_start) * 1000;
        contract_category    = data.contract_category;
        set_barrier          = !contract_category.match('digits');
        barrier              = data.barrier;
        abs_barrier          = data.abs_barrier;
        display_decimals     = data.display_decimals || 2;
        show_contract_result = data.show_contract_result;
        if (options.id_render) {
            id_render = options.id_render;
        }

        if (data.show_contract_result) {
            contract_sentiment = data.contract_sentiment;
        }

        const minimize = data.show_contract_result;
        const end_time = parseInt(data.contract_start) + parseInt((number_of_ticks + 2) * 5);

        setXIndicators();
        CommonFunctions.requireHighstock((Highstock) => {
            Highcharts = Highstock;
            initializeChart({
                minimize,
                plot_from: data.previous_tick_epoch * 1000,
                plot_to  : new Date(end_time * 1000).getTime(),
                width    : data.width ? data.width : undefined,
            }, options);
        });
    };

    const setXIndicators = () => {
        const exit_tick_index = number_of_ticks - 1;
        if (contract_category.match('asian')) {
            ticks_needed = number_of_ticks;
            x_indicators = {
                _0: { label: 'Entry Spot', id: 'start_tick' },
            };
            x_indicators[`_${exit_tick_index}`] = {
                label: 'Exit Spot',
                id   : 'exit_tick',
            };
        } else if (contract_category.match('callput') || contract_category.match('touchnotouch')) {
            ticks_needed = number_of_ticks + 1;
            x_indicators = {
                _0: { label: 'Entry Spot', id: 'entry_tick' },
            };
            x_indicators[`_${number_of_ticks}`] = {
                label: 'Exit Spot',
                id   : 'exit_tick',
            };
        } else if (contract_category.match('digits')) {
            ticks_needed = number_of_ticks;
            x_indicators = {
                _0: { label: 'Tick 1', id: 'start_tick' },
            };
            x_indicators[`_${exit_tick_index}`] = {
                label: `Tick ${number_of_ticks}`,
                id   : 'last_tick',
            };
        } else {
            x_indicators = {};
        }
    };

    const initializeChart = (config, data) => {
        chart = new Highcharts.Chart({
            chart: {
                type           : 'line',
                renderTo       : id_render,
                width          : config.width || (config.minimize ? 394 : null),
                height         : config.minimize ? 143 : null,
                backgroundColor: null,
                events         : { load: plot(config.plot_from, config.plot_to) },
                marginLeft     : 50,
            },
            credits: { enabled: false },
            tooltip: {
                formatter() {
                    const new_y = this.y.toFixed(display_decimals);
                    const mom   = moment.utc(applicable_ticks[this.x].epoch * 1000).format('dddd, MMM D, HH:mm:ss');
                    return `${mom}<br/>${display_symbol} ${new_y}`;
                },
            },
            xAxis: {
                type  : 'linear',
                min   : 0,
                max   : number_of_ticks + 1,
                labels: { enabled: false },
            },
            yAxis: {
                opposite: false,
                labels  : {
                    align: 'left',
                    x    : 0,
                },
                title: '',
            },
            series: [{
                data: [],
            }],
            title    : '',
            exporting: { enabled: false, enableImages: false },
            legend   : { enabled: false },
        });
        Highcharts.setOptions({
            lang: { thousandsSep: ',' },
        });
        if (data) {
            dispatch(data);
        }
    };

    const applyChartBackgroundColor = (tick) => {
        if (!show_contract_result) return;

        const chart_container = $(`#${id_render}`);

        const winning = contract_sentiment === 'up' && tick.quote > contract_barrier
            || contract_sentiment === 'down' && tick.quote < contract_barrier;

        chart_container.css('background-color', winning
            ? 'rgba(46,136,54,0.198039)'
            : 'rgba(204,0,0,0.098039)');
    };

    const addBarrier = () => {
        if (!set_barrier) {
            return;
        }

        const barrier_type = contract_category.match('asian') ? 'asian' : 'static';

        if (barrier_type === 'static') {
            const first_quote = applicable_ticks[0].quote;
            let barrier_quote = first_quote;

            if (barrier) {
                let final_barrier = barrier_quote + parseFloat(barrier);
                // sometimes due to rounding issues, result is 1.009999 while it should
                // be 1.01
                final_barrier = Number(`${Math.round(`${final_barrier}e${display_decimals}`)}e-${display_decimals}`);
                barrier_quote = final_barrier;
            } else if (abs_barrier) {
                barrier_quote = parseFloat(abs_barrier);
            }

            chart.yAxis[0].addPlotLine({
                id    : 'tick-barrier',
                value : barrier_quote,
                label : { text: `Barrier (${barrier_quote})`, align: 'center' },
                color : 'green',
                width : 2,
                zIndex: 2,
            });
            contract_barrier = barrier_quote;
            set_barrier      = false;
        }

        if (barrier_type === 'asian') {
            let total = 0;
            for (let i = 0; i < applicable_ticks.length; i++) {
                total += parseFloat(applicable_ticks[i].quote);
            }
            // round calculated barrier
            const calc_barrier = (total / applicable_ticks.length).toFixed(parseInt(display_decimals) + 1);

            chart.yAxis[0].removePlotLine('tick-barrier');
            chart.yAxis[0].addPlotLine({
                id   : 'tick-barrier',
                value: calc_barrier,
                color: 'green',
                label: {
                    text : `Average (${calc_barrier})`,
                    align: 'center',
                },
                width : 2,
                zIndex: 2,
            });
            contract_barrier = calc_barrier;
        }
        if (contract_barrier) {
            CommonFunctions.elementInnerHtml(CommonFunctions.getElementById('contract_purchase_barrier'), `${localize('Barrier')}: ${contract_barrier}`);
        }
    };

    const add = (indicator) => {
        chart.xAxis[0].addPlotLine({
            value    : indicator.index,
            id       : indicator.id,
            label    : { text: indicator.label, x: /start_tick|entry_tick/.test(indicator.id) ? -15 : 5 },
            color    : '#e98024',
            width    : 2,
            zIndex   : 2,
            dashStyle: indicator.dashStyle || '',
        });
    };

    const plot = () => {
        contract_start_moment = moment(contract_start_ms).utc();
        counter               = 0;
        applicable_ticks      = [];
    };

    const dispatch = (data) => {
        const tick_chart = CommonFunctions.getElementById(id_render);

        if (!CommonFunctions.isVisible(tick_chart) || !data || (!data.tick && !data.history)) {
            return;
        }

        if (subscribe && data.tick && document.getElementById('sell_content_wrapper')) {
            responseID = data.tick.id;
            ViewPopupUI.storeSubscriptionID(responseID);
        }

        let epoches,
            spots2,
            chart_display_decimals;
        if (document.getElementById('sell_content_wrapper')) {
            if (data.tick) {
                Tick.details(data);
                if (!chart_display_decimals) {
                    chart_display_decimals = data.tick.quote.split('.')[1].length || 2;
                }
            } else if (data.history) {
                if (!chart_display_decimals) {
                    chart_display_decimals = data.history.prices[0].split('.')[1].length || 2;
                }
            }
            if (!tick_init) {
                let category = 'callput';
                if (/asian/i.test(tick_shortcode)) {
                    category = 'asian';
                } else if (/digit/i.test(tick_shortcode)) {
                    category = 'digits';
                }
                initialize({
                    symbol              : tick_underlying,
                    number_of_ticks     : tick_count,
                    contract_category   : category,
                    longcode            : tick_longcode,
                    display_symbol      : tick_display_name,
                    contract_start      : tick_date_start,
                    abs_barrier         : absolute_barrier,
                    display_decimals    : chart_display_decimals,
                    show_contract_result: 0,
                }, data);
                spots_list = {};
                tick_init  = 'initialized';
                return;
            }
        }
        if (data.tick) {
            spots2  = Tick.spots();
            epoches = Object.keys(spots2).sort((a, b) => a - b);
        } else if (data.history) {
            epoches = data.history.times;
        }

        const has_finished = applicable_ticks && ticks_needed && applicable_ticks.length >= ticks_needed;
        const has_sold = sell_spot_time
            && applicable_ticks
            && applicable_ticks.find(({ epoch }) => epoch === sell_spot_time) !== undefined;

        if (!has_finished && !has_sold) {
            for (let d = 0; d < epoches.length; d++) {
                let tick;
                if (data.tick) {
                    tick = {
                        epoch: parseInt(epoches[d]),
                        quote: parseFloat(spots2[epoches[d]]),
                    };
                } else if (data.history) {
                    tick = {
                        epoch: parseInt(data.history.times[d]),
                        quote: parseFloat(data.history.prices[d]),
                    };
                }

                if (contract_start_moment && tick.epoch > contract_start_moment.unix() && !spots_list[tick.epoch]) {
                    if (!chart || !chart.series) return;
                    chart.series[0].addPoint([counter, tick.quote], true, false);
                    applicable_ticks.push(tick);
                    spots_list[tick.epoch] = tick.quote;
                    const indicator_key    = `_${counter}`;

                    if (tick.epoch === sell_spot_time && !x_indicators[indicator_key]) {
                        x_indicators[indicator_key] = {
                            index    : counter,
                            dashStyle: 'Dash',
                        };
                    }

                    if (typeof x_indicators[indicator_key] !== 'undefined') {
                        x_indicators[indicator_key].index = counter;
                        add(x_indicators[indicator_key]);
                    }

                    addBarrier();
                    applyChartBackgroundColor(tick);
                    counter++;
                }
            }
        }
    };

    const updateChart = (data, contract) => {
        subscribe = 'false';
        if (data.is_sold && applicable_ticks) {
            sell_spot_time = +contract.sell_spot_time;

            const index = applicable_ticks.findIndex(({ epoch }) => epoch === sell_spot_time);
            const indicator_key = `_${index}`;

            if (!x_indicators[indicator_key]) {
                x_indicators[indicator_key] = {
                    index,
                    dashStyle: 'Dash',
                };
                add(x_indicators[indicator_key]);
            }
        } else if (contract) {
            tick_underlying   = contract.underlying;
            tick_count        = contract.tick_count;
            tick_longcode     = contract.longcode;
            tick_display_name = contract.display_name;
            tick_date_start   = contract.date_start;
            absolute_barrier  = contract.barrier;
            tick_shortcode    = contract.shortcode;
            tick_init         = '';
            sell_spot_time    = +contract.sell_spot_time;
            const request     = {
                ticks_history: contract.underlying,
                start        : contract.date_start,
                end          : 'latest',
            };
            if (contract.current_spot_time < contract.date_expiry) {
                request.subscribe = 1;
                subscribe         = 'true';
            } else if (contract.sell_time < contract.date_expiry) {
                request.end = contract.sell_time;
            } else {
                request.end = contract.date_expiry;
            }
            BinarySocket.send(request, { callback: dispatch });
        } else {
            dispatch(data);
        }
    };

    return {
        updateChart,
        init      : initialize,
        resetSpots: () => { spots_list = {}; },
    };
})();

module.exports = TickDisplay;
<|endoftext|>


<commit_before>
import Icon from './Icon';

import React from 'react';
import classNames from 'classnames';

/**
 * Methods to bind in 'this' context
 */
const METHODS_TO_BIND = [
  'getDetailLink',
  'getDetailMessages',
  'getFixedPart',
  'getToggledPart',
  'toggleExpanded'
];

/**
 * An error bar component commonly used in the ServiceForm and the JobsForm
 * that contains collapsible error messages.
 *
 * @example
How to use the CollapsibleErrorMessage

 *   <CollapsibleErrorMessage
 *
 *        className="error-for-modal"
 *
 *        details={[ 'an', 'array', 'of', 'detailed errors' ]}
 *        message="The message to display"
 *
 *        onToggle={function(isToggled) {
 *          // Do something
 *        }}
 *
 *      />
 */
class CollapsibleErrorMessage extends React.Component {

  /**
   * Initialize superclass
   */
  constructor() {
    super(...arguments);

    // Initial state
    this.state = {
      expanded: false
    };

    // Bind methods in context
    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });

  }

  /**
   * Set the default expandedg from the properties
   */
  componentWillMount() {
    this.setState({
      expanded: this.props.expanded
    });
  }

  /**
   * Toggle the expanded state of the collapsible error bar
   */
  toggleExpanded() {
    this.setState({
      expanded: !this.state.expanded
    });

    // Call onToggle callback
    this.props.onToggle(this.state.expanded);
  }

  /**
   * [Custom component] The (show more/less) link
   *
   * @returns {React.Component} - The rendered content
   */
  getDetailLink() {
    let {message, details} = this.props;
    let isDetailed = message && details && details.length;

    // Check if we must not show the detail link at all
    if (!isDetailed) {
      return null;
    }

    // Get text
    let moreLess = 'more';
    if (this.state.expanded) {
      moreLess = 'less';
    }

    // Render
    return (

          (Show {moreLess})

      );

  }

  /**
   * [Custom component] The list of errors in the details
   *
   * @returns {React.Component} - The rendered content
   */
  getDetailMessages() {
    let {details} = this.props;
    return details.map(function (message) {
      let msg = message.toString();
      return (

{msg}

        );
    });
  }

  /**
   * [Custom component] The fixed message part
   *
   * @returns {React.Component} - The rendered content
   */
  getFixedPart() {
    let {message} = this.props;
    let isVisible = !!message;

    // If not visible, just exit
    if (!isVisible) {
      return null;
    }

    // Render the fixed part of the message
    return (

          <Icon
            family="mini"
            id="yield"
            size="mini"
            className="icon-alert icon-margin-right"
            color="red" />
          {message}
          {this.getDetailLink()}

      );
  }

  /**
   * [Custom component] The toggled message part
   *
   * @returns {React.Component} - The rendered content
   */
  getToggledPart() {
    let {message, details} = this.props;
    let isDetailed = !!message && details && details.length;

    // If not expanded or detailed, just exit
    if (!isDetailed || !this.state.expanded) {
      return null;
    }

    // Render the toggled part of the message
    // (Note: The nested div is used to float the contents when needed)
    return (

            {this.getDetailMessages()}

      );

  }

  /**
   * React.js Render Function
   *
   * @returns {React.Component} - The rendered content
   */
  render() {
    let {message} = this.props;
    let isVisible = !!message;

    // If not visible, just exit
    if (!isVisible) {
      return null;
    }

    // Compile classes
    let className = classNames(
      this.props.className,
      'collapsible-error-message',
      {
        'expanded': this.state.expanded
      }
    );

    // Render message component
    return (

          {this.getFixedPart()}
          {this.getToggledPart()}

      );

  };

};

CollapsibleErrorMessage.defaultProps = {
  className: '',
  details: null,
  expanded: false,
  message: '',
  onToggle: function () { }
};

CollapsibleErrorMessage.propTypes = {
  className: React.PropTypes.string,
  details: React.PropTypes.array,
  expanded: React.PropTypes.bool,
  message: React.PropTypes.string,
  onToggle: React.PropTypes.func
};

module.exports = CollapsibleErrorMessage;
<commit_msg>Cleaning-up some unused code parts<commit_after>
import Icon from './Icon';

import React from 'react';
import classNames from 'classnames';

/**
 * Methods to bind in 'this' context
 */
const METHODS_TO_BIND = [
  'toggleExpanded'
];

/**
 * An error bar component commonly used in the ServiceForm and the JobsForm
 * that contains collapsible error messages.
 *
 * @example
How to use the CollapsibleErrorMessage

 *   <CollapsibleErrorMessage
 *
 *        className="error-for-modal"
 *
 *        details={[ 'an', 'array', 'of', 'detailed errors' ]}
 *        message="The message to display"
 *
 *        onToggle={function(isToggled) {
 *          // Do something
 *        }}
 *
 *      />
 */
class CollapsibleErrorMessage extends React.Component {

  /**
   * Initialize superclass
   */
  constructor() {
    super(...arguments);

    // Initial state
    this.state = {
      expanded: false
    };

    // Bind methods in context
    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });

  }

  /**
   * Set the default expandedg from the properties
   */
  componentWillMount() {
    this.setState({
      expanded: this.props.expanded
    });
  }

  /**
   * Toggle the expanded state of the collapsible error bar
   */
  toggleExpanded() {
    this.setState({
      expanded: !this.state.expanded
    });

    // Call onToggle callback
    this.props.onToggle(this.state.expanded);
  }

  /**
   * [Custom component] The (show more/less) link
   *
   * @returns {React.Component} - The rendered content
   */
  getDetailLink() {
    let {message, details} = this.props;
    let isDetailed = message && details && details.length;

    // Check if we must not show the detail link at all
    if (!isDetailed) {
      return null;
    }

    // Get text
    let moreLess = 'more';
    if (this.state.expanded) {
      moreLess = 'less';
    }

    // Render
    return (

          (Show {moreLess})

      );

  }

  /**
   * [Custom component] The list of errors in the details
   *
   * @returns {React.Component} - The rendered content
   */
  getDetailMessages() {
    let {details} = this.props;

    return details.map(function (message) {
      let msg = message.toString();

      return (

{msg}

        );
    });
  }

  /**
   * [Custom component] The fixed message part
   *
   * @returns {React.Component} - The rendered content
   */
  getFixedPart() {
    let {message} = this.props;
    let isVisible = !!message;

    // If not visible, just exit
    if (!isVisible) {
      return null;
    }

    // Render the fixed part of the message
    return (

          <Icon
            family="mini"
            id="yield"
            size="mini"
            className="icon-alert icon-margin-right"
            color="red" />
          {message}
          {this.getDetailLink()}

      );
  }

  /**
   * [Custom component] The toggled message part
   *
   * @returns {React.Component} - The rendered content
   */
  getToggledPart() {
    let {message, details} = this.props;
    let isDetailed = !!message && details && details.length;

    // If not expanded or detailed, just exit
    if (!isDetailed || !this.state.expanded) {
      return null;
    }

    // Render the toggled part of the message
    // (Note: The nested div is used to float the contents when needed)
    return (

            {this.getDetailMessages()}

      );

  }

  /**
   * React.js Render Function
   *
   * @returns {React.Component} - The rendered content
   */
  render() {
    let {message} = this.props;
    let isVisible = !!message;

    // If not visible, just exit
    if (!isVisible) {
      return null;
    }

    // Compile classes
    let className = classNames(
      this.props.className,
      'collapsible-error-message',
      {
        'expanded': this.state.expanded
      }
    );

    // Render message component
    return (

          {this.getFixedPart()}
          {this.getToggledPart()}

      );

  };

};

CollapsibleErrorMessage.defaultProps = {
  className: '',
  details: null,
  expanded: false,
  message: '',
  onToggle: function () { }
};

CollapsibleErrorMessage.propTypes = {
  className: React.PropTypes.string,
  details: React.PropTypes.array,
  expanded: React.PropTypes.bool,
  message: React.PropTypes.string,
  onToggle: React.PropTypes.func
};

module.exports = CollapsibleErrorMessage;
<|endoftext|>


<commit_before>"use strict";

exports.BattleScripts = {
	randomSeasonalMeleeTeam: function (side) {
		let team = [];
		let variant = (this.random(2) === 1);
		let sets = {
			'charizard8888': {
				species: 'Charizard-Mega-X', ability: 'Refrigerate', item: 'Charizardite X', gender: 'M',
				moves: ['fakeout', 'extremespeed', 'earthquake'],
				signatureMove: "ggm8",
				evs: {spd:4, atk:252, spe:252}, nature: 'Jolly',
			},
			'Paul☯71': {
				species: 'Palkia', ability: 'discover me', item: 'Leftovers', gender: 'M',
				moves: ['hyperbeam', 'outrage', 'waterspout'],
				signatureMove: "Kick My Ass",
				evs: {spd:4, atk:252, spe:252}, nature: 'Adamant',
			},
			'ClassyZ': {
				species: 'Scizor-Mega', ability: 'Technician', item: 'Scizorite', gender: 'F', shiny: true,
				moves: ['machpunch', 'bulletpunch', 'swordsdance'],
				signatureMove: 'Hyperspeed Punch',
				evs: {atk:252, spd:4, hp:252}, nature: 'Adamant',
			},
			'PI EddyChomp': {
				species: 'Garchomp-Mega', ability: 'Epic Claws', item: 'Leftovers',
				moves: ['precipiceblades', 'dragonclaw', 'sacredfire'],
				signatureMove: "evalchomp",
				evs: {atk:252, def:4, spe:252}, nature: 'Adamant',
			},
			'Digital Edge': {
				species: 'Jirachi', ability: 'Serene Grace', item: 'Choice Scarf',
				moves: ['iciclecrash', 'ironhead', 'uturn'],
				signatureMove: "Sacred Hax",
				evs: {atk:252, spd:4, spe:252}, nature: 'Adamant',
			},
			'Ransei': {
				species: 'Rayquaza', ability: 'Wonder Breaker', item: 'Life Orb', gender: ['M'],shiny:true,
				moves: ['dragonpulse', 'tailglow', 'dracometeor'],
				signatureMove: "Legend's Ambition",
				evs: {hp:248, atk:252, spa:252, spe:252}, nature: 'Mild',
			},
			'Flygonerz': {
				species: 'Flygon', ability: 'Magic Claws', item: 'Focus Sash', gender: ['F'],shiny:true,
				moves: ['dragonrush', 'thousandarrows', 'gunkshot'],
				signatureMove: "Dragon Shift",
				evs: {hp:4, atk:252, spe:252}, nature: 'Adamant',
			},
			'Spandan': {
			    species: 'Salamence', ability: 'Multiscale', item: 'Salamencite', gender: 'M',
				moves: ['extremespeed', 'shiftgear', 'boomburst'],
				signatureMove: "Yo MaMMa Joke",
				evs: {hp: 252, atk:252, def:252, spa:252, spd:252, spe:252}, nature: 'Naive',
			},
			'SnakeXZero5': {
			    species: 'Sneasel', ability: 'Knowledge', item: 'Liechi Berry', gender: 'M',
				moves: ['icepunch', 'knockoff', 'fakeout'],
				signatureMove: "Logic Power",
				evs: {atk:252, spd:6, spe:252}, nature: 'Adamant',
			},
			'Theswordbreaker': {
			    species: 'Arceus-Dragon', ability: 'Breaking Point', item: 'Draco Plate', gender: 'M',
				moves: ['spacialrend', 'focusblast', 'blizzard'],
				signatureMove: "Wait and hope",
				evs: {spa:252, spd:4, spe:252}, nature: 'Modest',
			},
			'The God of Haxorus': {
				species: 'Haxorus', ability: 'Blessed Hax', item: 'Life Orb', gender: 'M',
				moves: ['ironhead', 'diamondstorm', 'sacredfire'],
				signatureMove: "Haxing Rage",
				evs: {atk:252, spe:252, spd:4}, nature: 'Adamant',
			},
			'XpRienzo ☑-☑': {
 				species: 'Reshiram', ability: 'Adaptability', item: 'Charcoal', gender: 'M',
 				moves: ['fusionflare', 'spacialrend', 'voltswitch'],
 				signatureMove: "blehflame",
 				evs: {spa:254, spd:4, spe:252}, nature: 'Timid',
 			},
		};

		// Generate the team randomly.
		let pool = Object.keys(sets);
		for (let i = 0; i < 6; i++) {
			let name = this.sampleNoReplace(pool);
			let set = sets[name];
			set.level = 100;
			set.name = name;
			if (!set.ivs) {
				set.ivs = {hp:31, atk:31, def:31, spa:31, spd:31, spe:31};
			} else {
				for (let iv in {hp:31, atk:31, def:31, spa:31, spd:31, spe:31}) {
					set.ivs[iv] = iv in set.ivs ? set.ivs[iv] : 31;
				}
			}
			// Assuming the hardcoded set evs are all legal.
			if (!set.evs) set.evs = {hp:84, atk:84, def:84, spa:84, spd:84, spe:84};
			set.moves = [this.sampleNoReplace(set.moves), this.sampleNoReplace(set.moves), this.sampleNoReplace(set.moves)].concat(set.signatureMove);
			team.push(set);
		}

		return team;
	},
};
<commit_msg>Update charizard8888's set<commit_after>"use strict";

exports.BattleScripts = {
	randomSeasonalMeleeTeam: function (side) {
		let team = [];
		let variant = (this.random(2) === 1);
		let sets = {
			'charizard8888': {
				species: 'Charizard-Mega-X', ability: 'Refrigerate', item: 'Charizardite X', gender: 'M',
				moves: ['fakeout', 'extremespeed', 'flareblitz'],
				signatureMove: "ggm8",
				evs: {spd:4, atk:252, spe:252}, nature: 'Jolly',
			},
			'Paul☯71': {
				species: 'Palkia', ability: 'discover me', item: 'Leftovers', gender: 'M',
				moves: ['hyperbeam', 'outrage', 'waterspout'],
				signatureMove: "Kick My Ass",
				evs: {spd:4, atk:252, spe:252}, nature: 'Adamant',
			},
			'ClassyZ': {
				species: 'Scizor-Mega', ability: 'Technician', item: 'Scizorite', gender: 'F', shiny: true,
				moves: ['machpunch', 'bulletpunch', 'swordsdance'],
				signatureMove: 'Hyperspeed Punch',
				evs: {atk:252, spd:4, hp:252}, nature: 'Adamant',
			},
			'PI EddyChomp': {
				species: 'Garchomp-Mega', ability: 'Epic Claws', item: 'Leftovers',
				moves: ['precipiceblades', 'dragonclaw', 'sacredfire'],
				signatureMove: "evalchomp",
				evs: {atk:252, def:4, spe:252}, nature: 'Adamant',
			},
			'Digital Edge': {
				species: 'Jirachi', ability: 'Serene Grace', item: 'Choice Scarf',
				moves: ['iciclecrash', 'ironhead', 'uturn'],
				signatureMove: "Sacred Hax",
				evs: {atk:252, spd:4, spe:252}, nature: 'Adamant',
			},
			'Ransei': {
				species: 'Rayquaza', ability: 'Wonder Breaker', item: 'Life Orb', gender: ['M'],shiny:true,
				moves: ['dragonpulse', 'tailglow', 'dracometeor'],
				signatureMove: "Legend's Ambition",
				evs: {hp:248, atk:252, spa:252, spe:252}, nature: 'Mild',
			},
			'Flygonerz': {
				species: 'Flygon', ability: 'Magic Claws', item: 'Focus Sash', gender: ['F'],shiny:true,
				moves: ['dragonrush', 'thousandarrows', 'gunkshot'],
				signatureMove: "Dragon Shift",
				evs: {hp:4, atk:252, spe:252}, nature: 'Adamant',
			},
			'Spandan': {
			    species: 'Salamence', ability: 'Multiscale', item: 'Salamencite', gender: 'M',
				moves: ['extremespeed', 'shiftgear', 'boomburst'],
				signatureMove: "Yo MaMMa Joke",
				evs: {hp: 252, atk:252, def:252, spa:252, spd:252, spe:252}, nature: 'Naive',
			},
			'SnakeXZero5': {
			    species: 'Sneasel', ability: 'Knowledge', item: 'Liechi Berry', gender: 'M',
				moves: ['icepunch', 'knockoff', 'fakeout'],
				signatureMove: "Logic Power",
				evs: {atk:252, spd:6, spe:252}, nature: 'Adamant',
			},
			'Theswordbreaker': {
			    species: 'Arceus-Dragon', ability: 'Breaking Point', item: 'Draco Plate', gender: 'M',
				moves: ['spacialrend', 'focusblast', 'blizzard'],
				signatureMove: "Wait and hope",
				evs: {spa:252, spd:4, spe:252}, nature: 'Modest',
			},
			'The God of Haxorus': {
				species: 'Haxorus', ability: 'Blessed Hax', item: 'Life Orb', gender: 'M',
				moves: ['ironhead', 'diamondstorm', 'sacredfire'],
				signatureMove: "Haxing Rage",
				evs: {atk:252, spe:252, spd:4}, nature: 'Adamant',
			},
			'XpRienzo ☑-☑': {
 				species: 'Reshiram', ability: 'Adaptability', item: 'Charcoal', gender: 'M',
 				moves: ['fusionflare', 'spacialrend', 'voltswitch'],
 				signatureMove: "blehflame",
 				evs: {spa:254, spd:4, spe:252}, nature: 'Timid',
 			},
		};

		// Generate the team randomly.
		let pool = Object.keys(sets);
		for (let i = 0; i < 6; i++) {
			let name = this.sampleNoReplace(pool);
			let set = sets[name];
			set.level = 100;
			set.name = name;
			if (!set.ivs) {
				set.ivs = {hp:31, atk:31, def:31, spa:31, spd:31, spe:31};
			} else {
				for (let iv in {hp:31, atk:31, def:31, spa:31, spd:31, spe:31}) {
					set.ivs[iv] = iv in set.ivs ? set.ivs[iv] : 31;
				}
			}
			// Assuming the hardcoded set evs are all legal.
			if (!set.evs) set.evs = {hp:84, atk:84, def:84, spa:84, spd:84, spe:84};
			set.moves = [this.sampleNoReplace(set.moves), this.sampleNoReplace(set.moves), this.sampleNoReplace(set.moves)].concat(set.signatureMove);
			team.push(set);
		}

		return team;
	},
};
<|endoftext|>


<commit_before>var _ = require('lodash')
var http = require('http')
var args = require('optimist').argv
var httpProxy = require('http-proxy')
var cOS = require('commonos')
var arkUtil = require('arkutil')

var userHome = cOS.getUserHome()
console.log('home directory:', userHome)

var config = require('./config/default.js')

var testConfig = {}
if (process.env.mode && process.env.mode == 'test')
	testConfig = require('./config/test.js')

var userConfig = {}
var userConfigPath = userHome + 'config/proxy.js'
try {
	userConfig = require(userConfigPath)
} catch (err) {
	console.log('\n\n\nERROR: could not find user config:', userConfigPath)
}

delete args._
delete args.$0
config = _.merge(config, testConfig, userConfig, args)
console.log('Config:')
console.log(config)

// var port
// var servers = _.map(_.range(config.serverCount), function(i)
// {
// 	port = config.startingPort + i + 1
// 	return config.baseUrl + ':' + port
// })
var headerRegex = new RegExp(/[^A-Za-z0-9_\(\)<>\@\,\;\:\\\/\[\]\?\=\{\}]/g)
var servers = []

// console.log('Proxy URLs:', servers)

var proxy = httpProxy.createProxyServer()

var currentServer = 0
function loadBalanceProxy(request, response)
{
	if (!servers.length)
	{
		var err = 'Error: No servers online!'
		console.log(err)
		response.writeHead(500, {'Content-Type': 'text/html'})
		response.write(err)
		response.end()
		return
	}
	var index = currentServer % servers.length
	currentServer += 1
	var target = servers[index]
	proxy.web(request, response,
	{
		target: target
	}, function(err)
	{
		if (err)
			console.log('\n\nError:', err)
		loadBalanceProxy(request, response)
	})
}

var server = http.createServer(function(request, response)
{
	_.each(request.headers, function(val, key)
	{
		request.headers[key] = val.replace(headerRegex, '')
	})
	console.log('request.url:', request.url)

	if (request.url == '/_proxy/addServer' && request.method == 'POST')
	{
		console.log('\nAdding server')
		var body = ''

		request.on('data', function (data) {
			body += data

			// Too much POST data, kill the connection!
			// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
			if (body.length > 1e6)
				request.connection.destroy()
		})

		request.on('end', function ()
		{
			var data = arkUtil.parseJSON(body)
			var err
			if (!data ||
				!_.isObject(data) ||
				!data.url ||
				!data.secret)
			{
				err = 'Invalid request, need url and secret'
				console.log(err)
				response.writeHead(500, {'Content-Type': 'text/html'})
				response.write(err)
				response.end()
				return
			}
			if (data.secret != config.secret)
			{
				err = 'Incorrect proxy secret'
				console.log(err)
				response.writeHead(500, {'Content-Type': 'text/html'})
				response.write(err)
				response.end()
				return
			}

			var responseData = {registered: 1}

			response.writeHead(200, {'Content-Type': 'application/json'})
			response.write(JSON.stringify(responseData))
			response.end()

			console.log(data.url)
			servers.push(data.url)
			return
		})
	}
	else if (request.url == '/_proxy/status')
	{
		var data = {'tacos': true}
		response.writeHead(200, {'Content-Type': 'application/json'})
		response.write(JSON.stringify(data))
		response.end()
	}
	else
	{
		loadBalanceProxy(request, response)
	}
})

server.listen(config.port)

console.log('Proxy listening on port ' + config.port)
<commit_msg>solid pass at proxy<commit_after>var _ = require('lodash')
var http = require('http')
var args = require('optimist').argv
var httpProxy = require('http-proxy')
var cOS = require('commonos')
var arkUtil = require('arkutil')

var userHome = cOS.getUserHome()
console.log('home directory:', userHome)

var config = require('./config/default.js')

var testConfig = {}
if (process.env.mode && process.env.mode == 'test')
	testConfig = require('./config/test.js')

var userConfig = {}
var userConfigPath = userHome + 'config/proxy.js'
try {
	userConfig = require(userConfigPath)
} catch (err) {
	console.log('\n\n\nERROR: could not find user config:', userConfigPath)
}

delete args._
delete args.$0
config = _.merge(config, testConfig, userConfig, args)
// console.log('Config:')
// console.log(config)

var headerRegex = new RegExp(/[^A-Za-z0-9_\(\)<>\@\,\;\:\\\/\[\]\?\=\{\}]/g)
var servers = []

var proxy = httpProxy.createProxyServer()

var currentServer = 0

function loadBalanceProxy(request, response)
{
	// if we have no servers
	// or we've tried more times than we have servers
	if (!servers.length || request._coren_proxyTries >= servers.length)
	{
		var err = 'Error: No servers online!'
		console.log(err)
		response.writeHead(500, {'Content-Type': 'text/html'})
		response.write(err)
		response.end()
		return
	}

	request._coren_proxyTries += 1
	var index = currentServer % servers.length
	currentServer += 1
	var target = servers[index]
	if (!target.online)
	{
		console.log('server not online:', target.url)
		return loadBalanceProxy(request, response)
	}
	proxy.web(request, response,
	{
		target: target.url
	}, function(err)
	{
		if (err)
			console.log('\n\nError:', err)

		// remove the server from the list
		// servers.splice(index,1)
		// currentServer -= 1
		// set online = false
		servers[index].online = false
		servers[index].lastError = err
		loadBalanceProxy(request, response)
	})
}

var server = http.createServer(function(request, response)
{
	_.each(request.headers, function(val, key)
	{
		request.headers[key] = val.replace(headerRegex, '')
	})

	// register proxy
	if (request.url == '/_proxy/addServer' && request.method == 'POST')
	{
		var body = ''

		request.on('data', function (data) {
			body += data

			// Too much POST data, kill the connection!
			// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
			if (body.length > 1e6)
				request.connection.destroy()
		})

		request.on('end', function ()
		{
			var data = arkUtil.parseJSON(body)
			var err
			if (!data ||
				!_.isObject(data) ||
				!data.url ||
				!data.secret)
			{
				err = 'Invalid request, need url and secret'
				console.log(err)
				response.writeHead(500, {'Content-Type': 'text/html'})
				response.write(err)
				response.end()
				return
			}
			if (data.secret != config.secret)
			{
				err = 'Incorrect proxy secret'
				console.log(err)
				response.writeHead(500, {'Content-Type': 'text/html'})
				response.write(err)
				response.end()
				return
			}
			var index = -1
			_.each(servers, function(info, i)
			{
				if (info.url == data.url)
					index = i
			})

			var responseData = {registered: 1}
			response.writeHead(200, {'Content-Type': 'application/json'})
			response.write(JSON.stringify(responseData))
			response.end()

			// if we're re-registering a server
			// just set it back to online
			if (index != -1)
			{
				console.log('\nUpdating server:', data.url)
				servers[index].online = true
			}
			// otherwise add the new server
			else
			{
				console.log('\nAdding server:', data.url)
				servers.push({
					url: data.url,
					online: true,
					lastError: null,
				})
			}
			return
		})
	}
	// proxy status
	else if (request.url == '/_proxy/status')
	{
		response.writeHead(200, {'Content-Type': 'application/json'})
		response.write(JSON.stringify(servers))
		response.end()
	}
	// proxy
	else
	{
		console.log('request.url:', request.url)
		request._coren_proxyTries = 0
		loadBalanceProxy(request, response)
	}
})

server.listen(config.port)

console.log('Proxy listening on port ' + config.port)
<|endoftext|>


<commit_before>// openSeadragonApp: Defines the Angular application ==================================================================================================================================
var openSeadragonApp = angular.module('openSeadragonApp', ['ERMrest']);

// ERMrestService: A service for operations that deal with the ERMrest db =============================================================================================================
openSeadragonApp.service('ERMrestService', ['ermrestClientFactory', '$http', function(ermrestClientFactory, $http) {
    var client = ermrestClientFactory.getClient(window.location.origin + '/ermrest', null);
    var catalog = client.getCatalog(1);

    // Get a reference to the ERMrestService service
    var self = this;

    // Parse Chaise url to determine required parameters to find the requested entity
    this.path = window.location.hash;
    this.params = this.path.split('/');
    this.catalogId = this.params[0].substring(1);
    this.schemaName = this.params[1].split(':')[0];
    this.tableName = this.params[1].split(':')[1];
    this.entityId = this.params[2].split('=')[1];

    var ERMREST_ENDPOINT = window.location.origin + '/ermrest/catalog/';
    if (chaiseConfig['ermrestLocation'] != null) {
        ERMREST_ENDPOINT = chaiseConfig['ermrestLocation'] + '/ermrest/catalog';
    }

    // Returns a Schema object from ERMrest
    this.getSchema = function getSchema() {
        return catalog.introspect().then(function(schemas) {
            return schemas[self.schemaName];
        });
    };

    // Returns the uri value from a row in rbk:image (filtered by the id found in URL)
    this.getEntity = function getEntity() {
        return this.getSchema().then(function(schema) {
            var table = schema.getTable(self.tableName);
            var filteredTable = table.getFilteredTable(["id=" + self.entityId]);
            return filteredTable.getRows().then(function(rows) {
                return rows[0].data.uri;
            });
        });
    };

    this.insertRoi = function insertRoi(x, y, width, height, context) {
        var timestamp = new Date().toISOString();
        var coordinates = [x, y, width, height];
        var roi = [{
            "id": null,
            "image_id": parseInt(this.entityId),
            "author": null,
            "timestamp": timestamp,
            "coords": coordinates,
            "context_uri": context,
            "anatomy": null
        }];
        var entityPath = ERMREST_ENDPOINT + this.catalogId + '/entity/' + this.schemaName + ':roi?defaults=id,author';
        return $http.post(entityPath, roi);
    };

    this.insertRoiComment = function insertRoiComment(roiId, comment) {
        var timestamp = new Date().toISOString();
        var roiComment = [{
            "id": null,
            "roi_id": roiId,
            "author": null,
            "timestamp": timestamp,
            "comment": comment
        }];

        var entityPath = ERMREST_ENDPOINT + this.catalogId + '/entity/' + this.schemaName + ':roi_comment?defaults=id,author';
        return $http.post(entityPath, roiComment);
    };
    // TODO: Rewrite this with ermrestjs
    this.createAnnotation = function createAnnotation(x, y, width, height, context, comment, successCallback) {
        var newAnnotation = {};
        // First create a row in rbk:roi...
        this.insertRoi(x, y, width, height, context).then(function(response) {
            if (response.data) {
                newAnnotation = response.data[0];
                return response.data[0];
            } else {
                return 'Error: Region of interest could not be created. ' + response.status + ' ' + response.statusText;
            }
        // Then create a row in roi_comment, filling in the roi_id column with the result of insertRoi()
        }).then(function(data) {
            var roiId = data.id;
            self.insertRoiComment(roiId, comment).then(function(response) {
                if (response.data) {
                    var commentData = response.data[0];
                    newAnnotation.comments = {id: commentData.id, roiId: commentData.roi_id, author: commentData.author, comment: commentData.comment, timestamp: commentData.timestamp};
                    return response.data[0];
                } else {
                    return 'Error: Comment could not be created. ' + response.status + ' ' + response.statusText;
                }
            });
            successCallback(newAnnotation);
        });
    };

    this.getAnnotations = function getAnnotations() {
        var annotations = [];
        this.getSchema().then(function(schema) {
            var roiTable = schema.getTable('roi');
            var filteredRoiTable = roiTable.getFilteredTable(["image_id=" + self.entityId]);
            return filteredRoiTable.getRows().then(function(roiRows) {
                if (roiRows.length > 0) {
                    return Promise.all(roiRows.map(function(roi) {
                        return roi.getRelatedTable(self.schemaName, 'roi_comment').getRows().then(function(commentRows) {
                            return Promise.all(commentRows.map(function(comment) {
                                roi.data.comments = {id: comment.data.id, roiId: comment.data.roi_id, author: comment.data.author, comment: comment.data.comment, timestamp: comment.data.timestamp};
                                annotations.push(roi.data);
                            }));
                        });
                    }));
                } else {
                    console.log('No annotations found for this image.')
                }
            });
        });
        return annotations;
    };
}]);

// MainController: An Angular controller to update the view ===========================================================================================================================
openSeadragonApp.controller('MainController', ['$scope', 'ERMrestService', function($scope, ERMrestService) {
    $scope.annotations = ERMrestService.getAnnotations();
    $scope.viewer = null;
    $scope.viewerReady = false;
    $scope.viewerSource = null;
    $scope.highlightedAnnotation = null;
    $scope.creatingANewAnnotation = false;

    // Fetch uri from image table to load OpenSeadragon
    ERMrestService.getEntity().then(function(uri) {
        // Initialize OpenSeadragon with the uri
        $scope.viewerSource = uri;
    });

    // Listen for events from OpenSeadragon/iframe
    // TODO: Maybe figure out an Angular way to listen to the postMessage event
    window.addEventListener('message', function(event) {
        if (event.origin === window.location.origin) {
            var data = event.data;
            var messageType = data.messageType;
            switch (messageType) {
                case 'myAnnoReady':
                    $scope.viewerReady = data.content;
                    if ($scope.viewerReady) {
                        $scope.viewer = window.frames[0];
                        $scope.viewer.postMessage({messageType: 'annotationsList', content: $scope.annotations}, window.location.origin);
                    }
                    break;
                case 'onAnnotationCreated':
                    var annotation = JSON.parse(event.data.content);
                    var coordinates = annotation.data.shapes[0].geometry;
                    ERMrestService.createAnnotation(coordinates.x, coordinates.y, coordinates.width, coordinates.height, annotation.data.context, annotation.data.text, $scope.pushAnnotationToScope);
                    break;
                default:
                    console.log('Invalid message type. No action performed.');
            }
        } else {
            console.log('Invalid event origin. Event origin: ', origin, '. Expected origin: ', window.location.origin);
        }
    });

    // A success callback fn to push new annotations into this controller's scope
    $scope.pushAnnotationToScope = function pushAnnotationToScope(newAnnotation) {
        $scope.annotations.push(newAnnotation);
    };

    $scope.highlightAnnotation = function highlightAnnotation(annotation) {
        $scope.viewer.postMessage({messageType: 'highlightAnnotation', content: annotation}, window.location.origin);
    };

    $scope.setHighlightedAnnotation = function setHighlightedAnnotation(annotationIndex) {
        $scope.highlightedAnnotation = annotationIndex;
    };

    $scope.drawNewAnnotation = function drawNewAnnotation() {
        $scope.creatingANewAnnotation = true;
        $scope.viewer.postMessage({messageType: 'drawNewAnnotation'}, window.location.origin);
    };

    // TODO: Finish this.
    $scope.writtenNewAnnotation = function writtenNewAnnotation() {
        // 1. Create the new annotation in ERMrest and Annotorious

        $scope.creatingANewAnnotation = false;
    };
}]);

// Trusted: A filter that tells Angular when a url is trusted =========================================================================================================================
openSeadragonApp.filter('trusted', ['$sce', function($sce) {
    return function(url) {
        return $sce.trustAsResourceUrl(url);
    };
}]);

// Refreshes page when the window's hash changes
window.onhashchange = function() {
    if (window.location.hash != '#undefined') {
        location.reload();
    } else {
        history.replaceState("", document.title, window.location.pathname);
        location.reload();
    }
    function goBack() {
        window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
        window.location.lasthash.pop();
    }
}
<commit_msg>Created functions to edit annotations in the UI and in ERMrest Edited annotations do not get updated on the Annotorious side yet.<commit_after>// openSeadragonApp: Defines the Angular application ==================================================================================================================================
var openSeadragonApp = angular.module('openSeadragonApp', ['ERMrest']);

// ERMrestService: A service for operations that deal with the ERMrest db =============================================================================================================
openSeadragonApp.service('ERMrestService', ['ermrestClientFactory', '$http', function(ermrestClientFactory, $http) {
    var client = ermrestClientFactory.getClient(window.location.origin + '/ermrest', null);
    var catalog = client.getCatalog(1);

    // Get a reference to the ERMrestService service
    var self = this;

    // Parse Chaise url to determine required parameters to find the requested entity
    this.path = window.location.hash;
    this.params = this.path.split('/');
    this.catalogId = this.params[0].substring(1);
    this.schemaName = this.params[1].split(':')[0];
    this.tableName = this.params[1].split(':')[1];
    this.entityId = this.params[2].split('=')[1];

    var ERMREST_ENDPOINT = window.location.origin + '/ermrest/catalog/';
    if (chaiseConfig['ermrestLocation'] != null) {
        ERMREST_ENDPOINT = chaiseConfig['ermrestLocation'] + '/ermrest/catalog';
    }

    // Returns a Schema object from ERMrest
    this.getSchema = function getSchema() {
        return catalog.introspect().then(function(schemas) {
            return schemas[self.schemaName];
        });
    };

    // Returns the uri value from a row in rbk:image (filtered by the id found in URL)
    this.getEntity = function getEntity() {
        return this.getSchema().then(function(schema) {
            var table = schema.getTable(self.tableName);
            var filteredTable = table.getFilteredTable(["id=" + self.entityId]);
            return filteredTable.getRows().then(function(rows) {
                return rows[0].data.uri;
            });
        });
    };

    this.insertRoi = function insertRoi(x, y, width, height, context) {
        var timestamp = new Date().toISOString();
        var coordinates = [x, y, width, height];
        var roi = [{
            "id": null,
            "image_id": parseInt(this.entityId),
            "author": null,
            "timestamp": timestamp,
            "coords": coordinates,
            "context_uri": context,
            "anatomy": null
        }];
        var entityPath = ERMREST_ENDPOINT + this.catalogId + '/entity/' + this.schemaName + ':roi?defaults=id,author';
        return $http.post(entityPath, roi);
    };

    this.insertRoiComment = function insertRoiComment(roiId, comment) {
        var timestamp = new Date().toISOString();
        var roiComment = [{
            "id": null,
            "roi_id": roiId,
            "author": null,
            "timestamp": timestamp,
            "comment": comment
        }];

        var entityPath = ERMREST_ENDPOINT + this.catalogId + '/entity/' + this.schemaName + ':roi_comment?defaults=id,author';
        return $http.post(entityPath, roiComment);
    };
    // TODO: Rewrite this with ermrestjs
    this.createAnnotation = function createAnnotation(x, y, width, height, context, comment, successCallback) {
        var newAnnotation = {};
        // First create a row in rbk:roi...
        this.insertRoi(x, y, width, height, context).then(function(response) {
            if (response.data) {
                newAnnotation = response.data[0];
                return response.data[0];
            } else {
                return 'Error: Region of interest could not be created. ' + response.status + ' ' + response.statusText;
            }
        // Then create a row in roi_comment, filling in the roi_id column with the result of insertRoi()
        }).then(function(data) {
            var roiId = data.id;
            self.insertRoiComment(roiId, comment).then(function(response) {
                if (response.data) {
                    var commentData = response.data[0];
                    newAnnotation.comments = {id: commentData.id, roiId: commentData.roi_id, author: commentData.author, comment: commentData.comment, timestamp: commentData.timestamp};
                    return response.data[0];
                } else {
                    return 'Error: Comment could not be created. ' + response.status + ' ' + response.statusText;
                }
            });
            successCallback(newAnnotation);
        });
    };

    // TODO: Rewrite this with ermrestjs
    this.editAnnotation = function editAnnotation(annotation) {
        var editedComment = [{
            "id": annotation.comments.id,
            "roi_id": annotation.id,
            "author": null,
            "timestamp": annotation.comments.timestamp,
            "comment": annotation.comments.comment
        }];
        var entityPath = ERMREST_ENDPOINT + this.catalogId + '/entity/' + this.schemaName + ':roi_comment';
        return $http.put(entityPath, editedComment);
    }

    this.getAnnotations = function getAnnotations() {
        var annotations = [];
        this.getSchema().then(function(schema) {
            var roiTable = schema.getTable('roi');
            var filteredRoiTable = roiTable.getFilteredTable(["image_id=" + self.entityId]);
            return filteredRoiTable.getRows().then(function(roiRows) {
                if (roiRows.length > 0) {
                    return Promise.all(roiRows.map(function(roi) {
                        return roi.getRelatedTable(self.schemaName, 'roi_comment').getRows().then(function(commentRows) {
                            return Promise.all(commentRows.map(function(comment) {
                                roi.data.comments = {id: comment.data.id, roiId: comment.data.roi_id, author: comment.data.author, comment: comment.data.comment, timestamp: comment.data.timestamp};
                                annotations.push(roi.data);
                            }));
                        });
                    }));
                } else {
                    console.log('No annotations found for this image.')
                }
            });
        });
        return annotations;
    };
}]);

// MainController: An Angular controller to update the view ===========================================================================================================================
openSeadragonApp.controller('MainController', ['$scope', 'ERMrestService', function($scope, ERMrestService) {
    $scope.annotations = ERMrestService.getAnnotations();
    $scope.viewer = null;
    $scope.viewerReady = false;
    $scope.viewerSource = null;
    $scope.highlightedAnnotation = null;
    $scope.creatingANewAnnotation = false;
    $scope.editMode = false; // True if user is currently editing an annotation
    $scope.editedAnnotation = null; // Track which one is being edited right now
    $scope.editedAnnotationText = ''; // The new annotation text to be used when updating an annotation

    // Fetch uri from image table to load OpenSeadragon
    ERMrestService.getEntity().then(function(uri) {
        // Initialize OpenSeadragon with the uri
        $scope.viewerSource = uri;
    });

    // Listen for events from OpenSeadragon/iframe
    // TODO: Maybe figure out an Angular way to listen to the postMessage event
    window.addEventListener('message', function(event) {
        if (event.origin === window.location.origin) {
            var data = event.data;
            var messageType = data.messageType;
            switch (messageType) {
                case 'myAnnoReady':
                    $scope.viewerReady = data.content;
                    if ($scope.viewerReady) {
                        $scope.viewer = window.frames[0];
                        $scope.viewer.postMessage({messageType: 'annotationsList', content: $scope.annotations}, window.location.origin);
                    }
                    break;
                case 'onAnnotationCreated':
                    var annotation = JSON.parse(event.data.content);
                    var coordinates = annotation.data.shapes[0].geometry;
                    ERMrestService.createAnnotation(coordinates.x, coordinates.y, coordinates.width, coordinates.height, annotation.data.context, annotation.data.text, $scope.pushAnnotationToScope);
                    break;
                default:
                    console.log('Invalid message type. No action performed.');
            }
        } else {
            console.log('Invalid event origin. Event origin: ', origin, '. Expected origin: ', window.location.origin);
        }
    });

    // A success callback fn to push new annotations into this controller's scope
    $scope.pushAnnotationToScope = function pushAnnotationToScope(newAnnotation) {
        $scope.annotations.push(newAnnotation);
    };

    $scope.highlightAnnotation = function highlightAnnotation(annotation) {
        $scope.viewer.postMessage({messageType: 'highlightAnnotation', content: annotation}, window.location.origin);
    };

    $scope.setHighlightedAnnotation = function setHighlightedAnnotation(annotationIndex) {
        $scope.highlightedAnnotation = annotationIndex;
    };

    $scope.drawNewAnnotation = function drawNewAnnotation() {
        $scope.creatingANewAnnotation = true;
        $scope.viewer.postMessage({messageType: 'drawNewAnnotation'}, window.location.origin);
    };

    $scope.editAnnotation = function editAnnotation(annotation) {
        $scope.editedAnnotation = annotation.id;
        $scope.editMode = true;
    };

    $scope.saveAnnotation = function saveAnnotation(annotation) {
        $scope.editedAnnotation = null;
        $scope.editMode = false;
        var timestamp = new Date().toISOString();
        annotation.comments.timestamp = timestamp;
        annotation.comments.comment = annotation.comments.comment;
        ERMrestService.editAnnotation(annotation);
    }

    // $scope.writtenNewAnnotation = function writtenNewAnnotation() {
    //     // 1. Create the new annotation in ERMrest and Annotorious
    //
    //     $scope.creatingANewAnnotation = false;
    // };
}]);

// Trusted: A filter that tells Angular when a url is trusted =========================================================================================================================
openSeadragonApp.filter('trusted', ['$sce', function($sce) {
    return function(url) {
        return $sce.trustAsResourceUrl(url);
    };
}]);

// Refreshes page when the window's hash changes
window.onhashchange = function() {
    if (window.location.hash != '#undefined') {
        location.reload();
    } else {
        history.replaceState("", document.title, window.location.pathname);
        location.reload();
    }
    function goBack() {
        window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
        window.location.lasthash.pop();
    }
}
<|endoftext|>