<commit_before>// see https://github.com/camptocamp/cgxp/blob/master/core/src/script/CGXP/api/Map.js

/**
 * @module api/Map.js
 */

import OLMap from 'ol/Map.js';
import Feature from 'ol/Feature.js';
import Overlay from 'ol/Overlay.js';
import Point from 'ol/geom/Point.js';
import {Icon, Style} from 'ol/style.js';
import {createDefaultStyle} from 'ol/style/Style';
import View from 'ol/View.js';
import VectorSource from 'ol/source/Vector.js';
import VectorLayer from 'ol/layer/Vector.js';
import SelectInteraction from 'ol/interaction/Select.js';

import MousePosition from 'ol/control/MousePosition.js';
import {createStringXY} from 'ol/coordinate.js';
import ScaleLine from 'ol/control/ScaleLine.js';
import OverviewMap from 'ol/control/OverviewMap.js';

// @ts-ignore there is no existing types for ol-layerswitcher
import LayerSwitcher from 'ol-layerswitcher';

import {
  createEmpty as olExtentCreateEmpty,
  extend as olExtentExtend,
  getCenter,
  isEmpty as olExtentIsEmpty
} from 'ol/extent.js';
import {get as getProjection} from 'ol/proj.js';

import constants from './constants.js';

import {getFeaturesFromIds, getFeaturesFromCoordinates} from './Querent.js';
import * as themes from './Themes.js';

/**
 * @type {Array<string>}
 */
const EXCLUDE_PROPERTIES = ['geom', 'geometry', 'boundedBy'];

/**
 * @private
 * @hidden
 */
class Map {

  /**
   * @param {Object} options API options.
   * @property {string} div
   * @property {import("ol/coordinate.js").Coordinate} center
   * @property {number} [zoom=10]
   * @property {boolean} [showCoords=true]
   * TODO: more options
   */
  constructor(options) {

    /**
     * @private
     * @type {View}
     */
    this.view_ = new View({
      projection: getProjection(constants.projection),
      extent: constants.extent,
      resolutions: constants.resolutions,
      zoom: options.zoom !== undefined ? options.zoom : 10
    });

    if (options.center !== undefined) {
      this.view_.setCenter(options.center);
    } else if (constants.extent !== undefined) {
      this.view_.setCenter(getCenter(constants.extent));
    }

    /**
     * @private
     * @type {OLMap}
     */
    this.map_ = new OLMap({
      target: options.div,
      view: this.view_
    });

    /**
     * @private
     * @type {Overlay}
     */
    this.overlay_ = new Overlay({
      autoPan: true,
      autoPanAnimation: {
        duration: 80
      },
      element: this.createOverlayDomTree_()
    });
    this.map_.addOverlay(this.overlay_);

    this.map_.addControl(new ScaleLine());

    if (options.showCoords) {
      this.map_.addControl(new MousePosition({
        coordinateFormat: createStringXY(0)
      }));
    }
    if (options.addMiniMap) {
      this.map_.addControl(new OverviewMap({
        collapsed: !options.miniMapExpanded,
        view: new View({
          projection: this.view_.getProjection(),
          resolutions: this.view_.getResolutions()
        })
      }));
    }

    if (options.addLayerSwitcher) {
      this.map_.addControl(new LayerSwitcher());
    }

    // Get background layer first...
    themes.getBackgroundLayers().then((layers) => {
      // The options is an array for backward compatibility reason.
      const backgroundLayer = options.backgroundLayers || [constants.backgroundLayer];
      for (const layer of layers) {
        if (backgroundLayer.includes(layer.get('config.name'))) {
          // we don't want the background layer in the layerswitch so we remove the title.
          layer.set('title', undefined);
          this.map_.addLayer(layer);
        }
      }

      // ... then get overlay layers (if defined)
      const overlayLayerNames = options.layers;
      if (overlayLayerNames && overlayLayerNames.length) {
        themes.getOverlayLayers(overlayLayerNames).then((layers) => {
          for (const layer of layers) {
            this.map_.addLayer(layer);
          }
        });
      }
    });

    /**
     * @private
     * @type {VectorSource}
     */
    this.vectorSource_ = new VectorSource();

    /**
     * @private
     * @type {VectorLayer}
     */
    this.vectorLayer_ = new VectorLayer({
      zIndex: 1,
      style: null,
      source: this.vectorSource_
    });

    this.map_.addLayer(this.vectorLayer_);

    this.selectInteraction_ = new SelectInteraction({
      filter: (feature) => {
        const hasId = feature.getId() !== undefined;
        const hasTitle = feature.get('title') !== undefined;
        const hasDescription = feature.get('description') !== undefined;
        return hasId && hasTitle && hasDescription;
      },
      style: () => null
    });
    this.map_.addInteraction(this.selectInteraction_);

    this.selectInteraction_.on('select', (event) => {
      const selected = event.selected[0];
      if (selected) {
        this.selectObject(selected.getId());
      }
    });

    this.map_.on('singleclick', (event) => {
      const resolution = this.map_.getView().getResolution();
      const visibleLayers = this.map_.getLayers().getArray().filter(layer => layer.getVisible());
      const visibleLayersName = visibleLayers.map(layer => layer.get('config.name'));

      this.clearSelection();

      for (const layer of constants.queryableLayers) {
        if (visibleLayersName.includes(layer)) {
          getFeaturesFromCoordinates(layer, event.coordinate, resolution).then((feature) => {
            if (feature) {
              this.vectorSource_.addFeature(feature);
              this.selectObject(feature.getId(), true);
            }
          });
        }
      }
    });
  }

  /**
   * @private
   * @return {HTMLElement} overlay container element.
   */
  createOverlayDomTree_() {
    const overlayContainer = document.createElement('div');
    overlayContainer.className = 'ol-popup';
    const overlayCloser = document.createElement('div');
    overlayCloser.className = 'ol-popup-closer';
    overlayCloser.addEventListener('click', () => {
      this.clearSelection();
      return false;
    });
    const overlayContent = document.createElement('div');
    overlayContent.className = 'ol-popup-content';

    overlayContainer.appendChild(overlayCloser);
    overlayContainer.appendChild(overlayContent);

    return overlayContainer;
  }

  /**
   * @param {import("ol/coordinate.js").Coordinate} center Center.
   * @param {number} zoom Zoom.
   */
  recenter(center, zoom) {
    this.view_.setCenter(center);
    this.view_.setZoom(zoom);
  }

  /**
   * @param {Object} options Options.
   * @property {import("ol/coordinate.js").Coordinate} position
   * @property {string} [icon]
   * @property {import("ol/size.js").Size} [size]
   */
  addMarker(options = {}) {
    const marker = new Feature({
      geometry: new Point(options.position ? options.position : this.view_.getCenter())
    });
    if (options.icon) {
      // FIXME: use size?
      marker.setStyle(new Style({
        image: new Icon({
          src: options.icon
        })
      }));
    } else {
      marker.setStyle(createDefaultStyle);
    }
    this.vectorSource_.addFeature(marker);
  }

  /**
   * @param {string} layer Name of the layer to fetch the features from
   * @param {Array.<string>} ids List of ids
   * @param {boolean} [highlight=false] Whether to add the features on the map or not.
   */
  recenterOnObjects(layer, ids, highlight = false) {
    getFeaturesFromIds(layer, ids)
      .then((features) => {
        if (!features.length) {
          console.error('Could not recenter: no objects were found.');
          return;
        }
        const extent = olExtentCreateEmpty();
        for (const feature of features) {
          const geom = feature.getGeometry();
          if (geom) {
            olExtentExtend(extent, geom.getExtent());
          }
        }
        if (!olExtentIsEmpty(extent)) {
          this.view_.fit(extent);
        }
        if (highlight) {
          this.vectorSource_.addFeatures(features);
        }
      })
      .catch((error) => {
        console.error(error);
      });
  }

  /**
   * @param {string} type Layer type, only 'text' format is supported.
   * @param {string} name Name.
   * @param {string} url URL.
   * @param {Object} [options] Options
   * @property {Array.<string>} [attr=['title', 'description']]
   * @property {function()} [success]
   * @property {function()} [error]
   */
  addCustomLayer(type, name, url, options = {}) {
    fetch(url)
      .then(response => response.text())
      .then((text) => {
        const attr = options.attr || ['title', 'description'];
        const lines = text.split(/\r\n|\r|\n/);
        const columns = lines.shift().split('\t');
        for (const line of lines) {
          if (line) {
            const values = zip(columns, line.split('\t'));
            // reverse to order of the coordinates to be compatible with the old api.
            const marker = new Feature({
              geometry: new Point(values.point.split(',').reverse().map(parseFloat))
            });
            marker.setProperties(filterByKeys(values, attr));
            marker.setId(values.id);
            let anchor;
            if (values.iconOffset) {
              // flip the sign of the value to be compatible with the old api.
              anchor = values.iconOffset.split(',').map(parseFloat).map(val => val * Math.sign(val));
            }
            marker.setStyle(new Style({
              image: new Icon({
                src: values.icon,
                anchorXUnits: 'pixels',
                anchorYUnits: 'pixels',
                anchor: anchor
              })
            }));
            this.vectorSource_.addFeature(marker);
          }
        }
        this.view_.fit(this.vectorSource_.getExtent());
      })
      .then(() => {
        if (options.success) {
          options.success();
        }
      })
      .catch(() => {
        if (options.error) {
          options.error();
        }
      });
  }

  /**
   * @param {string|number} id Identifier.
   * @param {boolean} table Display all properties in a table
   */
  selectObject(id, table = false) {
    const feature = this.vectorSource_.getFeatureById(id);
    if (feature) {
      const coordinates = /** @type {import('ol/geom/Point.js').default} */(
        feature.getGeometry()
      ).getCoordinates();
      const properties = feature.getProperties();
      let contentHTML = '';
      if (table) {
        contentHTML += '

';
        for (const key in properties) {
          if (!EXCLUDE_PROPERTIES.includes(key)) {
            contentHTML += '
';
            contentHTML += `<th>${key}</th>`;
            contentHTML += `<td>${properties[key]}</td>`;
            contentHTML += '
';
          }
        }
        contentHTML += '

';
      } else {
        contentHTML += `<div><b>${properties.title}</b></div>`;
        contentHTML += `<p>${properties.description}</p>`;
      }
      const content = this.overlay_.getElement().querySelector('.ol-popup-content');
      content.innerHTML = contentHTML;
      this.overlay_.setPosition(coordinates);
    }
  }

  /**
   *
   */
  clearSelection() {
    // clear the selected features
    this.selectInteraction_.getFeatures().clear();
    // hide the overlay
    this.overlay_.setPosition(undefined);
  }
}

/**
 * @param {Array.<string>} keys Keys.
 * @param {Array.<*>} values Values.
 * @returns {Object<string, *>} Object.
 * @private
 * @hidden
 */
function zip(keys, values) {
  const obj = {};
  keys.forEach((key, index) => {
    obj[key] = values[index];
  });
  return obj;
}

/**
 * @param {Object.<string, *>} obj Object.
 * @param {Array.<string>} keys keys.
 * @returns {Object<string, *>} Object.
 * @private
 * @hidden
 */
function filterByKeys(obj, keys) {
  const filtered = {};
  keys.forEach((key) => {
    filtered[key] = obj[key];
  });
  return filtered;
}

export default Map;
<commit_msg>Exclude the_geom property from query result<commit_after>// see https://github.com/camptocamp/cgxp/blob/master/core/src/script/CGXP/api/Map.js

/**
 * @module api/Map.js
 */

import OLMap from 'ol/Map.js';
import Feature from 'ol/Feature.js';
import Overlay from 'ol/Overlay.js';
import Point from 'ol/geom/Point.js';
import {Icon, Style} from 'ol/style.js';
import {createDefaultStyle} from 'ol/style/Style';
import View from 'ol/View.js';
import VectorSource from 'ol/source/Vector.js';
import VectorLayer from 'ol/layer/Vector.js';
import SelectInteraction from 'ol/interaction/Select.js';

import MousePosition from 'ol/control/MousePosition.js';
import {createStringXY} from 'ol/coordinate.js';
import ScaleLine from 'ol/control/ScaleLine.js';
import OverviewMap from 'ol/control/OverviewMap.js';

// @ts-ignore there is no existing types for ol-layerswitcher
import LayerSwitcher from 'ol-layerswitcher';

import {
  createEmpty as olExtentCreateEmpty,
  extend as olExtentExtend,
  getCenter,
  isEmpty as olExtentIsEmpty
} from 'ol/extent.js';
import {get as getProjection} from 'ol/proj.js';

import constants from './constants.js';

import {getFeaturesFromIds, getFeaturesFromCoordinates} from './Querent.js';
import * as themes from './Themes.js';

/**
 * @type {Array<string>}
 */
const EXCLUDE_PROPERTIES = ['boundedBy'];

/**
 * @private
 * @hidden
 */
class Map {

  /**
   * @param {Object} options API options.
   * @property {string} div
   * @property {import("ol/coordinate.js").Coordinate} center
   * @property {number} [zoom=10]
   * @property {boolean} [showCoords=true]
   * TODO: more options
   */
  constructor(options) {

    /**
     * @private
     * @type {View}
     */
    this.view_ = new View({
      projection: getProjection(constants.projection),
      extent: constants.extent,
      resolutions: constants.resolutions,
      zoom: options.zoom !== undefined ? options.zoom : 10
    });

    if (options.center !== undefined) {
      this.view_.setCenter(options.center);
    } else if (constants.extent !== undefined) {
      this.view_.setCenter(getCenter(constants.extent));
    }

    /**
     * @private
     * @type {OLMap}
     */
    this.map_ = new OLMap({
      target: options.div,
      view: this.view_
    });

    /**
     * @private
     * @type {Overlay}
     */
    this.overlay_ = new Overlay({
      autoPan: true,
      autoPanAnimation: {
        duration: 80
      },
      element: this.createOverlayDomTree_()
    });
    this.map_.addOverlay(this.overlay_);

    this.map_.addControl(new ScaleLine());

    if (options.showCoords) {
      this.map_.addControl(new MousePosition({
        coordinateFormat: createStringXY(0)
      }));
    }
    if (options.addMiniMap) {
      this.map_.addControl(new OverviewMap({
        collapsed: !options.miniMapExpanded,
        view: new View({
          projection: this.view_.getProjection(),
          resolutions: this.view_.getResolutions()
        })
      }));
    }

    if (options.addLayerSwitcher) {
      this.map_.addControl(new LayerSwitcher());
    }

    // Get background layer first...
    themes.getBackgroundLayers().then((layers) => {
      // The options is an array for backward compatibility reason.
      const backgroundLayer = options.backgroundLayers || [constants.backgroundLayer];
      for (const layer of layers) {
        if (backgroundLayer.includes(layer.get('config.name'))) {
          // we don't want the background layer in the layerswitch so we remove the title.
          layer.set('title', undefined);
          this.map_.addLayer(layer);
        }
      }

      // ... then get overlay layers (if defined)
      const overlayLayerNames = options.layers;
      if (overlayLayerNames && overlayLayerNames.length) {
        themes.getOverlayLayers(overlayLayerNames).then((layers) => {
          for (const layer of layers) {
            this.map_.addLayer(layer);
          }
        });
      }
    });

    /**
     * @private
     * @type {VectorSource}
     */
    this.vectorSource_ = new VectorSource();

    /**
     * @private
     * @type {VectorLayer}
     */
    this.vectorLayer_ = new VectorLayer({
      zIndex: 1,
      style: null,
      source: this.vectorSource_
    });

    this.map_.addLayer(this.vectorLayer_);

    this.selectInteraction_ = new SelectInteraction({
      filter: (feature) => {
        const hasId = feature.getId() !== undefined;
        const hasTitle = feature.get('title') !== undefined;
        const hasDescription = feature.get('description') !== undefined;
        return hasId && hasTitle && hasDescription;
      },
      style: () => null
    });
    this.map_.addInteraction(this.selectInteraction_);

    this.selectInteraction_.on('select', (event) => {
      const selected = event.selected[0];
      if (selected) {
        this.selectObject(selected.getId());
      }
    });

    this.map_.on('singleclick', (event) => {
      const resolution = this.map_.getView().getResolution();
      const visibleLayers = this.map_.getLayers().getArray().filter(layer => layer.getVisible());
      const visibleLayersName = visibleLayers.map(layer => layer.get('config.name'));

      this.clearSelection();

      for (const layer of constants.queryableLayers) {
        if (visibleLayersName.includes(layer)) {
          getFeaturesFromCoordinates(layer, event.coordinate, resolution).then((feature) => {
            if (feature) {
              this.vectorSource_.addFeature(feature);
              this.selectObject(feature.getId(), true);
            }
          });
        }
      }
    });
  }

  /**
   * @private
   * @return {HTMLElement} overlay container element.
   */
  createOverlayDomTree_() {
    const overlayContainer = document.createElement('div');
    overlayContainer.className = 'ol-popup';
    const overlayCloser = document.createElement('div');
    overlayCloser.className = 'ol-popup-closer';
    overlayCloser.addEventListener('click', () => {
      this.clearSelection();
      return false;
    });
    const overlayContent = document.createElement('div');
    overlayContent.className = 'ol-popup-content';

    overlayContainer.appendChild(overlayCloser);
    overlayContainer.appendChild(overlayContent);

    return overlayContainer;
  }

  /**
   * @param {import("ol/coordinate.js").Coordinate} center Center.
   * @param {number} zoom Zoom.
   */
  recenter(center, zoom) {
    this.view_.setCenter(center);
    this.view_.setZoom(zoom);
  }

  /**
   * @param {Object} options Options.
   * @property {import("ol/coordinate.js").Coordinate} position
   * @property {string} [icon]
   * @property {import("ol/size.js").Size} [size]
   */
  addMarker(options = {}) {
    const marker = new Feature({
      geometry: new Point(options.position ? options.position : this.view_.getCenter())
    });
    if (options.icon) {
      // FIXME: use size?
      marker.setStyle(new Style({
        image: new Icon({
          src: options.icon
        })
      }));
    } else {
      marker.setStyle(createDefaultStyle);
    }
    this.vectorSource_.addFeature(marker);
  }

  /**
   * @param {string} layer Name of the layer to fetch the features from
   * @param {Array.<string>} ids List of ids
   * @param {boolean} [highlight=false] Whether to add the features on the map or not.
   */
  recenterOnObjects(layer, ids, highlight = false) {
    getFeaturesFromIds(layer, ids)
      .then((features) => {
        if (!features.length) {
          console.error('Could not recenter: no objects were found.');
          return;
        }
        const extent = olExtentCreateEmpty();
        for (const feature of features) {
          const geom = feature.getGeometry();
          if (geom) {
            olExtentExtend(extent, geom.getExtent());
          }
        }
        if (!olExtentIsEmpty(extent)) {
          this.view_.fit(extent);
        }
        if (highlight) {
          this.vectorSource_.addFeatures(features);
        }
      })
      .catch((error) => {
        console.error(error);
      });
  }

  /**
   * @param {string} type Layer type, only 'text' format is supported.
   * @param {string} name Name.
   * @param {string} url URL.
   * @param {Object} [options] Options
   * @property {Array.<string>} [attr=['title', 'description']]
   * @property {function()} [success]
   * @property {function()} [error]
   */
  addCustomLayer(type, name, url, options = {}) {
    fetch(url)
      .then(response => response.text())
      .then((text) => {
        const attr = options.attr || ['title', 'description'];
        const lines = text.split(/\r\n|\r|\n/);
        const columns = lines.shift().split('\t');
        for (const line of lines) {
          if (line) {
            const values = zip(columns, line.split('\t'));
            // reverse to order of the coordinates to be compatible with the old api.
            const marker = new Feature({
              geometry: new Point(values.point.split(',').reverse().map(parseFloat))
            });
            marker.setProperties(filterByKeys(values, attr));
            marker.setId(values.id);
            let anchor;
            if (values.iconOffset) {
              // flip the sign of the value to be compatible with the old api.
              anchor = values.iconOffset.split(',').map(parseFloat).map(val => val * Math.sign(val));
            }
            marker.setStyle(new Style({
              image: new Icon({
                src: values.icon,
                anchorXUnits: 'pixels',
                anchorYUnits: 'pixels',
                anchor: anchor
              })
            }));
            this.vectorSource_.addFeature(marker);
          }
        }
        this.view_.fit(this.vectorSource_.getExtent());
      })
      .then(() => {
        if (options.success) {
          options.success();
        }
      })
      .catch(() => {
        if (options.error) {
          options.error();
        }
      });
  }

  /**
   * @param {string|number} id Identifier.
   * @param {boolean} table Display all properties in a table
   */
  selectObject(id, table = false) {
    const feature = this.vectorSource_.getFeatureById(id);
    if (feature) {
      const coordinates = /** @type {import('ol/geom/Point.js').default} */(
        feature.getGeometry()
      ).getCoordinates();
      const geometryName = feature.getGeometryName();
      const properties = feature.getProperties();
      let contentHTML = '';
      if (table) {
        contentHTML += '

';
        for (const key in properties) {
          if (!EXCLUDE_PROPERTIES.includes(key) || key !== geometryName) {
            contentHTML += '
';
            contentHTML += `<th>${key}</th>`;
            contentHTML += `<td>${properties[key]}</td>`;
            contentHTML += '
';
          }
        }
        contentHTML += '

';
      } else {
        contentHTML += `<div><b>${properties.title}</b></div>`;
        contentHTML += `<p>${properties.description}</p>`;
      }
      const content = this.overlay_.getElement().querySelector('.ol-popup-content');
      content.innerHTML = contentHTML;
      this.overlay_.setPosition(coordinates);
    }
  }

  /**
   *
   */
  clearSelection() {
    // clear the selected features
    this.selectInteraction_.getFeatures().clear();
    // hide the overlay
    this.overlay_.setPosition(undefined);
  }
}

/**
 * @param {Array.<string>} keys Keys.
 * @param {Array.<*>} values Values.
 * @returns {Object<string, *>} Object.
 * @private
 * @hidden
 */
function zip(keys, values) {
  const obj = {};
  keys.forEach((key, index) => {
    obj[key] = values[index];
  });
  return obj;
}

/**
 * @param {Object.<string, *>} obj Object.
 * @param {Array.<string>} keys keys.
 * @returns {Object<string, *>} Object.
 * @private
 * @hidden
 */
function filterByKeys(obj, keys) {
  const filtered = {};
  keys.forEach((key) => {
    filtered[key] = obj[key];
  });
  return filtered;
}

export default Map;
<|endoftext|>


<commit_before>'use strict';

var d3 = require('d3');
var _ = require('underscore');

var symbolSize = 10,
	gapRegion = 0,
	gapShape = 0,
	dictionary = {
		metal: "diamond",
		site: "chevron",
		binding: "catFace",
		act_site: "circle",
		mod_res: "triangle",
		lipid: "wave",
		carbohyd: "hexagon",
		non_std: "pentagon",
		init_met: "arrow",
		non_ter: "doubleBar",
		non_cons: "doubleBar",
		ca_bind:'rectangle',
		disulfid:'bridge',
		crosslink:'bridge',
		turn:'rectangle',
		chain:'rectangle',
		mutagen:'rectangle',
		conflict:'rectangle',
		helix:'rectangle',
		repeat:'rectangle',
		region:'rectangle',
		signal:'rectangle',//CHECK
		peptide:'rectangle',//CHECK
		strand:'rectangle',//CHECK
		topo_dom:'rectangle',//CHECK
		transmem:'rectangle',//CHECK
		motif:'rectangle',//CHECK
		domain:'rectangle',//CHECK
		compbias:'rectangle',//CHECK
		missense:'variant',//CHECK
		ms_del:'variant',//CHECK
		insdel:'variant',//CHECK
		stop_lost:'variant',//CHECK
		stop_gained:'variant',//CHECK
		init_codon:'variant'//CHECK
	};

var Feature = function() {
	var feature = this;
	return feature;
};

var FeatureFactory = function() {
	return {
		getFeature: function(type, aaWidth, height, length) {
			var feature,
				featureType = dictionary[type.toLowerCase()],
				width = aaWidth * length;

			//0,0 is in the middle, so we first move to the starting of the aa at gapShape,0.
			gapShape = length === 1 ? 0 : width/length/2,
			//again a gap is needed for regions
			gapRegion = aaWidth/2;

			// if the constructor doesn't exist, rectangle is used by default
			if (typeof Feature[featureType] !== 'function') {
				console.log(type + ' doesn\'t exist');
				featureType = 'rectangle';
			}

			Feature[featureType].prototype = new Feature();
			feature = Feature[featureType](width, height, length);

			return feature;
		}
	};
}();

Feature.rectangle = function(width, height, length) {
	return 'M' + -(gapRegion) + ',0'
			+ 'L' + (width-gapRegion) + ',0'
			+ 'L' + (width-gapRegion) + ',' + height
			+ 'L' + -(gapRegion) + ',' + height
			+ 'Z';
};

Feature.bridge = function(width, height, length) {
    if (length !== 1) {
    	return 'M' + -(gapRegion) + ',' + height
	            + 'L' + -(gapRegion) + ',0'
	            + 'L' + (width-gapRegion) + ',0'
	            + 'L' + (width-gapRegion) + ',' + height
	            + 'L' + (width-gapRegion) + ',2'
	            + 'L' + -(gapRegion) + ',2Z';
	            //S for bridges, could be C but not implemented yet
	            // + 'M ' + (width/2) + ',0'
				// + 'q ' + -(height+height/2) + ',' + (height/4) + ' ' + -(height/2) + ',' + (height/2)
				// + 'q ' + height + ',' + (height/4) + ' ' + -(height/2) + ',' + (height/2);
    } else {
    	return 'M' + -(gapRegion) + ',' + height
    			+ 'L' + -(gapRegion) + ',' + (height/2)
				+ 'L0,' + (height/2)
				+ 'L0,0'
				+ 'L0,' + (height/2)
				+ 'L' + (width-gapRegion) + ',' + (height/2)
				+ 'L' + (width-gapRegion) + ',' + height
				+ 'Z';
    }
};

// Feature.link = function(width) {
//     var x = feature.x;
//     var y = feature.y;
//     var xLine = feature.xLine;
//     var yLine = feature.yLine;
//     var gap = 6*this.scaleFactor;
//     if (pixelPerAA > this.minShapeSize) {
//         gap = this.pixelScale(gap, pixelPerAA);
//     }
//     feature.shape = ' M ' + xLine + ' ' + yLine //line
//         + ' L ' + (xLine-thick) + ' ' + yLine //line
//         + ' L ' + (xLine-thick) + ' ' + y //line
//         + ' L ' + x + ' ' + y //line
//         //+ 'L' + (x) + ',' + (y-gap*2) //shape
//         //+ 'L' + x + ',' + y //shape
//         + ' L ' + (xLine+thick) + ' ' + y //line
//         + ' L ' + (xLine+thick) + ' ' + yLine //line
//         + ' Z';
//     return feature.shape;
// }

var getMiddleLine = function(centerx, width) {
	return 'M' + centerx + ',' + centerx
			+ 'L' + (width/2+gapShape) + ',' + centerx
			+ 'L' + (-width/2+gapShape) + ',' + centerx;
};

Feature.diamond = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
			+ 'L' + (centerx+gapShape) + ',' + centerx
			+ 'L' + gapShape + ',' + symbolSize
			+ 'L' + (-centerx+gapShape) + ',' + centerx;
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.chevron = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',' + centerx
			+ 'L' + (centerx+gapShape) + ',0'
			+ 'L' + (centerx+gapShape) +',' + centerx
			+ 'L' + gapShape + ',' + symbolSize
			+ 'L' + (-centerx+gapShape) + ',' + centerx
			+ 'L' + (-centerx+gapShape) + ',0';
	return length !== 1
		? shape + 'L' + gapShape + ',' + centerx + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.catFace = function(width, height, length) {
	var centerx = symbolSize/2;
	var step = symbolSize/10;
    var shape = 'M' + (-centerx+gapShape) + ',0'
		+ 'L' + (-centerx+gapShape) + ',' + (6*step)
		+ 'L' + (-2*step+gapShape) + ',' + symbolSize
		+ 'L' + (2*step+gapShape) + ',' + symbolSize
		+ 'L' + (centerx+gapShape) + ',' + (6*step)
		+ 'L' + (centerx+gapShape) + ',0'
		+ 'L' + (2*step+gapShape) + ',' + (4*step)
		+ 'L' + (-2*step+gapShape) + ',' + (4*step);
	return length !== 1
		? shape + 'M' + (-centerx+gapShape) + ',0' + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.triangle = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
				+ 'L' + (centerx+gapShape) + ',' + symbolSize
				+ 'L' + (-centerx+gapShape) + ',' + symbolSize;
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.wave = function(width, height, length) {
	var rx = symbolSize/4;//Math.sqrt(symbolSize / Math.PI);
	var ry = symbolSize/2;
	var shape = 'M' + (-symbolSize/2+gapShape) + ',' + ry
		    + "A" + rx + "," + ry + " 0 1,1 " + gapShape + "," + ry
		    + "A" + rx + "," + ry + " 0 1,0 " + (symbolSize/2+gapShape) + ',' + ry;
    return length !== 1
		? shape + getMiddleLine(ry, width) + 'Z'
		: shape + 'Z';
};

var getPolygon = function(N, width, length){
	var r = symbolSize/2;
	var polygon = 'M ';
	for(var i=0; i < N;i++) {
		polygon += (r * Math.cos(2*Math.PI*i/N) + gapShape) + ',' + (r * Math.sin(2*Math.PI*i/N)+r)  + ' ';
	};
	return length !== 1
		? polygon + ' ' + (r * Math.cos(0) + gapShape) + ',' + (r * Math.sin(0)+r)  + ' ' + getMiddleLine(r, width) + 'Z'
		: polygon + 'Z';
};

Feature.hexagon = function(width, height, length) {
	return getPolygon(6, width, length);
};

Feature.pentagon = function(width, height, length) {
	return getPolygon(5, width, length);
};

Feature.circle = function(width, height, length) {
  var r = Math.sqrt(symbolSize / Math.PI);
  var centerx = symbolSize/2;
  var shape = "M" + gapShape + ",0"
      + "A" + r + "," + r + " 0 1,1 " + gapShape + "," + symbolSize
      + "A" + r + "," + r + " 0 1,1 " + gapShape + ",0";
  return length !== 1
		? shape + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.arrow = function(width, height, length) {
	var step = symbolSize/10;
	var shape = 'M' + gapShape + ',0'
		+ 'L' + (-step+gapShape) + ',0'
		+ 'L' + (-5*step+gapShape) + ',' + (4*step)
		+ 'L' + (-step+gapShape) + ',' + height
		+ 'L' + gapShape + ',' + height
		+ 'L' + (4*step+gapShape) + ',' + (4*step);
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.doubleBar = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
		+ 'L' + (-centerx+gapShape) + ',' + symbolSize
		+ 'L' + gapShape + ',' + symbolSize
		+ 'L' + (centerx+gapShape) + ',0';
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.variant = function() {
	//TODO
};

module.exports = FeatureFactory;<commit_msg>Keep the bar totally behind the shapes.<commit_after>'use strict';

var d3 = require('d3');
var _ = require('underscore');

var symbolSize = 10,
	gapRegion = 0,
	gapShape = 0,
	dictionary = {
		metal: "diamond",
		site: "chevron",
		binding: "catFace",
		act_site: "circle",
		mod_res: "triangle",
		lipid: "wave",
		carbohyd: "hexagon",
		non_std: "pentagon",
		init_met: "arrow",
		non_ter: "doubleBar",
		non_cons: "doubleBar",
		ca_bind:'rectangle',
		disulfid:'bridge',
		crosslink:'bridge',
		turn:'rectangle',
		chain:'rectangle',
		mutagen:'rectangle',
		conflict:'rectangle',
		helix:'rectangle',
		repeat:'rectangle',
		region:'rectangle',
		signal:'rectangle',//CHECK
		peptide:'rectangle',//CHECK
		strand:'rectangle',//CHECK
		topo_dom:'rectangle',//CHECK
		transmem:'rectangle',//CHECK
		motif:'rectangle',//CHECK
		domain:'rectangle',//CHECK
		compbias:'rectangle',//CHECK
		missense:'variant',//CHECK
		ms_del:'variant',//CHECK
		insdel:'variant',//CHECK
		stop_lost:'variant',//CHECK
		stop_gained:'variant',//CHECK
		init_codon:'variant'//CHECK
	};

var Feature = function() {
	var feature = this;
	return feature;
};

var FeatureFactory = function() {
	return {
		getFeature: function(type, aaWidth, height, length) {
			var feature,
				featureType = dictionary[type.toLowerCase()],
				width = aaWidth * length;

			//0,0 is in the middle, so we first move to the starting of the aa at gapShape,0.
			gapShape = length === 1 ? 0 : width/length/2,
			//again a gap is needed for regions
			gapRegion = aaWidth/2;

			// if the constructor doesn't exist, rectangle is used by default
			if (typeof Feature[featureType] !== 'function') {
				console.log(type + ' doesn\'t exist');
				featureType = 'rectangle';
			}

			Feature[featureType].prototype = new Feature();
			feature = Feature[featureType](width, height, length);

			return feature;
		}
	};
}();

Feature.rectangle = function(width, height, length) {
	return 'M' + -(gapRegion) + ',0'
			+ 'L' + (width-gapRegion) + ',0'
			+ 'L' + (width-gapRegion) + ',' + height
			+ 'L' + -(gapRegion) + ',' + height
			+ 'Z';
};

Feature.bridge = function(width, height, length) {
    if (length !== 1) {
    	return 'M' + -(gapRegion) + ',' + height
	            + 'L' + -(gapRegion) + ',0'
	            + 'L' + (width-gapRegion) + ',0'
	            + 'L' + (width-gapRegion) + ',' + height
	            + 'L' + (width-gapRegion) + ',2'
	            + 'L' + -(gapRegion) + ',2Z';
	            //S for bridges, could be C but not implemented yet
	            // + 'M ' + (width/2) + ',0'
				// + 'q ' + -(height+height/2) + ',' + (height/4) + ' ' + -(height/2) + ',' + (height/2)
				// + 'q ' + height + ',' + (height/4) + ' ' + -(height/2) + ',' + (height/2);
    } else {
    	return 'M' + -(gapRegion) + ',' + height
    			+ 'L' + -(gapRegion) + ',' + (height/2)
				+ 'L0,' + (height/2)
				+ 'L0,0'
				+ 'L0,' + (height/2)
				+ 'L' + (width-gapRegion) + ',' + (height/2)
				+ 'L' + (width-gapRegion) + ',' + height
				+ 'Z';
    }
};

// Feature.link = function(width) {
//     var x = feature.x;
//     var y = feature.y;
//     var xLine = feature.xLine;
//     var yLine = feature.yLine;
//     var gap = 6*this.scaleFactor;
//     if (pixelPerAA > this.minShapeSize) {
//         gap = this.pixelScale(gap, pixelPerAA);
//     }
//     feature.shape = ' M ' + xLine + ' ' + yLine //line
//         + ' L ' + (xLine-thick) + ' ' + yLine //line
//         + ' L ' + (xLine-thick) + ' ' + y //line
//         + ' L ' + x + ' ' + y //line
//         //+ 'L' + (x) + ',' + (y-gap*2) //shape
//         //+ 'L' + x + ',' + y //shape
//         + ' L ' + (xLine+thick) + ' ' + y //line
//         + ' L ' + (xLine+thick) + ' ' + yLine //line
//         + ' Z';
//     return feature.shape;
// }

var getMiddleLine = function(centerx, width) {
	return 'M' + (centerx+gapShape) + ',' + centerx
			+ 'L' + (width/2+gapShape) + ',' + centerx
			+ 'M' + (-centerx+gapShape) + ',' + centerx
			+ 'L' + (-width/2+gapShape) + ',' + centerx;
};

Feature.diamond = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
			+ 'L' + (centerx+gapShape) + ',' + centerx
			+ 'L' + gapShape + ',' + symbolSize
			+ 'L' + (-centerx+gapShape) + ',' + centerx;
	return length !== 1
		? shape + 'L' + gapShape + ',0Z' + getMiddleLine(centerx, width)
		: shape + 'Z';
};

Feature.chevron = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',' + centerx
			+ 'L' + (centerx+gapShape) + ',0'
			+ 'L' + (centerx+gapShape) +',' + centerx
			+ 'L' + gapShape + ',' + symbolSize
			+ 'L' + (-centerx+gapShape) + ',' + centerx
			+ 'L' + (-centerx+gapShape) + ',0';
	return length !== 1
		? shape + 'L' + gapShape + ',' + centerx + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.catFace = function(width, height, length) {
	var centerx = symbolSize/2;
	var step = symbolSize/10;
    var shape = 'M' + (-centerx+gapShape) + ',0'
		+ 'L' + (-centerx+gapShape) + ',' + (6*step)
		+ 'L' + (-2*step+gapShape) + ',' + symbolSize
		+ 'L' + (2*step+gapShape) + ',' + symbolSize
		+ 'L' + (centerx+gapShape) + ',' + (6*step)
		+ 'L' + (centerx+gapShape) + ',0'
		+ 'L' + (2*step+gapShape) + ',' + (4*step)
		+ 'L' + (-2*step+gapShape) + ',' + (4*step);
	return length !== 1
		? shape + 'M' + (-centerx+gapShape) + ',0' + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.triangle = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
				+ 'L' + (centerx+gapShape) + ',' + symbolSize
				+ 'L' + (-centerx+gapShape) + ',' + symbolSize;
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(centerx, width) + 'Z'
		: shape + 'Z';
};

Feature.wave = function(width, height, length) {
	var rx = symbolSize/4;//Math.sqrt(symbolSize / Math.PI);
	var ry = symbolSize/2;
	var shape = 'M' + (-symbolSize/2+gapShape) + ',' + ry
		    + "A" + rx + "," + ry + " 0 1,1 " + gapShape + "," + ry
		    + "A" + rx + "," + ry + " 0 1,0 " + (symbolSize/2+gapShape) + ',' + ry;
    return length !== 1
		? shape + getMiddleLine(ry, width) + 'Z'
		: shape + 'Z';
};

var getPolygon = function(N, width, length){
	var r = symbolSize/2;
	var polygon = 'M ';
	for(var i=0; i < N;i++) {
		polygon += (r * Math.cos(2*Math.PI*i/N) + gapShape) + ',' + (r * Math.sin(2*Math.PI*i/N)+r)  + ' ';
	};
	return length !== 1
		? polygon + ' ' + (r * Math.cos(0) + gapShape) + ',' + (r * Math.sin(0)+r)  + ' ' + getMiddleLine(r, width) + 'Z'
		: polygon + 'Z';
};

Feature.hexagon = function(width, height, length) {
	return getPolygon(6, width, length);
};

Feature.pentagon = function(width, height, length) {
	return getPolygon(5, width, length);
};

Feature.circle = function(width, height, length) {
  var r = Math.sqrt(symbolSize / Math.PI);
  var centerx = symbolSize/2;
  var shape = "M" + gapShape + ",0"
      + "A" + r + "," + r + " 0 1,1 " + gapShape + "," + symbolSize
      + "A" + r + "," + r + " 0 1,1 " + gapShape + ",0";
  return length !== 1
		? shape + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.arrow = function(width, height, length) {
	var step = symbolSize/10;
	var shape = 'M' + gapShape + ',0'
		+ 'L' + (-step+gapShape) + ',0'
		+ 'L' + (-5*step+gapShape) + ',' + (4*step)
		+ 'L' + (-step+gapShape) + ',' + height
		+ 'L' + gapShape + ',' + height
		+ 'L' + (4*step+gapShape) + ',' + (4*step);
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.doubleBar = function(width, height, length) {
	var centerx = symbolSize/2;
	var shape = 'M' + gapShape + ',0'
		+ 'L' + (-centerx+gapShape) + ',' + symbolSize
		+ 'L' + gapShape + ',' + symbolSize
		+ 'L' + (centerx+gapShape) + ',0';
	return length !== 1
		? shape + 'L' + gapShape + ',0' + getMiddleLine(symbolSize/2, width) + 'Z'
		: shape + 'Z';
};

Feature.variant = function() {
	//TODO
};

module.exports = FeatureFactory;<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 pingworks - Alexander Birk und Christoph Lukas
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
var Dash = {};

Dash.config = {
    toolbar: {
        left: [{
            id: 'Logo',
            xtype: 'component',
            width: 48,
            height: 38,
            html: ''
        }, {
            xtype: 'component',
            html: ' ',
            width: 10
        }, {
            id: 'Title',
            xtype: 'component',
            html: 'Dashboard',
            style: 'font-size: 32px'
        }],
        links: [{
            id: 'JenkinsButton',
            text: 'Jenkins',
            url: 'https://dash.pingworks.net/jenkins/'
        }, {
            id: 'RepoButton',
            text: 'Repo',
            url: 'https://dash.pingworks.net/repo/'
        }, {
            id: 'EnvButton',
            text: 'Environments',
            handler: function() {
                this.findParentByType('toolbar').fireEvent('hideDeployWindow');
                this.findParentByType('toolbar').fireEvent('showEnvironmentsWindow');
            }
        }]
    },

    bundlegrid: {
        title: 'Bundles in Branch: {0}',
        dateformat: 'd.m.Y H:i:s',
        icon: {
            change: 'resources/img/icons/change.png',
            deploy: 'resources/img/icons/deploy.png'
        },
        repolink: '{1}',
        vcslink: '{1}',
        vcsrepolink: '{0}',
        sort: {
            field: 'timestamp',
            dir: 'DESC'
        },
        reload: 300000, // 5 min
        deployment: {
            enabled: true,
            required: {
                field: 'stage1',
                value: 3
            }
        },
        triggerJenkinsJob: {
            enabled: true,
            required: {
                field: 'stage1',
                value: 3
            }
        },
        colwidth: {
            timestamp: 180,
            committer: 120,
            revision: 90,
            repository: 90,
            bundle: 120,
            stage1: 40,
            stage2: 40,
            stage3: 40,
            changes: 120,
            deployment: 60,
            triggerJenkinsJob: 60
        },
        label: {
            timestamp: 'Created',
            committer: 'Committer',
            revision: 'CommitId',
            repository: 'VCS',
            bundle: 'Bundle',
            stage1: '1st',
            stage2: '2nd',
            stage3: '3rd',
            changes: 'Changes',
            deployment: 'Deploy Test',
            triggerJenkinsJob: 'Deploy Prod'
        },
        hidden: {
            timestamp: false,
            committer: false,
            revision: false,
            repository: true,
            bundle: false,
            stage1: false,
            stage2: false,
            stage3: false,
            changes: false,
            deployment: false,
            triggerJenkinsJob: false
        }
    },

    environmentgrid: {
        dateformat: 'd.m.Y H:i:s',
        envlink: '{1}'
    },

    branch: {
        endpoint: '/branch'
    },

    bundle: {
        endpoint: '/bundle',
        dateformat: 'Y-m-d_H:i:s'
    },

    change: {
        endpoint: '/change',
        title: 'Changes in Bundle {0}'
    },

    content: {
        endpoint: '/content'
    },

    stagestatus: {
        iconpath: 'resources/img/icons/status/{0}',
        data: [
            {
                'id': 0,
                'name': 'not running',
                'cls' : 'unknown',
                'icon': 'grey.png'
            },
            {
                'id': 1,
                'name': 'in progress',
                'cls' : 'inprogress',
                'icon': 'green-ani.gif'
            },
            {
                'id': 2,
                'name': 'failed',
                'cls' : 'failed',
                'icon': 'red.png'
            },
            {
                'id': 3,
                'name': 'success',
                'cls' : 'success',
                'icon': 'green.png'
            }
        ]
    },

    jobstatus: {
        iconpath: 'resources/img/icons/status/{0}',
        data: [
            {
                'id': '-',
                'name': 'not running',
                'cls' : 'unknown',
                'icon': 'grey.png'
            },
            {
                'id': 'UNSTABLE',
                'name': 'unstable',
                'cls' : 'unstable',
                'icon': 'yellow.png'
            },
            {
                'id': 'FAILURE',
                'name': 'failed',
                'cls' : 'failed',
                'icon': 'red.png'
            },
            {
                'id': 'SUCCESS',
                'name': 'success',
                'cls' : 'success',
                'icon': 'green.png'
            }
        ]
    },

    jobresult: {
        endpoint: '/jobresult',
        text: '
 '
            + '{0}: Tests: {3}, skipped: {4}, failed: {5}
',
        title: '{1} stage Jobs for Bundle {2}',
        stageMap: {
            1: 'First',
            2: 'Second',
            3: 'Third'
        }
    },

    environment: {
        endpoint: '/environment',
        dateformat: 'Y-m-d H:i:s'
    },

    deployment: {
        triggerUrl: '/jenkins/job/Deployment/buildWithParameters?token=Omi7foh4gu7d',
        showUrl: '/jenkins/job/Deployment/',
        features: {
        	content: {
        		enabled: false,
        		label: 'Content',
        		emptyText: 'no deployment this time'
            },
            dbreset: {
                enabled: false,
                label: 'Database Reset'
            }
        }
    },

    triggerJenkinsJob: {
        triggerUrl: '/jenkins/job/DeploymentProd/buildWithParameters?token=Omi7foh4gu7d',
        showUrl: '/jenkins/job/DeploymentProd/',
        title: 'Deployment to production',
        label: {
            cancel: 'Cancel',
            run: 'Go go go !!'
        },
        text: 'Do you really want to deploy to production?',
        inputFields: [/*{
            type: 'checkbox',
            label: 'Module 1: {1}',
            labelBundleKey: 'foo',
            name: 'module1',
            value: 'module1'
        }, {
            type: 'checkbox',
            label: 'Module 2: {1}',
            labelBundleKey: 'bar',
            name: 'module2',
            value: 'module2'
        }*/],
        params: {
            bundle: {
                name: 'bundle',
                value: '{1}'
            },
            formValues: {
                name: 'formValues'
            }
        }
    },

    lockduration: {
        data: [
            {
                'id': '1',
                'name': '1 hour'
            }, {
                'id': '2',
                'name': '2 hours'
            }, {
                'id': '4',
                'name': '4 hours'
            }, {
                'id': '8',
                'name': '8 hours'
            }, {
                'id': '24',
                'name': '1 day'
            }, {
                'id': '48',
                'name': '2 days'
            }, {
                'id': '120',
                'name': '5 days'
            }
        ]
    },

    error: {
        title: 'Error',
        msg: 'Unable to read data from server.'
    }

}
<commit_msg>Title changed<commit_after>/*
 * Copyright (C) 2013 pingworks - Alexander Birk und Christoph Lukas
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
var Dash = {};

Dash.config = {
    toolbar: {
        left: [{
            id: 'Logo',
            xtype: 'component',
            width: 48,
            height: 38,
            html: ''
        }, {
            xtype: 'component',
            html: ' ',
            width: 10
        }, {
            id: 'Title',
            xtype: 'component',
            html: 'Abkon 2014',
            style: 'font-size: 32px'
        }],
        links: [{
            id: 'JenkinsButton',
            text: 'Jenkins',
            url: 'https://dash.pingworks.net/jenkins/'
        }, {
            id: 'RepoButton',
            text: 'Repo',
            url: 'https://dash.pingworks.net/repo/'
        }, {
            id: 'EnvButton',
            text: 'Environments',
            handler: function() {
                this.findParentByType('toolbar').fireEvent('hideDeployWindow');
                this.findParentByType('toolbar').fireEvent('showEnvironmentsWindow');
            }
        }]
    },

    bundlegrid: {
        title: 'Bundles in Branch: {0}',
        dateformat: 'd.m.Y H:i:s',
        icon: {
            change: 'resources/img/icons/change.png',
            deploy: 'resources/img/icons/deploy.png'
        },
        repolink: '{1}',
        vcslink: '{1}',
        vcsrepolink: '{0}',
        sort: {
            field: 'timestamp',
            dir: 'DESC'
        },
        reload: 300000, // 5 min
        deployment: {
            enabled: true,
            required: {
                field: 'stage1',
                value: 3
            }
        },
        triggerJenkinsJob: {
            enabled: true,
            required: {
                field: 'stage1',
                value: 3
            }
        },
        colwidth: {
            timestamp: 180,
            committer: 120,
            revision: 90,
            repository: 90,
            bundle: 120,
            stage1: 40,
            stage2: 40,
            stage3: 40,
            changes: 120,
            deployment: 60,
            triggerJenkinsJob: 60
        },
        label: {
            timestamp: 'Created',
            committer: 'Committer',
            revision: 'CommitId',
            repository: 'VCS',
            bundle: 'Bundle',
            stage1: '1st',
            stage2: '2nd',
            stage3: '3rd',
            changes: 'Changes',
            deployment: 'Deploy Test',
            triggerJenkinsJob: 'Deploy Prod'
        },
        hidden: {
            timestamp: false,
            committer: false,
            revision: false,
            repository: true,
            bundle: false,
            stage1: false,
            stage2: false,
            stage3: false,
            changes: false,
            deployment: false,
            triggerJenkinsJob: false
        }
    },

    environmentgrid: {
        dateformat: 'd.m.Y H:i:s',
        envlink: '{1}'
    },

    branch: {
        endpoint: '/branch'
    },

    bundle: {
        endpoint: '/bundle',
        dateformat: 'Y-m-d_H:i:s'
    },

    change: {
        endpoint: '/change',
        title: 'Changes in Bundle {0}'
    },

    content: {
        endpoint: '/content'
    },

    stagestatus: {
        iconpath: 'resources/img/icons/status/{0}',
        data: [
            {
                'id': 0,
                'name': 'not running',
                'cls' : 'unknown',
                'icon': 'grey.png'
            },
            {
                'id': 1,
                'name': 'in progress',
                'cls' : 'inprogress',
                'icon': 'green-ani.gif'
            },
            {
                'id': 2,
                'name': 'failed',
                'cls' : 'failed',
                'icon': 'red.png'
            },
            {
                'id': 3,
                'name': 'success',
                'cls' : 'success',
                'icon': 'green.png'
            }
        ]
    },

    jobstatus: {
        iconpath: 'resources/img/icons/status/{0}',
        data: [
            {
                'id': '-',
                'name': 'not running',
                'cls' : 'unknown',
                'icon': 'grey.png'
            },
            {
                'id': 'UNSTABLE',
                'name': 'unstable',
                'cls' : 'unstable',
                'icon': 'yellow.png'
            },
            {
                'id': 'FAILURE',
                'name': 'failed',
                'cls' : 'failed',
                'icon': 'red.png'
            },
            {
                'id': 'SUCCESS',
                'name': 'success',
                'cls' : 'success',
                'icon': 'green.png'
            }
        ]
    },

    jobresult: {
        endpoint: '/jobresult',
        text: '
 '
            + '{0}: Tests: {3}, skipped: {4}, failed: {5}
',
        title: '{1} stage Jobs for Bundle {2}',
        stageMap: {
            1: 'First',
            2: 'Second',
            3: 'Third'
        }
    },

    environment: {
        endpoint: '/environment',
        dateformat: 'Y-m-d H:i:s'
    },

    deployment: {
        triggerUrl: '/jenkins/job/Deployment/buildWithParameters?token=Omi7foh4gu7d',
        showUrl: '/jenkins/job/Deployment/',
        features: {
        	content: {
        		enabled: false,
        		label: 'Content',
        		emptyText: 'no deployment this time'
            },
            dbreset: {
                enabled: false,
                label: 'Database Reset'
            }
        }
    },

    triggerJenkinsJob: {
        triggerUrl: '/jenkins/job/DeploymentProd/buildWithParameters?token=Omi7foh4gu7d',
        showUrl: '/jenkins/job/DeploymentProd/',
        title: 'Deployment to production',
        label: {
            cancel: 'Cancel',
            run: 'Go go go !!'
        },
        text: 'Do you really want to deploy to production?',
        inputFields: [/*{
            type: 'checkbox',
            label: 'Module 1: {1}',
            labelBundleKey: 'foo',
            name: 'module1',
            value: 'module1'
        }, {
            type: 'checkbox',
            label: 'Module 2: {1}',
            labelBundleKey: 'bar',
            name: 'module2',
            value: 'module2'
        }*/],
        params: {
            bundle: {
                name: 'bundle',
                value: '{1}'
            },
            formValues: {
                name: 'formValues'
            }
        }
    },

    lockduration: {
        data: [
            {
                'id': '1',
                'name': '1 hour'
            }, {
                'id': '2',
                'name': '2 hours'
            }, {
                'id': '4',
                'name': '4 hours'
            }, {
                'id': '8',
                'name': '8 hours'
            }, {
                'id': '24',
                'name': '1 day'
            }, {
                'id': '48',
                'name': '2 days'
            }, {
                'id': '120',
                'name': '5 days'
            }
        ]
    },

    error: {
        title: 'Error',
        msg: 'Unable to read data from server.'
    }

}
<|endoftext|>


<commit_before>'use strict';

require('./_view-way.scss');

const viewOneProfileComponent = require('../../../dialog/profile/view-one-profile/view-one-profile.js');

const editWayComponent = require('../../../dialog/way/edit-way/edit-way.js');

module.exports = {
  template: require('./view-way.html'),
  controller: ['$log', '$mdDialog', '$mdToast','wayService', 'way', '$scope', 'messageService', 'profileService', '$mdMedia', ViewWayController],
  controllerAs: 'viewWayCtrl'
};

function ViewWayController($log, $mdDialog, $mdToast, wayService, way, $scope, messageService, profileService, $mdMedia) {
  console.log('this.way on view way ctrl before', this.way);
  this.way = wayService.getOneWay(way._id);

  console.log('this.way on view way ctrl after', this.way);

  profileService.fetchProfile()
  .then( profile => {
    this.profile = profile;
  });

  this.name = this.way.name || 'Way';

  this.startLocation = displayLocation(way.startLocation);
  this.endLocation = displayLocation(way.endLocation);

  console.log('wayer 0', this.way.wayerz[0]);

  // this.isPM = true;
  const dayMap = { '0': 'Monday', '1':'Tuesday', '2':'Wednesday', '3': 'Thursday', '4': 'Friday', '5': 'Saturday', '6': 'Sunday'};

  let dayArray = [];

  if (this.way.recurringDayOfWeek) {
    this.way.recurringDayOfWeek.forEach( i => {
      dayArray.push(`${dayMap[i]} `);
    });
  }

  if (this.way.oneTimeDate) {
    this.oneTimeDate = new Date(this.way.oneTimeDate);
  }

  if (this.way.hour) {
    if (this.way.hour > 12) {
      this.hour = this.way.hour - 12;
      this.ampm = 'pm';
    } else {
      this.hour = this.way.hour;
      this.ampm = 'am';
    }
    this.minutes = this.way.minutes;
  }

  this.dayArray = dayArray;

  this.isLoading = false;

  this.editWay = function ($event, bindFlag, way) {
    const dialogConfig = {
      // scope: $scope.$new(true),
      fullscreen: !$mdMedia('gt-sm'),
      targetEvent: $event,
      resolve: {
        way: function() {
          return way;
        }
      },
    };
    $mdDialog.show(Object.assign(editWayComponent, dialogConfig));
  };

  this.viewProfile = function($event, profile) {
    const dialogConfig = {
      fullscreen: !$mdMedia('gt-sm'),
      targetEvent: $event,
      resolve: {
        profile: function() {
          return profile;
        }
      },
    };
    $mdDialog.show(Object.assign(viewOneProfileComponent, dialogConfig));
  };

  this.joinSubmit = function() {
    this.isLoading = true;

    console.log(this.way);

    const joinMessage = {
      subject: `${this.profile.displayName} wants to join your way!`,
      text: `Please add me to your ${this.way.name ? this.way.name : '' } Way: ${this.way._id}`,
      toProfileID: this.way.wayerz[0]._id
    };

    messageService.createMessage(joinMessage)
    .then( res => {
      $mdToast.showSimple('Request to Join Sent Successfully!');
      this.isLoading = false;

      $mdDialog.hide();
    })
    .catch( err => {
      $mdToast.showSimple(err.data);
      this.isLoading = false;
    });

    $log.log(this.way);
  };

  this.closeDialog = function() {
    $mdDialog.hide();
  };

  this.exists = function (item, list) {
    return list.indexOf(dayMap[item]) > -1;
  };

  this.toggle = function (item, list) {
    var idx = list.indexOf(dayMap[item]);
    if (idx > -1) {
      list.splice(idx, 1);
    }
    else {
      list.push(dayMap[item]);
    }
  };
}

function displayLocation({street, city, state}) {
  return `${street ? street : ''} ${city}, ${state}`;
}
<commit_msg>using filter method to check if current user is a part of the wayerz array.<commit_after>'use strict';

require('./_view-way.scss');

const viewOneProfileComponent = require('../../../dialog/profile/view-one-profile/view-one-profile.js');

const editWayComponent = require('../../../dialog/way/edit-way/edit-way.js');

module.exports = {
  template: require('./view-way.html'),
  controller: ['$log', '$mdDialog', '$mdToast','wayService', 'way', '$scope', 'messageService', 'profileService', '$mdMedia', ViewWayController],
  controllerAs: 'viewWayCtrl'
};

function ViewWayController($log, $mdDialog, $mdToast, wayService, way, $scope, messageService, profileService, $mdMedia) {
  console.log('this.way on view way ctrl before', this.way);
  this.way = wayService.getOneWay(way._id);

  console.log('this.way on view way ctrl after', this.way);

  profileService.fetchProfile()
  .then( profile => {
    this.profile = profile;
    $log.debug('wayerz.includes', this.way.wayerz.filter(function(ele) {
      return ele._id === profile._id;
    }).length > 0);
  });

  this.name = this.way.name || 'Way';

  this.startLocation = displayLocation(way.startLocation);
  this.endLocation = displayLocation(way.endLocation);

  console.log('wayer 0', this.way.wayerz[0]);
  // this.isPM = true;
  const dayMap = { '0': 'Monday', '1':'Tuesday', '2':'Wednesday', '3': 'Thursday', '4': 'Friday', '5': 'Saturday', '6': 'Sunday'};

  let dayArray = [];

  if (this.way.recurringDayOfWeek) {
    this.way.recurringDayOfWeek.forEach( i => {
      dayArray.push(`${dayMap[i]} `);
    });
  }

  if (this.way.oneTimeDate) {
    this.oneTimeDate = new Date(this.way.oneTimeDate);
  }

  if (this.way.hour) {
    if (this.way.hour > 12) {
      this.hour = this.way.hour - 12;
      this.ampm = 'pm';
    } else {
      this.hour = this.way.hour;
      this.ampm = 'am';
    }
    this.minutes = this.way.minutes;
  }

  this.dayArray = dayArray;

  this.isLoading = false;

  this.editWay = function ($event, bindFlag, way) {
    const dialogConfig = {
      // scope: $scope.$new(true),
      fullscreen: !$mdMedia('gt-sm'),
      targetEvent: $event,
      resolve: {
        way: function() {
          return way;
        }
      },
    };
    $mdDialog.show(Object.assign(editWayComponent, dialogConfig));
  };

  this.viewProfile = function($event, profile) {
    const dialogConfig = {
      fullscreen: !$mdMedia('gt-sm'),
      targetEvent: $event,
      resolve: {
        profile: function() {
          return profile;
        }
      },
    };
    $mdDialog.show(Object.assign(viewOneProfileComponent, dialogConfig));
  };

  this.joinSubmit = function() {
    this.isLoading = true;

    const joinMessage = {
      subject: `${this.profile.displayName} wants to join your way!`,
      text: `Please add me to your ${this.way.name ? this.way.name : '' } Way: ${this.way._id}`,
      toProfileID: this.way.wayerz[0]._id
    };

    messageService.createMessage(joinMessage)
    .then( () => {
      $mdToast.showSimple('Request to Join Sent Successfully!');
      this.isLoading = false;

      $mdDialog.hide();
    })
    .catch( err => {
      $mdToast.showSimple(err.data);
      this.isLoading = false;
    });

    $log.log(this.way);
  };

  this.closeDialog = function() {
    $mdDialog.hide();
  };

  this.exists = function (item, list) {
    return list.indexOf(dayMap[item]) > -1;
  };

  this.toggle = function (item, list) {
    var idx = list.indexOf(dayMap[item]);
    if (idx > -1) {
      list.splice(idx, 1);
    }
    else {
      list.push(dayMap[item]);
    }
  };
}

function displayLocation({street, city, state}) {
  return `${street ? street : ''} ${city}, ${state}`;
}
<|endoftext|>


<commit_before>(function () {
    var $el = $('body > pre');
    var text = $el.html();

    var d = new Date();

    var year = d.getFullYear();
    var month = ('0' + (d.getMonth()+1)).slice(-2);
    var day = ('0' + d.getDate()).slice(-2);
    var hour = ('0' + (d.getHours() + d.getTimezoneOffset()/60)).slice(-2);
    var minute = d.getMinutes();

    var pattern = new RegExp('(' + year + '-' + month + '-' +
            day + ' ' + hour + ':(' +
                minute + '|' + (minute-1) + '|' + (minute-2) +
                '|' + (minute-3) + '|' + (minute-4)  + '|' + (minute-5) +
            '):)', 'gm');

    text = text.replace(pattern, '$1');

    text = text.replace(/(^\[.+?\])/gm, '$1');
    text = text.replace(/(WARN|warning)/gm, '$1');
    text = text.replace(/(ERROR)/gm, '$1');
    text = text.replace(/(Sites\-(\w+-)?Site)/gm, '$1');
    text = text.replace(/(\/\w[^ ]+?\.[a-z]+)/gmi, '$1');
    text = text.replace(/(\/\w+\.[a-z]+)/gmi, '$1');
    text = text.replace(/(^\tat.+$)/gmi, '$1');

    $el.addClass('language-log')
        .html('' + text + '');

})();
<commit_msg>Adds the autoscroll to the end of the file, fixes the minutes pattern, devides the logs into sections, added more keywords<commit_after>(function () {
    var $el = $('body > pre');
    var text = $el.html();

    var d = new Date();

    var year = d.getFullYear();
    var month = pad(d.getMonth()+1);
    var day = pad(d.getDate());
    var hour = pad(d.getHours() + d.getTimezoneOffset()/60);
    var minute = d.getMinutes();

    var minutesPattern = pad(minute) + '|' + pad(minute-1) + '|' + pad(minute-2) +
                '|' + pad(minute-3) + '|' + pad(minute-4)  + '|' + pad(minute-5);

    var pattern = new RegExp('(\\[' + year + '-' + month + '-' +
            day + ' ' + hour + ':(' + minutesPattern + '):\\d+\.\\d+ GMT\\])', 'gm');

    text = text.replace(/(^\[.+?\])/gm, '

$1');
    text = text.replace(pattern, '(NEW) $1');
    text = text.replace(/(WARN|warning)/gm, '$1');
    text = text.replace(/(ERROR)/gm, '$1');
    text = text.replace(/(Sites\-(\w+-)?Site)/gm, '$1');
    text = text.replace(/(\/\w[^ ]+?\.[a-z]+)/gmi, '$1');
    text = text.replace(/(\/\w+\.[a-z]+)/gmi, '$1');
    text = text.replace(/(^\tat.+$)/gmi, '$1');
    text = text.replace(/((\#|lineNumber: |line )\d+)/gmi, '$1');
    text = text.replace(/(null|TypeError|ReferenceError)/gmi, '$1');

    $el.addClass('language-log')
        .html('

DW LOGS
' + text + '
');

    // scroll to the bottom of the document
    $(window).on('load', function () {
        $("html, body").animate({ scrollTop: $(document).height() }, 500);
    });

    function pad(number) {
        return ('0' + number).slice(-2);
    }

})();
<|endoftext|>


<commit_before><commit_msg>Fix sensor nudges.<commit_after><|endoftext|>


<commit_before>var test = require('tap').test,
    functions = require(__dirname + '/../../lib/functions.js');

var dimensions = [10, 20, 30];

test('optimum', function(t) {
	 for (var i in dimensions) {
	     var x = [];
	     for ( var j = 0; j < dimensions[i]; j++) {
		 x.push(0);
	     }
	     t.equal( functions.ackley(x), 0, "Optimum for dimension "+ dimensions[i] + " OK" );
     }
	 t.end();
});

test("l-trap", function(t) {
	 var a = 1,
	 b = 2;
	 var params3 = [3,a,b,2];
	 var subjects3= { '111': b,
			  '000': a,
			  '011': 0,
			  '110': 0};
	 test_trap( t, params3, subjects3);
	 var params4 = [4,a,b,3];
	 var subjects4= { '1111': b,
			  '0000': a,
			  '0111': 0,
			  '1110': 0};
	 test_trap( t, params4, subjects4);
	 t.end();
});

test("MMDP", function(t) {
	 var many_mmdp ='';
	 var sum = 0;
	 var subjects= { '111111': 1,
			  '000000111111': 2,
			  '000001': 0,
			  '100001': 0.360384,
			  '101001': 0.640576};
	 for ( var i in subjects ) {
	     many_mmdp +=i;
	     sum += subjects[i];
	     t.equal( functions.MMDP(i), subjects[i], "mmdp " + i + " = " + subjects[i]);
	 }
	 t.equal( functions.MMDP(many_mmdp), sum, "Many MMDP");

	 t.end();
});

function test_trap(t, params, subjects ) {
    var number_of_bits = params[0],
    a = params[1], b = params[2], z  = params[3];
    console.log( params );
    var many_traps = '';
    var sum = 0;
    for ( var i in subjects ) {
	many_traps +=i;
	sum += subjects[i];
	t.equal( functions.ltrap(i, number_of_bits, a, b, z ), subjects[i], "ltrap " + i + " = " + subjects[i]);
    }

    t.equal( functions.ltrap(many_traps, number_of_bits, a, b, z ), sum, "Many l-traps");

}

<commit_msg>First tests with mocha<commit_after>'use strict';
var assert = require("assert"),
functions = require("../../lib/functions");

suite('Functions', function() {
    var dimensions = [10, 20, 30];

    for (var i in dimensions) {
	test("Testing for dimension " + dimensions[i], function(){
	    var x = [];
	    for ( var j = 0; j < dimensions[i]; j++) {
		x.push(0);
	    }
	    assert.equal( functions.ackley(x), 0, "Optimum for dimension "+ dimensions[i] + " OK" );
	});
    }

});

/*

test("l-trap", function(t) {
	 var a = 1,
	 b = 2;
	 var params3 = [3,a,b,2];
	 var subjects3= { '111': b,
			  '000': a,
			  '011': 0,
			  '110': 0};
	 test_trap( t, params3, subjects3);
	 var params4 = [4,a,b,3];
	 var subjects4= { '1111': b,
			  '0000': a,
			  '0111': 0,
			  '1110': 0};
	 test_trap( t, params4, subjects4);
	 t.end();
});

test("MMDP", function(t) {
	 var many_mmdp ='';
	 var sum = 0;
	 var subjects= { '111111': 1,
			  '000000111111': 2,
			  '000001': 0,
			  '100001': 0.360384,
			  '101001': 0.640576};
	 for ( var i in subjects ) {
	     many_mmdp +=i;
	     sum += subjects[i];
	     t.equal( functions.MMDP(i), subjects[i], "mmdp " + i + " = " + subjects[i]);
	 }
	 t.equal( functions.MMDP(many_mmdp), sum, "Many MMDP");

	 t.end();
});

function test_trap(t, params, subjects ) {
    var number_of_bits = params[0],
    a = params[1], b = params[2], z  = params[3];
    console.log( params );
    var many_traps = '';
    var sum = 0;
    for ( var i in subjects ) {
	many_traps +=i;
	sum += subjects[i];
	t.equal( functions.ltrap(i, number_of_bits, a, b, z ), subjects[i], "ltrap " + i + " = " + subjects[i]);
    }

    t.equal( functions.ltrap(many_traps, number_of_bits, a, b, z ), sum, "Many l-traps");

}

*/
<|endoftext|>


<commit_before>import React from 'react';

import { Sparklines, SparklinesLine, SparklinesSpots } from 'react-sparklines';

const max = data => Math.max.apply(Math, data);
const min = data => Math.min.apply(Math, data);
const ypos = (data, val) => ((val - min(data)) / (max(data) - min(data)) * 120);
const history = data => data.map(x => x.quote);

const TickTradeSparkline = (props) => {
	const height = props.height || 100;
	const width = props.width || 344;
	const h = history(props.history);
	const y = (height - ypos(h, h[h.length - 1])) || height;

	const widthPerTick = 18;

	return (

			<Sparklines
				width={width}
				height={height}
				data={h}
				limit={Math.round(width / widthPerTick)}
				{...props}>
				<SparklinesLine />
				<SparklinesSpots />
				<line
					x1={0} y1={y} x2={width} y2={y}
					style={{ stroke: 'green', strokeOpacity: 0.75, strokeDasharray: 'none' }} />
				<rect
					x={0} y={(props.showBarrier ? y - height : y)}
					style={{ fill: 'green', fillOpacity: 0.1 }} />
			</Sparklines>

	);
};

TickTradeSparkline.propTypes = {
	history: React.PropTypes.array,
	showBarrier: React.PropTypes.bool,
	width: React.PropTypes.number,
	height: React.PropTypes.number,
};

TickTradeSparkline.defaultProps = {
	history: [],
};

export default TickTradeSparkline;
<commit_msg>Use defaultProps for default values<commit_after>import React from 'react';

import { Sparklines, SparklinesLine, SparklinesSpots } from 'react-sparklines';

const max = data => Math.max.apply(Math, data);
const min = data => Math.min.apply(Math, data);
const ypos = (data, val) => ((val - min(data)) / (max(data) - min(data)) * 120);
const history = data => data.map(x => x.quote);

const TickTradeSparkline = (props) => {
	const height = props.height;
	const width = props.width;
	const h = history(props.history);
	const y = (height - ypos(h, h[h.length - 1])) || height;

	return (

			<Sparklines
				width={width}
				height={height}
				data={h}
				limit={20}
				{...props}>
				<SparklinesLine />
				<SparklinesSpots />
				<line
					x1={0} y1={y} x2={width} y2={y}
					style={{ stroke: 'green', strokeOpacity: 0.75, strokeDasharray: 'none' }} />
				<rect
					x={0} y={(props.showBarrier ? y - height : y)}
					style={{ fill: 'green', fillOpacity: 0.1 }} />
			</Sparklines>

	);
};

TickTradeSparkline.propTypes = {
	history: React.PropTypes.array,
	showBarrier: React.PropTypes.bool,
	width: React.PropTypes.number,
	height: React.PropTypes.number,
};

TickTradeSparkline.defaultProps = {
	history: [],
	width: 344,
	height: 100,
};

export default TickTradeSparkline;
<|endoftext|>


<commit_before>module('lively.ide.tools.SystemConsole').requires('lively.persistence.BuildSpec').toRun(function() {

lively.BuildSpec('lively.ide.tools.SystemConsole', {
    _Extent: lively.pt(493.0,234.0),
    className: "lively.morphic.Window",
    contentOffset: lively.pt(3.0,22.0),
    draggingEnabled: true,
    name: "SystemConsole",
    layout: {adjustForNewBounds: true},
    submorphs: [{
        _BorderColor: Color.rgb(95,94,95),
        _ClipMode: { x: "hidden", y: "scroll" },
        _Extent: lively.pt(487.0,209.0),
        _Fill: Color.rgb(255,255,255),
        _FontSize: 10,
        _Position: lively.pt(3.0,22.0),
        _StyleSheet: ".list-item.error {\n\
    	color: red !important;\n\
    }\n\
    \n\
    .list-item.warn {\n\
    	color: orange !important;\n\
    }\n\
    \n\
    .list-item.new-log-item {\n\
    	font-weight: bold;\n\
    }\n\
    .list-item.log {\n\
    }",
        className: "lively.morphic.List",
        droppingEnabled: true,
        grabbingEnabled: false,
        isMultipleSelectionList: true,
        itemMorphs: [],
        layout: {
            adjustForNewBounds: true,
            extent: lively.pt(487.0,209.0),
            listItemHeight: 19,
            maxExtent: lively.pt(487.0,209.0),
            maxListItems: 11,
            noOfCandidatesShown: 1,
            padding: 0,
            resizeHeight: true,
            resizeWidth: true
        },
        multipleSelectionMode: "multiSelectWithShift",
        name: "SystemConsole",
        sourceModule: "lively.morphic.Lists",

        clear: function clear() {
            this.setList([]);
        },

        editItems: function editItems(items) {
            items.pluck('value').map(function(v) {
                $world.addCodeEditor({
                    title: 'log item ' + new Date(v.time),
                    content: v.string,
                    textMode: 'text'
                }).getWindow().comeForward();
            });
        },

        install: function install() {
            this.installConsoleWrapper();
            this.installErrorCapture();
        },

        installConsoleWrapper: function installConsoleWrapper() {
            var c = Global.console;

            this.warn = this.wrapperFunc('warn');
            this.error = this.wrapperFunc('error');
            this.log = this.wrapperFunc('log');

            if (c.consumers && !c.consumers.include(this)) c.addConsumer(this);
        },

        installErrorCapture: function installErrorCapture() {
            // window.removeEventListener('error', errorHandler)

            if (this._errorHandler) return;

            this._errorHandler = (function errorHandler(errEvent, url, lineNumber, column, errorObj) {
                var err = errEvent.error || err;
                if (err.stack) {
                    var string = String(err.stack)
                    console.error("%s", string.replace(/\n/g, ''));
                } else
                    console.error("%s  %s:%s", err, url, lineNumber);
            }).bind(this);

            window.addEventListener('error', this._errorHandler);
        },

        morphMenuItems: function morphMenuItems() {
            var items = $super(),
                c = lively.Config,
                logsVerbose = c.get("verboseLogging");
            return items.concat([
                ['clear', this.clear.bind(this)],
                ['[' + (logsVerbose ? 'x' : ' ') + '] allow message popups', toggleVerboseLogging]
            ]);

            function toggleVerboseLogging() {
                c.set("verboseLogging", !logsVerbose);
            }
        },

        onDoubleClick: function onDoubleClick(evt) {
            var items = this.getSelectedItems()
            if (!items || !items.length) return false;
            this.editItems(items);
            evt.stop();
            return true;
        },

        onFromBuildSpecCreated: function onFromBuildSpecCreated() {
            $super();
            console.log('System console started successfully.');
        },

        onKeyDown: function onKeyDown(evt) {
            var s = evt.getKeyString();
            if (s === "Enter") {
                var items = this.getSelectedItems();
                items.length && this.editItems(items);
                evt.stop(); return true;
            }
            return $super(evt);
        },

        onLoad: function onLoad() {
            this.clear();
            this.installConsoleWrapper();
        },

        onLoadFromPartsBin: function onLoadFromPartsBin() {
            this.onLoad();
            console.log('System console started successfully.');
        },

        onOwnerChanged: function onOwnerChanged(newOwner) {
            this[this.world() ? 'install' : 'uninstall']();
        },

        onWindowGetsFocus: function onWindowGetsFocus() {
            this.world() && this.focus();
        },

        reset: function reset() {
            this.enableMultipleSelections('multiSelectWithShift');
            this.uninstall();
            this.clear();
            this.getWindow().setTitle('System Console');
            this.getWindow().name = "SystemConsole";
            // this.partsBinMetaInfo = meta
        },

        uninstall: function uninstall() {
            this.uninstallConsoleWrapper();
            this.uninstallErrorCapture();
        },

        uninstallConsoleWrapper: function uninstallConsoleWrapper() {
            console.consumers.remove(this);
        },

        uninstallErrorCapture: function uninstallErrorCapture() {
            if (!this._errorHandler) return;
            window.removeEventListener('error', this._errorHandler);
            delete this._errorHandler;
        },

        wrapperFunc: function wrapperFunc(type) {

        var list = this;

        return function consoleWrapper(/*args*/) {
            var string = String(arguments[0]);
            for (var i = 1; i < arguments.length; i++) {
                var idx = string.indexOf('%s');
                if (idx > -1) string = string.slice(0,idx) + String(arguments[i]) + string.slice(idx+2);
            }

            var oneLine = string.replace(/\n/g, '');

            keepScrollOrScrollDownAfter(function() {
                var last = list.getList().last()
                var repeated = repeatEntry(oneLine, last);
                if (repeated) {
                    list.removeItemOrValue(last);
                    oneLine = repeated;
                };

                list.addItem({
                    isListItem: true,
                    string: oneLine,
                    value: {string: string, time: Date.now()},
                    cssClassNames: [type, 'new-log-item']
                });

                unemphasizeOldItems();
            });
        }

        // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

        function repeatEntry(string, item) {
            if (!item) return null;
            var repeatRe = /^[0-9]+x\s*/,
                repeatMatch = item.string.match(repeatRe);
            if (repeatMatch && repeatMatch[0]) {
                var repeat = parseInt(repeatMatch[0]);
                var itemString = item.string.replace(repeatRe, '');
            } else {
                var repeat = 1;
                var itemString = item.string;
            }

            return !isNaN(repeat) && itemString === string ?
                (repeat + 1) + 'x ' + string : null;
        }

        function keepScrollOrScrollDownAfter(func) {
            if (!list.world()) { func(); return; }

            var maxScroll = list.getMaxScrollExtent().y;
            var scroll = list.getScroll();
            var scrollDown = scroll[1] >= maxScroll - 10;

            func();

            if (scrollDown) list.scrollToBottom();
            else list.setScroll(scroll[0], scroll[1])
        }

        function unemphasizeOldItems() {
            var now = Date.now();
            var old = 1000*10;
            list.getList()
                .filter(function(ea) { return now - ea.value.time > old; })
                .forEach(function(ea) { ea.cssClassNames.remove('new-log-item'); })
        }
    },

    }],
    titleBar: "System Console"
});

Object.extend(lively.ide.tools.SystemConsole, {
    open: function() {
        return lively.BuildSpec('lively.ide.tools.SystemConsole')
            .createMorph().openInWorld($world.positionForNewMorph()).comeForward();
    }
});

}) // end of module
<commit_msg>System Console: Fixing bug #270 (cutoff at right margin)<commit_after>module('lively.ide.tools.SystemConsole').requires('lively.persistence.BuildSpec').toRun(function() {

lively.BuildSpec('lively.ide.tools.SystemConsole', {
    _Extent: lively.pt(493.0,234.0),
    className: "lively.morphic.Window",
    contentOffset: lively.pt(3.0,22.0),
    draggingEnabled: true,
    name: "SystemConsole",
    layout: {adjustForNewBounds: true},
    submorphs: [{
        _BorderColor: Color.rgb(95,94,95),
        _ClipMode: "scroll",
        _Extent: lively.pt(487.0,209.0),
        _Fill: Color.rgb(255,255,255),
        _FontSize: 10,
        _Position: lively.pt(3.0,22.0),
        _StyleSheet: ".list-item.error {\n\
    	color: red !important;\n\
    }\n\
    \n\
    .list-item.warn {\n\
    	color: orange !important;\n\
    }\n\
    \n\
    .list-item.new-log-item {\n\
    	font-weight: bold;\n\
    }\n\
    .list-item.log {\n\
    }",
        className: "lively.morphic.List",
        droppingEnabled: true,
        grabbingEnabled: false,
        isMultipleSelectionList: true,
        itemMorphs: [],
        layout: {
            adjustForNewBounds: true,
            extent: lively.pt(487.0,209.0),
            listItemHeight: 19,
            maxExtent: lively.pt(487.0,209.0),
            maxListItems: 11,
            noOfCandidatesShown: 1,
            padding: 0,
            resizeHeight: true,
            resizeWidth: true
        },
        multipleSelectionMode: "multiSelectWithShift",
        name: "SystemConsole",
        sourceModule: "lively.morphic.Lists",

        clear: function clear() {
            this.setList([]);
        },

        editItems: function editItems(items) {
            items.pluck('value').map(function(v) {
                $world.addCodeEditor({
                    title: 'log item ' + new Date(v.time),
                    content: v.string,
                    textMode: 'text'
                }).getWindow().comeForward();
            });
        },

        install: function install() {
            this.installConsoleWrapper();
            this.installErrorCapture();
        },

        installConsoleWrapper: function installConsoleWrapper() {
            var c = Global.console;

            this.warn = this.wrapperFunc('warn');
            this.error = this.wrapperFunc('error');
            this.log = this.wrapperFunc('log');

            if (c.consumers && !c.consumers.include(this)) c.addConsumer(this);
        },

        installErrorCapture: function installErrorCapture() {
            // window.removeEventListener('error', errorHandler)

            if (this._errorHandler) return;

            this._errorHandler = (function errorHandler(errEvent, url, lineNumber, column, errorObj) {
                var err = errEvent.error || err;
                if (err.stack) {
                    var string = String(err.stack)
                    console.error("%s", string.replace(/\n/g, ''));
                } else
                    console.error("%s  %s:%s", err, url, lineNumber);
            }).bind(this);

            window.addEventListener('error', this._errorHandler);
        },

        morphMenuItems: function morphMenuItems() {
            var items = $super(),
                c = lively.Config,
                logsVerbose = c.get("verboseLogging");
            return items.concat([
                ['clear', this.clear.bind(this)],
                ['[' + (logsVerbose ? 'x' : ' ') + '] allow message popups', toggleVerboseLogging]
            ]);

            function toggleVerboseLogging() {
                c.set("verboseLogging", !logsVerbose);
            }
        },

        onDoubleClick: function onDoubleClick(evt) {
            var items = this.getSelectedItems()
            if (!items || !items.length) return false;
            this.editItems(items);
            evt.stop();
            return true;
        },

        onFromBuildSpecCreated: function onFromBuildSpecCreated() {
            $super();
            console.log('System console started successfully.');
        },

        onKeyDown: function onKeyDown(evt) {
            var s = evt.getKeyString();
            if (s === "Enter") {
                var items = this.getSelectedItems();
                items.length && this.editItems(items);
                evt.stop(); return true;
            }
            return $super(evt);
        },

        onLoad: function onLoad() {
            this.clear();
            this.installConsoleWrapper();
        },

        onLoadFromPartsBin: function onLoadFromPartsBin() {
            this.onLoad();
            console.log('System console started successfully.');
        },

        onOwnerChanged: function onOwnerChanged(newOwner) {
            this[this.world() ? 'install' : 'uninstall']();
        },

        onWindowGetsFocus: function onWindowGetsFocus() {
            this.world() && this.focus();
        },

        reset: function reset() {
            this.enableMultipleSelections('multiSelectWithShift');
            this.uninstall();
            this.clear();
            this.getWindow().setTitle('System Console');
            this.getWindow().name = "SystemConsole";
            // this.partsBinMetaInfo = meta
        },

        setupScroll: function setupScroll(noOfItems, layout) {
            $super(noOfItems, layout);
            this.setClipMode('scroll');
        },

        uninstall: function uninstall() {
            this.uninstallConsoleWrapper();
            this.uninstallErrorCapture();
        },

        uninstallConsoleWrapper: function uninstallConsoleWrapper() {
            console.consumers.remove(this);
        },

        uninstallErrorCapture: function uninstallErrorCapture() {
            if (!this._errorHandler) return;
            window.removeEventListener('error', this._errorHandler);
            delete this._errorHandler;
        },

        wrapperFunc: function wrapperFunc(type) {

        var list = this;

        return function consoleWrapper(/*args*/) {
            var string = String(arguments[0]);
            for (var i = 1; i < arguments.length; i++) {
                var idx = string.indexOf('%s');
                if (idx > -1) string = string.slice(0,idx) + String(arguments[i]) + string.slice(idx+2);
            }

            var oneLine = string.replace(/\n/g, '');

            keepScrollOrScrollDownAfter(function() {
                var last = list.getList().last()
                var repeated = repeatEntry(oneLine, last);
                if (repeated) {
                    list.removeItemOrValue(last);
                    oneLine = repeated;
                };

                list.addItem({
                    isListItem: true,
                    string: oneLine,
                    value: {string: string, time: Date.now()},
                    cssClassNames: [type, 'new-log-item']
                });

                unemphasizeOldItems();
            });
        }

        // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

        function repeatEntry(string, item) {
            if (!item) return null;
            var repeatRe = /^[0-9]+x\s*/,
                repeatMatch = item.string.match(repeatRe);
            if (repeatMatch && repeatMatch[0]) {
                var repeat = parseInt(repeatMatch[0]);
                var itemString = item.string.replace(repeatRe, '');
            } else {
                var repeat = 1;
                var itemString = item.string;
            }

            return !isNaN(repeat) && itemString === string ?
                (repeat + 1) + 'x ' + string : null;
        }

        function keepScrollOrScrollDownAfter(func) {
            if (!list.world()) { func(); return; }

            var maxScroll = list.getMaxScrollExtent().y;
            var scroll = list.getScroll();
            var scrollDown = scroll[1] >= maxScroll - 10;

            func();

            if (scrollDown) list.scrollToBottom();
            else list.setScroll(scroll[0], scroll[1])
        }

        function unemphasizeOldItems() {
            var now = Date.now();
            var old = 1000*10;
            list.getList()
                .filter(function(ea) { return now - ea.value.time > old; })
                .forEach(function(ea) { ea.cssClassNames.remove('new-log-item'); })
        }
    },

    }],
    titleBar: "System Console"
});

Object.extend(lively.ide.tools.SystemConsole, {
    open: function() {
        return lively.BuildSpec('lively.ide.tools.SystemConsole')
            .createMorph().openInWorld($world.positionForNewMorph()).comeForward();
    }
});

}) // end of module
<|endoftext|>


<commit_before>/*
===============================================================================

    Class defines UI: HUD (head-up display) with player stats and menu GUI.

===============================================================================
*/
function UI() {
    if ( !(this instanceof UI) ) return new UI();

    this.camera = new THREE.OrthographicCamera( DOA.Settings.width  / - 2, DOA.Settings.width  /   2,
                                                DOA.Settings.height /   2, DOA.Settings.height / - 2,
                                                DOA.Settings.minView, DOA.Settings.maxView );
    /*
     * If camera rotation on Y is 0, not PI radian, all objects visible by
     * camera must have negative Z coordinates. In this case, the backside
     * of the object is visible only, and Material.side should be set to
     * THREE.DoubleSide, so the object can be drawn.
     */
    this.camera.rotateY( Math.PI );

    this.scene = new THREE.Scene();

    this.menu = null;
}

/*
================
init
    Creates objects of user interface.
================
*/
UI.prototype.init = function () {
    // Interface

    // Menu
    this.menu = new dat.GUI();
    this.menu.domElement.style.display = 'none';
    this.buildSettingsMenu();
};

/*
================
updateSize
    Updates camera size and projection in accordance with window size.
================
*/
UI.prototype.updateSize = function () {
    this.camera.left   = DOA.Settings.width  / - 2;
    this.camera.right  = DOA.Settings.width  /   2;
    this.camera.top    = DOA.Settings.height /   2;
    this.camera.bottom = DOA.Settings.height / - 2;
    this.camera.updateProjectionMatrix();
};

/*
================
updateHudSize
    Updates HUD elements texture size.
================
*/
UI.prototype.updateHud = function () {
};

/*
================
clearMenu
    Removes all elements from the menu recursively.
================
*/
UI.prototype.clearMenu = function ( menu ) {
    menu = menu || this.menu;
    var k;

    for ( k in menu.__controllers ) {
        menu.remove( menu.__controllers[ k ] );
        delete menu.__controllers[ k ];
        delete menu.__listening[ k ];
    }

    menu.__controllers = [];
    menu.__listening = [];

    for ( k in menu.__folders ) {
        UI.prototype.clearMenu( menu.__folders[ k ] );
        menu.__folders[ k ].domElement.parentNode.remove();
        delete menu.__folders[ k ];
    }
};

/*
================
resetMenu
    Resets menu values to the remembered ones.
================
*/
UI.prototype.resetMenu = function () {
    try {
        this.menu.revert();
    } catch ( ex ) {
        // Cannot read property 'selectedIndex' of undefined
    }
};

/*
================
buildSettingsMenu
    Creates new set of controllers, based on DOA.Settings.
================
*/
UI.prototype.buildSettingsMenu = function () {
    this.clearMenu();
    var folder = this.menu.addFolder( 'Common' );
    folder.add( DOA.Settings, 'fps', [ 30, 60 ] ).name( 'fps counter' ).listen();
    folder.addColor( DOA.Settings.colors, 'mesh' ).name( 'blank color' ).listen();
    folder.open();

    folder = this.menu.addFolder( 'Graphics' );
    folder.add( DOA.Settings, 'minView', 0.1, 1.0 ).step( 0.1 ).name( 'min view' ).listen();
    folder.add( DOA.Settings, 'maxView', 100, 9000 ).step( 100 ).name( 'max view' ).listen();
    folder.add( DOA.Settings, 'fov', 30, 120 ).step( 15 ).name( 'filed of view' ).listen();
    folder.add( DOA.Settings, 'anisotropy', 1, 16 ).step( 1 ).name( 'anisotropy' ).listen();
    folder.open();

    folder = this.menu.addFolder( 'Player' );
    folder.add( DOA.Settings, 'mouseSensitivity', 0.05, 0.5 ).step( 0.05 ).name( 'mouse speed' ).listen();
    folder.add( DOA.Settings, 'hudSize', { normal : 32, big : 64, large : 128 } ).name( 'HUD size' ).listen();
    folder.add( DOA.Settings, 'hudOpacity', 0.0, 1.0 ).step( 0.01 ).name( 'HUD opacity' ).listen();
    folder.open();

    this.menu.add( DOA.UI, 'resetMenu' ).name( 'Reset' );
    this.menu.add( DOA.Settings, 'quickSave' ).name( 'Save' );
    this.menu.add( DOA.Settings, 'quickLoad' ).name( 'Load' );
};

/*
---------------------------------------------------------------------------
DOA
---------------------------------------------------------------------------
*/
DOA.UI = new UI();
<commit_msg>Update code style.<commit_after>/*
===============================================================================

    Class defines UI: HUD (head-up display) with player stats and menu GUI.

===============================================================================
*/
function UI() {
    if ( !(this instanceof UI) ) return new UI();

    this.camera = new THREE.OrthographicCamera( DOA.Settings.width  / -2, DOA.Settings.width  /  2,
                                                DOA.Settings.height /  2, DOA.Settings.height / -2,
                                                DOA.Settings.minView, DOA.Settings.maxView );
    /*
     * If camera rotation on Y is 0, not PI radian, all objects visible by
     * camera must have negative Z coordinates. In this case, the backside
     * of the object is visible only, and Material.side should be set to
     * THREE.DoubleSide, so the object can be drawn.
     */
    this.camera.rotateY( Math.PI );

    this.scene = new THREE.Scene();

    this.menu = null;
}

/*
================
init
    Creates objects of user interface.
================
*/
UI.prototype.init = function () {
    // Interface

    // Menu
    this.menu = new dat.GUI();
    this.menu.domElement.style.display = 'none';
    this.buildSettingsMenu();
};

/*
================
updateSize
    Updates camera size and projection in accordance with window size.
================
*/
UI.prototype.updateSize = function () {
    this.camera.left   = DOA.Settings.width  / - 2;
    this.camera.right  = DOA.Settings.width  /   2;
    this.camera.top    = DOA.Settings.height /   2;
    this.camera.bottom = DOA.Settings.height / - 2;
    this.camera.updateProjectionMatrix();
};

/*
================
updateHudSize
    Updates HUD elements texture size.
================
*/
UI.prototype.updateHud = function () {
};

/*
================
clearMenu
    Removes all elements from the menu recursively.
================
*/
UI.prototype.clearMenu = function ( menu ) {
    menu = menu || this.menu;
    var k;

    for ( k in menu.__controllers ) {
        menu.remove( menu.__controllers[ k ] );
        delete menu.__controllers[ k ];
        delete menu.__listening[ k ];
    }

    menu.__controllers = [];
    menu.__listening = [];

    for ( k in menu.__folders ) {
        UI.prototype.clearMenu( menu.__folders[ k ] );
        menu.__folders[ k ].domElement.parentNode.remove();
        delete menu.__folders[ k ];
    }
};

/*
================
resetMenu
    Resets menu values to the remembered ones.
================
*/
UI.prototype.resetMenu = function () {
    try {
        this.menu.revert();
    } catch ( ex ) {
        // Cannot read property 'selectedIndex' of undefined
    }
};

/*
================
buildSettingsMenu
    Creates new set of controllers, based on DOA.Settings.
================
*/
UI.prototype.buildSettingsMenu = function () {
    this.clearMenu();
    var folder = this.menu.addFolder( 'Common' );
    folder.add( DOA.Settings, 'fps', [ 30, 60 ] ).name( 'fps counter' ).listen();
    folder.addColor( DOA.Settings.colors, 'mesh' ).name( 'blank color' ).listen();
    folder.open();

    folder = this.menu.addFolder( 'Graphics' );
    folder.add( DOA.Settings, 'minView', 0.1, 1.0 ).step( 0.1 ).name( 'min view' ).listen();
    folder.add( DOA.Settings, 'maxView', 100, 9000 ).step( 100 ).name( 'max view' ).listen();
    folder.add( DOA.Settings, 'fov', 30, 120 ).step( 15 ).name( 'filed of view' ).listen();
    folder.add( DOA.Settings, 'anisotropy', 1, 16 ).step( 1 ).name( 'anisotropy' ).listen();
    folder.open();

    folder = this.menu.addFolder( 'Player' );
    folder.add( DOA.Settings, 'mouseSensitivity', 0.05, 0.5 ).step( 0.05 ).name( 'mouse speed' ).listen();
    folder.add( DOA.Settings, 'hudSize', { normal : 32, big : 64, large : 128 } ).name( 'HUD size' ).listen();
    folder.add( DOA.Settings, 'hudOpacity', 0.0, 1.0 ).step( 0.01 ).name( 'HUD opacity' ).listen();
    folder.open();

    this.menu.add( DOA.UI, 'resetMenu' ).name( 'Reset' );
    this.menu.add( DOA.Settings, 'quickSave' ).name( 'Save' );
    this.menu.add( DOA.Settings, 'quickLoad' ).name( 'Load' );
};

/*
---------------------------------------------------------------------------
DOA
---------------------------------------------------------------------------
*/
DOA.UI = new UI();
<|endoftext|>