<commit_before>
/****************************
          Map.js
 ****************************/

// Iterate through, and place layers onto Leaflet map
function addLayers(layers){

  // Map Boundaries
  bounds = leaflet_map.getBounds();
  topLeft = leaflet_map.latLngToLayerPoint(bounds.getNorthWest());
  bottomRight = leaflet_map.latLngToLayerPoint(bounds.getSouthEast());

  // Clear map just to be safe
  // d3.select('#overlay').remove();

  // Iterate through layers
	for (var i = layers.length - 1; i >= 0; i--) {

    var layer = layers[i]; // Current Layer

    // Create unique ID for current layer
    layer.id = layer.name.replace(/\s/g, '').toLowerCase();

    // @ TODO:
    // Prevent Duplicates

		if (layer.type == "scatterplot"){
			drawScatterplot(leaflet_map, layer);
		}

		if (layer.type == "path"){
      layer.path = true;
      drawScatterplot(leaflet_map, layer);
		}

		if (layer.type == "heatmap"){
			var layer = drawHeatmap(leaflet_map,layer)

      // Prevent multiple heatmaps from overlaying.
      d3.select(".leaflet-overlay-pane canvas").remove();

      leaflet_map.addLayer(layer);
		}

    if (layer.type == "hex"){
      drawHexmap(leaflet_map, layer);
    }
	};
}

/****************************
        Scatterplot
 ****************************/

// Plot Points as a scatterplot
// http://bost.ocks.org/mike/leaflet/
// chriszetter.com/blog/2014/06/15/building-a-voronoi-map-with-d3-and-leaflet/
function drawScatterplot(map, layer){

    // Clear layer if previously existing.
    d3.select('#' + layer.id).remove();

    // Select leaflet's 'overlay pane' layer. Leaflet will
    // auto-repositions the overlay panes upon map movement.

    // Create an SVG elemnt for plotting points on
    var svg = d3.select(map.getPanes().overlayPane).append("svg")
      .attr('id', layer.id)
      .attr("class", "leaflet-zoom-hide")

    // Fix the size of our SVG layer to match the leaflet map
      .style("width",  map.getSize().x + 'px')
      .style("height", map.getSize().y + 'px')

    // Add a "g" (group) element. Organizes points
    // and ensures that layer aligns with leaflet.
    var g = svg.append("g")

    // Apply leaflet-zoom-hide so that the overlay
    // is hidden during zoom animations
      .attr("class", "leaflet-zoom-hide");

    // Create map-able set of points. For each point,
    // convert the lat/long into a plottable x/y position
    var points = layer.data.filter(function(p) {

      // Check for missing data points
      if (!p.latitude || !p.longitude){
        console.log("ERROR. Missing Latitude/Longitude Data.");
        return false;
      }

      // Create new leaflet Lat/Long Object
      var latlng = new L.LatLng(p.latitude, p.longitude);

      // Remove points that are outside current viewport
      if (!bounds.contains(latlng)) { return false };

      // Convert Latitude and Longitude into a Mapable
      // point using leaflet's LayerPoint API.
      var point = map.latLngToLayerPoint(latlng);

      // Save the resulting x & y values
      // onto the current point object.
      p.x = point.x;
      p.y = point.y;

      return true;
    });

    // Create a group for this layer
    var svgPoints = g.attr("class", "points")
      .selectAll("g")

      // Append a <g class="point"> for
      // ever data point in the set.
      .data(points)
      .enter().append("g")
      .attr("class", "point")
      .style("z-index", 999);

    // Add circles for each point
    svgPoints.append("circle")

      // Position each circle with the x/y position.
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })

      // Visual Settings
      .style('fill', function(d) { return layer.color } )
      .attr("r", layer.width)
      .attr("opacity", 1);

      // .attr("date", function(d) { return d.date })
      // .attr("pointer-events", "all")

    if (layer.path){

      for (var i = 0; i < points.length - 1; i++) {

        // Stop iteration if there's not
        // a next point to connect.
        if (i >= points.length - 2) return;

        var current = points[i];
        var next = points[i + 1];

        svgPoints.append("line")
          .attr("x1", current.x)
          .attr("y1", current.y)
          .attr("x2", next.x)
          .attr("y2", next.y)
          .style("stroke", layer.color)
          .style("stroke-width", layer.width * 2)
          .style("opacity", 1);

      };

    }

};

/****************************
          Path
 ****************************/

// function drawPath(map, layer){
// 	// Enable path
// 	layer.pathing = true;

//   console.log(layer)

// 	// Render Layer
// 	drawPoints(map, layer);
// };

/****************************
         Heatmap
 ****************************/

// WebGL Heatmap Implementation:
// https://github.com/ursudio/webgl-heatmap-leaflet
// Returns a leaflet layer
function drawHeatmap(map, layer){

	var heatmap = new L.TileLayer.WebGLHeatMap({
    	size: 500,
    	autoresize: true,
    	opacity: .4,
  	});

	var dataPoints = [];

	for (var i = layer.data.length - 1; i >= 0; i--) {
		var point = layer.data[i]
		dataPoints.push([point.latitude, point.longitude, point.value / 40000]);
	};

	heatmap.setData(dataPoints);

	return heatmap;
}

function drawHexmap(map, layer){

    // Options for the hexbin layer
    var hexSettings = {
        radius : 10,                            // Size of the hexagons/bins
        opacity: 0.5,                           // Opacity of the hexagonal layer
        duration: 200,                          // millisecond duration of d3 transitions (see note below)
        lng: function(d){ return d[0]; },       // longitude accessor
        lat: function(d){ return d[1]; },       // latitude accessor
        value: function(d){ return d.length; }, // value accessor - derives the bin value
        valueFloor: 0,                          // override the color scale domain low value
        valueCeil: undefined,                   // override the color scale domain high value
        colorRange: ['#f7fbff', '#08306b']      // default color range for the heat map
    };

    // Create the hexbin layer and add it to the map
    var hexLayer = L.hexbinLayer(hexSettings).addTo(map);

    // Optionally, access the d3 color scale directly
    // Can also set scale via hexLayer.colorScale(d3.scale.linear()...)
    hexLayer.colorScale().range('white', 'blue');

    var center = [42.329077, -71.108871];

    var latFn = d3.random.normal(center[0], 1);
    var longFn = d3.random.normal(center[1], 1);

    var data = [];

    for(i=0; i<1000; i++){
        data.push([longFn(),  latFn(), Math.random()]);
    }

    // Set the data (can be set multiple times)
    hexLayer.data(data);
}
<commit_msg>Comment un-intuitive functions<commit_after>
/****************************
          Map.js
 ****************************/

// Iterate through, and place layers onto Leaflet map
function addLayers(layers){

  // Map Boundaries
  bounds = leaflet_map.getBounds();
  topLeft = leaflet_map.latLngToLayerPoint(bounds.getNorthWest());
  bottomRight = leaflet_map.latLngToLayerPoint(bounds.getSouthEast());

  // Clear map just to be safe
  // d3.select('#overlay').remove();

  // Iterate through layers
	for (var i = layers.length - 1; i >= 0; i--) {

    var layer = layers[i]; // Current Layer

    // Create unique ID for current layer
    layer.id = layer.name.replace(/\s/g, '').toLowerCase();

    // @ TODO:
    // Prevent Duplicates

		if (layer.type == "scatterplot"){
			drawScatterplot(leaflet_map, layer);
		}

		if (layer.type == "path"){
      layer.path = true;

      // Currently utilized same functionality as
      // scatterploy. @ TODO Fix this.
      drawScatterplot(leaflet_map, layer);
		}

		if (layer.type == "heatmap"){
			var layer = drawHeatmap(leaflet_map,layer)

      // Prevent multiple heatmaps from overlaying.
      d3.select(".leaflet-overlay-pane canvas").remove();

      leaflet_map.addLayer(layer);
		}

    if (layer.type == "hex"){
      drawHexmap(leaflet_map, layer);
    }
	};
}

/****************************
        Scatterplot
 ****************************/

// Plot Points as a scatterplot
// http://bost.ocks.org/mike/leaflet/
// chriszetter.com/blog/2014/06/15/building-a-voronoi-map-with-d3-and-leaflet/
function drawScatterplot(map, layer){

    // Clear layer if previously existing.
    d3.select('#' + layer.id).remove();

    // Select leaflet's 'overlay pane' layer. Leaflet will
    // auto-repositions the overlay panes upon map movement.

    // Create an SVG elemnt for plotting points on
    var svg = d3.select(map.getPanes().overlayPane).append("svg")
      .attr('id', layer.id)
      .attr("class", "leaflet-zoom-hide")

    // Fix the size of our SVG layer to match the leaflet map
      .style("width",  map.getSize().x + 'px')
      .style("height", map.getSize().y + 'px')

    // Add a "g" (group) element. Organizes points
    // and ensures that layer aligns with leaflet.
    var g = svg.append("g")

    // Apply leaflet-zoom-hide so that the overlay
    // is hidden during zoom animations
      .attr("class", "leaflet-zoom-hide");

    // Create map-able set of points. For each point,
    // convert the lat/long into a plottable x/y position
    var points = layer.data.filter(function(p) {

      // Check for missing data points
      if (!p.latitude || !p.longitude){
        console.log("ERROR. Missing Latitude/Longitude Data.");
        return false;
      }

      // Create new leaflet Lat/Long Object
      var latlng = new L.LatLng(p.latitude, p.longitude);

      // Remove points that are outside current viewport
      if (!bounds.contains(latlng)) { return false };

      // Convert Latitude and Longitude into a Mapable
      // point using leaflet's LayerPoint API.
      var point = map.latLngToLayerPoint(latlng);

      // Save the resulting x & y values
      // onto the current point object.
      p.x = point.x;
      p.y = point.y;

      return true;
    });

    // Create a group for this layer
    var svgPoints = g.attr("class", "points")
      .selectAll("g")

      // Append a <g class="point"> for
      // ever data point in the set.
      .data(points)
      .enter().append("g")
      .attr("class", "point")
      .style("z-index", 999);

    // Add circles for each point
    svgPoints.append("circle")

      // Position each circle with the x/y position.
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })

      // Visual Settings
      .style('fill', function(d) { return layer.color } )
      .attr("r", layer.width)
      .attr("opacity", 1);

      // .attr("date", function(d) { return d.date })
      // .attr("pointer-events", "all")

    // Logic for drawing paths between points
    if (layer.path){

      for (var i = 0; i < points.length - 1; i++) {

        // Stop iteration if there's not
        // a next point to connect.
        if (i >= points.length - 2) return;

        var current = points[i];
        var next = points[i + 1];

        svgPoints.append("line")
          .attr("x1", current.x)
          .attr("y1", current.y)
          .attr("x2", next.x)
          .attr("y2", next.y)
          .style("stroke", layer.color)
          .style("stroke-width", layer.width * 2)
          .style("opacity", 1);

      };

    }

};

/****************************
          Path
 ****************************/

// function drawPath(map, layer){
// 	// Enable path
// 	layer.pathing = true;

//   console.log(layer)

// 	// Render Layer
// 	drawPoints(map, layer);
// };

/****************************
         Heatmap
 ****************************/

// WebGL Heatmap Implementation:
// https://github.com/ursudio/webgl-heatmap-leaflet
// Returns a leaflet layer
function drawHeatmap(map, layer){

	var heatmap = new L.TileLayer.WebGLHeatMap({
    	size: 500,
    	autoresize: true,
    	opacity: .4,
  	});

	var dataPoints = [];

	for (var i = layer.data.length - 1; i >= 0; i--) {
		var point = layer.data[i]
		dataPoints.push([point.latitude, point.longitude, point.value / 40000]);
	};

	heatmap.setData(dataPoints);

	return heatmap;
}

function drawHexmap(map, layer){

    // Options for the hexbin layer
    var hexSettings = {
        radius : 10,                            // Size of the hexagons/bins
        opacity: 0.5,                           // Opacity of the hexagonal layer
        duration: 200,                          // millisecond duration of d3 transitions (see note below)
        lng: function(d){ return d[0]; },       // longitude accessor
        lat: function(d){ return d[1]; },       // latitude accessor
        value: function(d){ return d.length; }, // value accessor - derives the bin value
        valueFloor: 0,                          // override the color scale domain low value
        valueCeil: undefined,                   // override the color scale domain high value
        colorRange: ['#f7fbff', '#08306b']      // default color range for the heat map
    };

    // Create the hexbin layer and add it to the map
    var hexLayer = L.hexbinLayer(hexSettings).addTo(map);

    // Optionally, access the d3 color scale directly
    // Can also set scale via hexLayer.colorScale(d3.scale.linear()...)
    hexLayer.colorScale().range('white', 'blue');

    var center = [42.329077, -71.108871];

    var latFn = d3.random.normal(center[0], 1);
    var longFn = d3.random.normal(center[1], 1);

    var data = [];

    for(i=0; i<1000; i++){
        data.push([longFn(),  latFn(), Math.random()]);
    }

    // Set the data (can be set multiple times)
    hexLayer.data(data);
}
<|endoftext|>


<commit_before>/*! @license ©2013 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
/* A TurtleFragmentIterator reads data and metadata from Linked Data Fragments in Turtle. */

var TransformIterator = require('../iterators/Iterator').TransformIterator,
    BufferIterator = require('../iterators/Iterator').BufferIterator,
    rdf = require('../util/RdfUtil'),
    N3 = require('n3');

// Creates a new TurtleFragmentIterator
function TurtleFragmentIterator(source, fragmentUrl) {
  if (!(this instanceof TurtleFragmentIterator))
    return new TurtleFragmentIterator(source, fragmentUrl);
  TransformIterator.call(this, source);

  // Expose an additional metadata stream
  this.metadataStream = new BufferIterator();
  if (source && source.ended) return this.metadataStream._push(null);
  // When a metadata listener is added, drain the source to read metadata
  this.metadataStream.on('newListener', function metadataListenerAdded(event) {
    if (event === 'data' || event === 'end') {
      this.removeListener('newListener', metadataListenerAdded);
      self._bufferAll();
    }
  });

  // Convert Turtle into triples using the N3 parser
  var self = this;
  this._parser = new N3.Parser({ documentURI: fragmentUrl });
  this._parser.parse(function (error, triple) {
    triple && self._push(self._processTriple(triple)) ||
    error  && self.emit('error', error);
  });
  this._fragmentUrl = fragmentUrl;
}
TransformIterator.inherits(TurtleFragmentIterator);

// Sends a chunk of Turtle to the N3 parser to convert it to triples
TurtleFragmentIterator.prototype._transform = function (chunk, done) {
  this._parser.addChunk(chunk), done();
};

// Sends the given parsed triple to the data or metadata stream
TurtleFragmentIterator.prototype._processTriple = function (triple) {
  // This separation between data and metadata/controls is an approximation;
  // for a proper separation, use an RDF format with graph support (see TrigFragmentParser).
  if (triple.subject !== this._fragmentUrl && triple.predicate.indexOf(rdf.HYDRA) !== 0)
    this._push(triple);
  else
    this.metadataStream._push(triple);
};

// Closes the metadata stream after the source has ended
TurtleFragmentIterator.prototype._flush = function () {
  this.metadataStream._end();
  this._parser.end();
  this._end();
};

// Indicates whether the class supports the content type
TurtleFragmentIterator.supportsContentType = function (contentType) {
  return (/^(?:text\/turtle|text\/n3|application\/n-triples)$/).test(contentType);
};

module.exports = TurtleFragmentIterator;
<commit_msg>Ensure all metadata triples are parsed.<commit_after>/*! @license ©2013 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
/* A TurtleFragmentIterator reads data and metadata from Linked Data Fragments in Turtle. */

var TransformIterator = require('../iterators/Iterator').TransformIterator,
    BufferIterator = require('../iterators/Iterator').BufferIterator,
    rdf = require('../util/RdfUtil'),
    N3 = require('n3');

// Creates a new TurtleFragmentIterator
function TurtleFragmentIterator(source, fragmentUrl) {
  if (!(this instanceof TurtleFragmentIterator))
    return new TurtleFragmentIterator(source, fragmentUrl);
  TransformIterator.call(this, source);

  // Expose an additional metadata stream
  this.metadataStream = new BufferIterator();
  if (source && source.ended) return this.metadataStream._push(null);
  // When a metadata listener is added, drain the source to read metadata
  this.metadataStream.on('newListener', function metadataListenerAdded(event) {
    if (event === 'data' || event === 'end') {
      this.removeListener('newListener', metadataListenerAdded);
      self._bufferAll();
    }
  });

  // Convert Turtle into triples using the N3 parser
  var self = this;
  this._parser = new N3.Parser({ documentURI: fragmentUrl });
  this._parser.parse(function (error, triple) {
    triple && self._push(self._processTriple(triple)) ||
    error  && self.emit('error', error);
  });
  this._fragmentUrl = fragmentUrl;
}
TransformIterator.inherits(TurtleFragmentIterator);

// Sends a chunk of Turtle to the N3 parser to convert it to triples
TurtleFragmentIterator.prototype._transform = function (chunk, done) {
  this._parser.addChunk(chunk), done();
};

// Sends the given parsed triple to the data or metadata stream
TurtleFragmentIterator.prototype._processTriple = function (triple) {
  // This separation between data and metadata/controls is an approximation;
  // for a proper separation, use an RDF format with graph support (see TrigFragmentParser).
  if (triple.subject !== this._fragmentUrl && triple.predicate.indexOf(rdf.HYDRA) !== 0)
    this._push(triple);
  else
    this.metadataStream._push(triple);
};

// Closes the streams after the source has ended
TurtleFragmentIterator.prototype._flush = function () {
  // Ensure the parser processes possible pending triples
  this._parser.end();
  // Once all triples have been processed, end both streams
  this.metadataStream._end();
  this._end();
};

// Indicates whether the class supports the content type
TurtleFragmentIterator.supportsContentType = function (contentType) {
  return (/^(?:text\/turtle|text\/n3|application\/n-triples)$/).test(contentType);
};

module.exports = TurtleFragmentIterator;
<|endoftext|>


<commit_before>import kotlinPlayground from 'kotlin-playground';
import $ from 'jquery';
import 'whatwg-fetch';

import '../com/search/search';
import '../com/cookie-banner';
import '../com/cities-banners';
import GifPlayer from '../com/gif-player/gif-player';
import CodeMirror from '../com/codemirror/CodeMirror';

$(document).ready(function () {
  kotlinPlayground('.sample');

  CodeMirror.colorize($('.code._highlighted'));

  const html = document.getElementsByTagName('html')[0];

  html.className = html.className.replace('no-js', '');

  // OS detection
  if (navigator.userAgent.indexOf('Linux') > -1)
    html.className += ' os_linux';

  // Browser detection
  if ('chrome' in window)
    html.className += ' ua_chrome';
  else if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1)
    html.className += ' ua_firefox';

  // hack to force :active support in mobile Safari
  document.addEventListener("touchstart", function () {
  }, false);

  $('h1,h2,h3').each(function (element) {
    const id = this.getAttribute("id");
    if (id == null) return;
    const referenceElement = document.createElement("a");
    referenceElement.className = "anchor";
    referenceElement.href = "#" + id;
    this.appendChild(referenceElement);
  });

  new GifPlayer(".gif-image")
});<commit_msg>fix: load git-player on each element<commit_after>import kotlinPlayground from 'kotlin-playground';
import $ from 'jquery';
import 'whatwg-fetch';

import '../com/search/search';
import '../com/cookie-banner';
import '../com/cities-banners';
import GifPlayer from '../com/gif-player/gif-player';
import CodeMirror from '../com/codemirror/CodeMirror';

$(document).ready(function () {
  kotlinPlayground('.sample');

  CodeMirror.colorize($('.code._highlighted'));

  const html = document.getElementsByTagName('html')[0];

  html.className = html.className.replace('no-js', '');

  // OS detection
  if (navigator.userAgent.indexOf('Linux') > -1)
    html.className += ' os_linux';

  // Browser detection
  if ('chrome' in window)
    html.className += ' ua_chrome';
  else if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1)
    html.className += ' ua_firefox';

  // hack to force :active support in mobile Safari
  document.addEventListener("touchstart", function () {
  }, false);

  $('h1,h2,h3').each(function (element) {
    const id = this.getAttribute("id");
    if (id == null) return;
    const referenceElement = document.createElement("a");
    referenceElement.className = "anchor";
    referenceElement.href = "#" + id;
    this.appendChild(referenceElement);
  });
  const elements = document.getElementsByClassName("gif-image");
  Array.prototype.forEach.call(elements, function(el) {
    new GifPlayer(el)
  });
});<|endoftext|>


<commit_before>function initMap() {
  // Map style from https://snazzymaps.com/style/27/shift-worker
  var styledMapType = new google.maps.StyledMapType(
    [
      {
        "stylers": [
          {
            "saturation": -100
          },
          {
            "gamma": 1
          }
        ]
      },
      {
        "elementType": "labels.text.stroke",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.place_of_worship",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.place_of_worship",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "road",
        "elementType": "geometry",
        "stylers": [
          {
            "visibility": "simplified"
          }
        ]
      },
      {
        "featureType": "water",
        "stylers": [
          {
            "visibility": "on"
          },
          {
            "saturation": 50
          },
          {
            "gamma": 0
          },
          {
            "hue": "#50a5d1"
          }
        ]
      },
      {
        "featureType": "administrative.neighborhood",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#333333"
          }
        ]
      },
      {
        "featureType": "road.local",
        "elementType": "labels.text",
        "stylers": [
          {
            "weight": 0.5
          },
          {
            "color": "#333333"
          }
        ]
      },
      {
        "featureType": "transit.station",
        "elementType": "labels.icon",
        "stylers": [
          {
            "gamma": 1
          },
          {
            "saturation": 50
          }
        ]
      }
    ], {name: 'Styled Map'});

  // Create a map object and specify the DOM element for display.
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 33.972536, lng: -118.426561},
    scrollwheel: false,
    zoom: 15,
    mapTypeControlOptions: {
        mapTypeIds: ['styled_map', 'roadmap']
      }
  });

  var marker = new google.maps.Marker({
    position: {lat: 33.976977, lng: -118.407325},
    map: map,
    title: 'Hello World!',
    animation: google.maps.Animation.DROP
  });

  // Associate the styled map with the MapTypeId and set it to display.
  map.mapTypes.set('styled_map', styledMapType);
  map.setMapTypeId('styled_map');
}
<commit_msg>Add geocode function to get position of address<commit_after>var locations = [
  {
    name: 'Test Broken',
    address: '1212 South Fake Street, Los Angeles, CA 90094'
  },
  {
    name: 'YouTube Spaces',
    address: '12422 Bluff Creek Dr, Los Angeles, CA 90094'
  },
  {
    name: 'Fullscreen, Inc.',
    address: '12180 Millennium Dr, Los Angeles, CA 90094'
  },
  {
    name: 'IMAX Post/DKP Inc.',
    address: '12582 Millennium Dr, Playa Vista, CA 90094'
  },
  {
    name: 'Belkin International',
    address: '12045 Waterfront Dr, Los Angeles, CA 90094'
  },
  {
    name: 'Yahoo Inc, Playa Vista. Office',
    address: '11975 Bluff Creek Dr, Los Angeles, CA 90094'
  },
  {
    name: 'Electronic Arts (EA)',
    address: '5510 Lincoln Blvd, Playa Vista, CA 90094'
  },
  {
    name: 'ICANN',
    address: '12025 E Waterfront Dr #300, Los Angeles, CA 90094'
  }
];

function initMap() {
  // Store all markers in this array
  var markers = [];

  // Initialize geocoding service
  var geocoder = new google.maps.Geocoder();

  // Map style from https://snazzymaps.com/style/27/shift-worker
  var styledMapType = new google.maps.StyledMapType(
    [
      {
        "stylers": [
          {
            "saturation": -100
          },
          {
            "gamma": 1
          }
        ]
      },
      {
        "elementType": "labels.text.stroke",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.place_of_worship",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.place_of_worship",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "road",
        "elementType": "geometry",
        "stylers": [
          {
            "visibility": "simplified"
          }
        ]
      },
      {
        "featureType": "water",
        "stylers": [
          {
            "visibility": "on"
          },
          {
            "saturation": 50
          },
          {
            "gamma": 0
          },
          {
            "hue": "#50a5d1"
          }
        ]
      },
      {
        "featureType": "administrative.neighborhood",
        "elementType": "labels.text.fill",
        "stylers": [
          {
            "color": "#333333"
          }
        ]
      },
      {
        "featureType": "road.local",
        "elementType": "labels.text",
        "stylers": [
          {
            "weight": 0.5
          },
          {
            "color": "#333333"
          }
        ]
      },
      {
        "featureType": "transit.station",
        "elementType": "labels.icon",
        "stylers": [
          {
            "gamma": 1
          },
          {
            "saturation": 50
          }
        ]
      }
    ], {name: 'Styled Map'});

  // Create a map object and specify the DOM element for display.
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 33.972536, lng: -118.426561},
    scrollwheel: false,
    zoom: 15,
    mapTypeControlOptions: {
        mapTypeIds: ['styled_map', 'roadmap']
      }
  });

  // Associate the styled map with the MapTypeId and set it to display.
  map.mapTypes.set('styled_map', styledMapType);
  map.setMapTypeId('styled_map');

  // Cycle through location addresses and create markers on map
  for (var i = 0; i < locations.length; i++) {
    geocodeAddressToMarker(locations[i], map, geocoder, markers);
  }
}

// Turns a location into a location using geocode service, and creates marker
function geocodeAddressToMarker(location, map, geocoder, markers) {
  geocoder.geocode({
    address: location.address
  }, function(results, status) {
    if (status === 'OK') {
      markers.push(createMarker(results[0].geometry.location, map, location.name));
    } else {
      alert('Geocode was not successful for the following reason: ' + status);
    }
  });
}

// Creates a default marker for map
function createMarker(position, map, title) {
  var marker = new google.maps.Marker({
    map: map,
    position: position,
    title: title,
    animation: google.maps.Animation.DROP
  });
  return marker;
}
<|endoftext|>


<commit_before>'use babel'
import $ from 'JQuery'
import _ from 'lodash'
var {allowUnsafeEval, allowUnsafeNewFunction} = require('loophole');
import Handlebars from "Handlebars"
import VariantsHandler from "./VariantsHandler"
var fs = require('fs');
const VARIANT_FILE_RELATIVE = "/variants/variants_def.xml";
export default class VariantsViewUIHandler {
  constructor() {
    console.log("create VariantsViewUIHandler");
    this.mainSection=undefined;
    this.variantsSelectorContainer = undefined;
    this.templatesFn={};
    this.variantsHandler= new VariantsHandler();
    this.variants = undefined;
    this.addPreferenceModalPanel = undefined;
    this.addVariantModalPanel = undefined;
  }

  createAndPrecompileTemplates(){
    console.log("createAndPrecompileTemplates");
    // import template src
    var noEntrySrc = $("#no-entry-template").html();
    var variantSelectorSrc = $("#variants-selector-template").html();
    var variantContainerSrc = $("#variants-template").html();
    var singleVariantSrc = $("#single-variant-template").html();
    // precompile template
    this.templatesFn['noEntry']= allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(noEntrySrc)));
    this.templatesFn['variantSelector']= allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(variantSelectorSrc)));
    this.templatesFn['variantContainer'] =  allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(variantContainerSrc)));
    this.templatesFn['singleVariant'] =  allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(singleVariantSrc)));
  }

  init(){
    this.variantsHandler.initEmptyObject();
    console.log("onInit");
    var path= atom.project.getPaths()[0] + VARIANT_FILE_RELATIVE;
    this.mainSection = $("#main-section");
    this.variantsSelectorContainer = $("#variants-selector-container");
    this.createAndPrecompileTemplates();

    if(!fs.existsSync(path)){
      console.log("No variants defined");
      this.showNoVariantsDef();
      this.variants = this.variantsHandler.getVariants();
    }else{
      this.reloadFromFile(path)
    }
    this.bindJS();
  }

  reloadFromFile(path){
    this.variantsHandler.load(path).then(() => {
      console.log("loading end");
      this.variants = this.variantsHandler.getVariants();
      console.log("Mapped in:",this.variants);
      this.renderVariantsSelector(this.variants);
      this.bindJSForSelector();
      this.setSelectedVariantByName(this.getNameByIndex(0));
      //this.renderSingleVariant(this.variants[0]);
      //this.renderVariants(this.variants);
    },() => {
      console.error("loading fail!!!!");
    });
  }

  bindJSForSelector(){
    $('[variant-selector]').bind('click',(evt) => {
      var variantName= $(evt.currentTarget).attr("variant-selector");
      console.log("Click on: ",variantName);
      this.setSelectedVariantByName(variantName);
    });
  }

  createModalAddPreference(){
    var addPreferenceView=require('./add-preference-view');
    this.addPreferenceModalPanel = atom.workspace.addModalPanel({
      item: addPreferenceView.getItem($),
      visible: true
    });
    this.addPreferenceModalPanel.__clear =function(){
      addPreferenceView.clear($);
    }
  }

  createModalAddVariant(){
    var addVariantView=require('./add-variant-view');
    this.addVariantModalPanel = atom.workspace.addModalPanel({
      item: addVariantView.getItem($),
      visible: true
    });
    this.addVariantModalPanel.__clear =function(){
      addVariantView.clear($);
    }
  }

  showModalAddVariant(){
    return new Promise((resolve,reject) => {
      if(!this.addVariantModalPanel){
        this.createModalAddVariant();
      }
      this.addVariantModalPanel.show();
      // bind js for manage modal
      $('#btn-confirm-add-variant').off('click').on('click',() => {
        console.log("Add variant done");
        var variantName=$("#txt-new-variant-name").val();
        this.addVariantModalPanel.hide();
        this.addVariantModalPanel.__clear()
        resolve({
          cancel:false,
          variantName:variantName
        })

      });
      $('#btn-cancel-add-variant').off('click').on('click',() => {
        console.log("Add variant cancel");
        this.addVariantModalPanel.hide();
        this.addVariantModalPanel.__clear()
        resolve({
          cancel:true
        });
      });
    });
  }

  showModalAddPreference(){
    return new Promise((resolve,reject) => {
      if(!this.addPreferenceModalPanel){
        this.createModalAddPreference();
      }
      this.addPreferenceModalPanel.show();
      // bind js for manage modal
      $('#btn-add-preference').off('click').on('click',() => {
        console.log("confirm preference add");
        var preference = {};
        preference.name = $('#txt-new-preference-name').val().trim() || undefined;
        preference.value = $('#txt-new-preference-value').val().trim() || undefined;
        this.addPreferenceModalPanel.hide();
        this.addPreferenceModalPanel.__clear();
        resolve({
          cancel:false,
          preference:preference
        });
      });
      $('#btn-cancel-add-preference').off('click').on('click',() => {
        console.log("cancel preference add");
        this.addPreferenceModalPanel.hide();
        this.addPreferenceModalPanel.__clear()
        resolve({cancel:true});
      });
    });
  }

  bindJSForPreferenceBtn(){
    $('[variant-add-preference]').off("click").on('click',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      console.log("Add preference",variantName);
      this.showModalAddPreference().then((res) => {
        if(res.cancel){
          console.log("operation cancel");
          return;
        }
        console.log("Add new preference: ",res.preference);
        this.applyPreferenceChange(res.preference.value,res.preference.name,variantName);
        this.reloadCurrentVariant();

      },(err) => {
        console.error("showModalAddPreference fail");
      });
    });
    $('[variant-add-preference-platform]').off("click").on('click',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var platformName= jqueryEl.attr("variant-platform-ref");
      console.log("Add preference",variantName,platformName);
      this.showModalAddPreference().then((res) => {
        if(res.cancel){
          console.log("operation cancel");
          return;
        }
        console.log("Add new preference: ",res.preference);
        this.applyPreferenceChange(res.preference.value,res.preference.name,variantName,platformName);
        this.reloadCurrentVariant();
      },(err) => {
        console.error("showModalAddPreference fail");
      });
    });
  }

  bindJSForPreferenceChange(){
    console.log("bindJSForPreferenceChange");
    $('[variant-preference-id]').off("change").on('change',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var preferenceName= jqueryEl.attr("variant-preference-id");
      var value=jqueryEl.val();
      console.log("Change preference: ",preferenceName," of variant",variantName, " value:",value);
      this.applyPreferenceChange(value,preferenceName,variantName);
    })

    $('[variant-preference-platform-id]').off("change").on('change',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var preferenceName= jqueryEl.attr("variant-preference-platform-id");
      var platformName= jqueryEl.attr("variant-platform-ref");
      var value=jqueryEl.val();
      console.log("Change preference: ",preferenceName," of variant",variantName,"of platform",platformName, " value:",value);
      this.applyPreferenceChange(value,preferenceName,variantName,platformName);
    })
  }

  reloadCurrentVariant(){
    console.log("reloadCurrentVariant");
    this.setSelectedVariant(this.setSelectedVariantIndex);
  }

  addOrChangePreference(preference,prefArray){
    var target = _.find(prefArray,(item) => {
      return item.name === preference.name;
    });
    if(!target){
      console.log("target not found in prefArray: add new preference");
      prefArray[prefArray.length] = preference;
      return;
    }
    target.value = preference.value;
  }

  applyPreferenceChange(value,prefName,variantName,platformName){
    console.log("applyPreferenceChange ",value,prefName,variantName,platformName);
    var index=this.getIndexByName(variantName);
    if(index<0){
      atom.notifications.addError("applyPreferenceChange fail: variant " + variantName  + " not found");
      return;
    }
    var variantDef=this.variants[index];
    console.log("variantDef:",variantDef);
    var preference= {
      name: prefName,
      value: value
    };
    if(!platformName){
      this.addOrChangePreference(preference,variantDef.preference);
    }else{
      var platform = _.find(variantDef.platform,(item)=>{
        return item.name === platformName;
      });
      if(!platform){
        console.error("platform ",platform," not found");
        return;
      }
      this.addOrChangePreference(preference,platform.preference);
    }
  }

  updateVariantSelector(name){
    $('[variant-selector]').removeClass("selected");
    $("[variant-selector='" + name + "'").addClass("selected");
  }

  reloadVariantSelector(index){
    this.renderVariantsSelector(this.variants);
    this.bindJSForSelector();
    var name = this.getNameByIndex(index);
    this.updateVariantSelector(name);
  }

  getIndexByName(name){
    return _.findIndex(this.variants,(item) => {
      return item.name == name;
    })
  }

  getNameByIndex(index){
    if(!this.variants || !this.variants[index]){
      return undefined;
    }
    return this.variants[index].name;
  }

  setSelectedVariantByName(name){
    var index=this.getIndexByName(name);
    if(index < 0){
      console.error("setSelectedVariantByName -> name not found");
      return;
    }
    this.updateVariantSelector(name)
    this.setSelectedVariant(index);
  }

  setSelectedVariant(index){
    this.setSelectedVariantIndex=index;
    this.renderSingleVariant(this.variants[index]);
    this.bindJSForPreferenceChange();
    this.bindJSForPreferenceBtn();
  }

  applyTemplate(name,context){
    return allowUnsafeEval(() => allowUnsafeNewFunction(() => this.templatesFn[name](context)));
  }

  renderVariants(variants){
    console.log("renderVariants");
    var html = this.applyTemplate("variantContainer", {variants: variants});
    this.mainSection.empty();
    this.mainSection.append(html);
  }

  renderSingleVariant(variant){
    console.log("renderSingleVariant");
    var html = this.applyTemplate("singleVariant", variant);
    this.mainSection.empty();
    this.mainSection.append(html);
  }

  renderVariantsSelector(variants){
    console.log("renderVariantsSelector");
    var html = this.applyTemplate("variantSelector", {variants: variants});
    this.variantsSelectorContainer.empty();
    this.variantsSelectorContainer.append(html);
  }

  showNoVariantsDef(){
    console.log("showNoVariantsDef");
    var html = this.applyTemplate("noEntry");
    this.mainSection.append(html);
  }

  bindJS(){
    console.log("bindJS for variants management");
    $('#btn-add-variant').off("click").on("click",() => {
      console.log("Add new variant click");
      this.showModalAddVariant().then((res) => {
        if(res.cancel){
          console.log("add variant cancel");
          return;
        }
        console.log("Add variant:",res.variantName);
        var newVariant=VariantsHandler.createVariantSkeleton(res.variantName);
        console.log("new variant:",newVariant);
        this.variants[this.variants.length] = newVariant;
        this.reloadVariantSelector(this.setSelectedVariantIndex);
      });
    });

    $('#btn-save').off("click").on("click",() => {
      console.log("Save Variants changes click");
      this.variantsHandler.applyChanges(this.variants);
    });

    $('#btn-delete-variant').off("click").on("click",() => {
      console.log("Delete variant click");
    });

  }

  onRemove(){
    console.log("onRemove");
  }
}
<commit_msg>Add require for variant delete<commit_after>'use babel'
import $ from 'JQuery'
import _ from 'lodash'
var {allowUnsafeEval, allowUnsafeNewFunction} = require('loophole');
import Handlebars from "Handlebars"
import VariantsHandler from "./VariantsHandler"
var fs = require('fs');
const VARIANT_FILE_RELATIVE = "/variants/variants_def.xml";
export default class VariantsViewUIHandler {
  constructor() {
    console.log("create VariantsViewUIHandler");
    this.mainSection=undefined;
    this.variantsSelectorContainer = undefined;
    this.templatesFn={};
    this.variantsHandler= new VariantsHandler();
    this.variants = undefined;
    this.addPreferenceModalPanel = undefined;
    this.addVariantModalPanel = undefined;
  }

  createAndPrecompileTemplates(){
    console.log("createAndPrecompileTemplates");
    // import template src
    var noEntrySrc = $("#no-entry-template").html();
    var variantSelectorSrc = $("#variants-selector-template").html();
    var variantContainerSrc = $("#variants-template").html();
    var singleVariantSrc = $("#single-variant-template").html();
    // precompile template
    this.templatesFn['noEntry']= allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(noEntrySrc)));
    this.templatesFn['variantSelector']= allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(variantSelectorSrc)));
    this.templatesFn['variantContainer'] =  allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(variantContainerSrc)));
    this.templatesFn['singleVariant'] =  allowUnsafeEval(() => allowUnsafeNewFunction(() => Handlebars.compile(singleVariantSrc)));
  }

  init(){
    this.variantsHandler.initEmptyObject();
    console.log("onInit");
    var path= atom.project.getPaths()[0] + VARIANT_FILE_RELATIVE;
    this.mainSection = $("#main-section");
    this.variantsSelectorContainer = $("#variants-selector-container");
    this.createAndPrecompileTemplates();

    if(!fs.existsSync(path)){
      console.log("No variants defined");
      this.showNoVariantsDef();
      this.variants = this.variantsHandler.getVariants();
    }else{
      this.reloadFromFile(path)
    }
    this.bindJS();
  }

  reloadFromFile(path){
    this.variantsHandler.load(path).then(() => {
      console.log("loading end");
      this.variants = this.variantsHandler.getVariants();
      console.log("Mapped in:",this.variants);
      this.renderVariantsSelector(this.variants);
      this.bindJSForSelector();
      this.setSelectedVariantByName(this.getNameByIndex(0));
      //this.renderSingleVariant(this.variants[0]);
      //this.renderVariants(this.variants);
    },() => {
      console.error("loading fail!!!!");
    });
  }

  bindJSForSelector(){
    $('[variant-selector]').bind('click',(evt) => {
      var variantName= $(evt.currentTarget).attr("variant-selector");
      console.log("Click on: ",variantName);
      this.setSelectedVariantByName(variantName);
    });
  }

  createModalAddPreference(){
    var addPreferenceView=require('./add-preference-view');
    this.addPreferenceModalPanel = atom.workspace.addModalPanel({
      item: addPreferenceView.getItem($),
      visible: true
    });
    this.addPreferenceModalPanel.__clear =function(){
      addPreferenceView.clear($);
    }
  }

  createModalAddVariant(){
    var addVariantView=require('./add-variant-view');
    this.addVariantModalPanel = atom.workspace.addModalPanel({
      item: addVariantView.getItem($),
      visible: true
    });
    this.addVariantModalPanel.__clear =function(){
      addVariantView.clear($);
    }
  }

  showModalAddVariant(){
    return new Promise((resolve,reject) => {
      if(!this.addVariantModalPanel){
        this.createModalAddVariant();
      }
      this.addVariantModalPanel.show();
      // bind js for manage modal
      $('#btn-confirm-add-variant').off('click').on('click',() => {
        console.log("Add variant done");
        var variantName=$("#txt-new-variant-name").val();
        this.addVariantModalPanel.hide();
        this.addVariantModalPanel.__clear()
        resolve({
          cancel:false,
          variantName:variantName
        })

      });
      $('#btn-cancel-add-variant').off('click').on('click',() => {
        console.log("Add variant cancel");
        this.addVariantModalPanel.hide();
        this.addVariantModalPanel.__clear()
        resolve({
          cancel:true
        });
      });
    });
  }

  showModalAddPreference(){
    return new Promise((resolve,reject) => {
      if(!this.addPreferenceModalPanel){
        this.createModalAddPreference();
      }
      this.addPreferenceModalPanel.show();
      // bind js for manage modal
      $('#btn-add-preference').off('click').on('click',() => {
        console.log("confirm preference add");
        var preference = {};
        preference.name = $('#txt-new-preference-name').val().trim() || undefined;
        preference.value = $('#txt-new-preference-value').val().trim() || undefined;
        this.addPreferenceModalPanel.hide();
        this.addPreferenceModalPanel.__clear();
        resolve({
          cancel:false,
          preference:preference
        });
      });
      $('#btn-cancel-add-preference').off('click').on('click',() => {
        console.log("cancel preference add");
        this.addPreferenceModalPanel.hide();
        this.addPreferenceModalPanel.__clear()
        resolve({cancel:true});
      });
    });
  }

  bindJSForPreferenceBtn(){
    $('[variant-add-preference]').off("click").on('click',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      console.log("Add preference",variantName);
      this.showModalAddPreference().then((res) => {
        if(res.cancel){
          console.log("operation cancel");
          return;
        }
        console.log("Add new preference: ",res.preference);
        this.applyPreferenceChange(res.preference.value,res.preference.name,variantName);
        this.reloadCurrentVariant();

      },(err) => {
        console.error("showModalAddPreference fail");
      });
    });
    $('[variant-add-preference-platform]').off("click").on('click',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var platformName= jqueryEl.attr("variant-platform-ref");
      console.log("Add preference",variantName,platformName);
      this.showModalAddPreference().then((res) => {
        if(res.cancel){
          console.log("operation cancel");
          return;
        }
        console.log("Add new preference: ",res.preference);
        this.applyPreferenceChange(res.preference.value,res.preference.name,variantName,platformName);
        this.reloadCurrentVariant();
      },(err) => {
        console.error("showModalAddPreference fail");
      });
    });
  }

  bindJSForPreferenceChange(){
    console.log("bindJSForPreferenceChange");
    $('[variant-preference-id]').off("change").on('change',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var preferenceName= jqueryEl.attr("variant-preference-id");
      var value=jqueryEl.val();
      console.log("Change preference: ",preferenceName," of variant",variantName, " value:",value);
      this.applyPreferenceChange(value,preferenceName,variantName);
    })

    $('[variant-preference-platform-id]').off("change").on('change',(evt) => {
      var jqueryEl=$(evt.currentTarget);
      var variantName= jqueryEl.attr("variant-ref");
      var preferenceName= jqueryEl.attr("variant-preference-platform-id");
      var platformName= jqueryEl.attr("variant-platform-ref");
      var value=jqueryEl.val();
      console.log("Change preference: ",preferenceName," of variant",variantName,"of platform",platformName, " value:",value);
      this.applyPreferenceChange(value,preferenceName,variantName,platformName);
    })
  }

  reloadCurrentVariant(){
    console.log("reloadCurrentVariant");
    this.setSelectedVariant(this.selectedVariantIndex);
  }

  addOrChangePreference(preference,prefArray){
    var target = _.find(prefArray,(item) => {
      return item.name === preference.name;
    });
    if(!target){
      console.log("target not found in prefArray: add new preference");
      prefArray[prefArray.length] = preference;
      return;
    }
    target.value = preference.value;
  }

  applyPreferenceChange(value,prefName,variantName,platformName){
    console.log("applyPreferenceChange ",value,prefName,variantName,platformName);
    var index=this.getIndexByName(variantName);
    if(index<0){
      atom.notifications.addError("applyPreferenceChange fail: variant " + variantName  + " not found");
      return;
    }
    var variantDef=this.variants[index];
    console.log("variantDef:",variantDef);
    var preference= {
      name: prefName,
      value: value
    };
    if(!platformName){
      this.addOrChangePreference(preference,variantDef.preference);
    }else{
      var platform = _.find(variantDef.platform,(item)=>{
        return item.name === platformName;
      });
      if(!platform){
        console.error("platform ",platform," not found");
        return;
      }
      this.addOrChangePreference(preference,platform.preference);
    }
  }

  updateVariantSelector(name){
    $('[variant-selector]').removeClass("selected");
    $("[variant-selector='" + name + "'").addClass("selected");
  }

  reloadVariantSelector(index){
    this.renderVariantsSelector(this.variants);
    this.bindJSForSelector();
    var name = this.getNameByIndex(index);
    this.updateVariantSelector(name);
  }

  getIndexByName(name){
    return _.findIndex(this.variants,(item) => {
      return item.name == name;
    })
  }

  getNameByIndex(index){
    if(!this.variants || !this.variants[index]){
      return undefined;
    }
    return this.variants[index].name;
  }

  setSelectedVariantByName(name){
    var index=this.getIndexByName(name);
    if(index < 0){
      console.error("setSelectedVariantByName -> name not found");
      return;
    }
    this.updateVariantSelector(name)
    this.setSelectedVariant(index);
  }

  setSelectedVariant(index){
    this.selectedVariantIndex=index;
    this.renderSingleVariant(this.variants[index]);
    this.bindJSForPreferenceChange();
    this.bindJSForPreferenceBtn();
  }

  applyTemplate(name,context){
    return allowUnsafeEval(() => allowUnsafeNewFunction(() => this.templatesFn[name](context)));
  }

  renderVariants(variants){
    console.log("renderVariants");
    var html = this.applyTemplate("variantContainer", {variants: variants});
    this.mainSection.empty();
    this.mainSection.append(html);
  }

  renderSingleVariant(variant){
    console.log("renderSingleVariant");
    var html = this.applyTemplate("singleVariant", variant);
    this.mainSection.empty();
    this.mainSection.append(html);
  }

  renderVariantsSelector(variants){
    console.log("renderVariantsSelector");
    var html = this.applyTemplate("variantSelector", {variants: variants});
    this.variantsSelectorContainer.empty();
    this.variantsSelectorContainer.append(html);
  }

  showNoVariantsDef(){
    console.log("showNoVariantsDef");
    var html = this.applyTemplate("noEntry");
    this.mainSection.append(html);
  }

  bindJS(){
    console.log("bindJS for variants management");
    $('#btn-add-variant').off("click").on("click",() => {
      console.log("Add new variant click");
      this.showModalAddVariant().then((res) => {
        if(res.cancel){
          console.log("add variant cancel");
          return;
        }
        console.log("Add variant:",res.variantName);
        var newVariant=VariantsHandler.createVariantSkeleton(res.variantName);
        console.log("new variant:",newVariant);
        this.variants[this.variants.length] = newVariant;
        this.reloadVariantSelector(this.selectedVariantIndex);
      });
    });

    $('#btn-save').off("click").on("click",() => {
      console.log("Save Variants changes click");
      this.variantsHandler.applyChanges(this.variants);
    });

    $('#btn-delete-variant').off("click").on("click",() => {
      if(this.selectedVariantIndex < 0){
        return;
      }
      this.variants[this.selectedVariantIndex].name
      console.log("Delete variant click");
      this.openConfirmDialog("Delete Variant","Delete variant " + this.variants[this.selectedVariantIndex].name  + "?").then(()=>{
        console.log("yes");
      }, () => {
        console.log("cancel");
      });
    });

  }

  openConfirmDialog(message,detailedMessage){
    return new Promise((resolve,reject) => {
      atom.confirm({
        message:message,
        detailedMessage:detailedMessage,
        buttons:{
          yes: resolve,
          cancel: reject
        }
      });
    });
  }

  onRemove(){
    console.log("onRemove");
  }
}
<|endoftext|>


<commit_before>function updateChart (data) {
	var list = [];
	var records = data.records;
	var len = records;
	for (var i = 0; i < len; i++) {
		list.push([records[i].Date, records[i].Power])
	}
	$.jqplot('futureplot', [list], {
		title:'Predicted Power Usage for the next 24 Hours',
		axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}},
		series:[{lineWidth:4, markerOptions:{style:'square'}}]
	});
}

function getData () {
	$.getJSON("/data", updateChart);
}
<commit_msg>js fixes<commit_after>function updateChart (data) {
	var list = [];
	var len = data.length;
	for (var i = 0; i < len; i++) {
		list.push([records[i].Date, records[i].Power])
	}
	$.jqplot('futureplot', [list], {
		title:'Predicted Power Usage for the next 24 Hours',
		axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}},
		series:[{lineWidth:4, markerOptions:{style:'square'}}]
	});
}

function getData () {
	$.getJSON("/data", updateChart);
}
<|endoftext|>


<commit_before>"use strict";

import $ from "jquery";
import d3 from "d3";

// We define these up here so we can re-use them for updating
// the bubble chart once it has been created.
var svg, bubble, text, tooltip;
var color = d3.scale.category20c();

// Util for getting the duration based on what has been selected
var getDuration = function() {
    var checkedDuration = $("#duration input[type=radio]:checked").val();

    return checkedDuration === "all" ? 0 : 1;
};

var durationRadioButtons = $("#duration input[type=radio][name=duration]");

var getNbaStatsAPI = function() {
    // Although we specify a Season, that doesn't matter since IsOnlyCurrentSeason is set
    // to 0, meaning the Season is ignored. We have to specify a Season otherwise we get
    // an error from the API.
    return "http://stats.nba.com/stats/commonallplayers/?LeagueID=00&Season=2014-15&IsOnlyCurrentSeason=" + getDuration();
};

var updateBubbleChart = function(data) {
    var formattedData = bubble.nodes(data).filter(d => { return !d.children; });

    var node = svg.selectAll(".node")
        .data(formattedData);

    // Capture enter selection
    var nodeEnter = node.enter()
        .append("g")
        .attr("class", "node")
        .attr("transform", d => { return `translate(${d.x}, ${d.y})`; });

    // Re-use enter selection for circles
    nodeEnter
        .append("circle")
        .attr("r", d => { return d.r; })
        .style("fill", (d, i) => { return color(i); });

    // Re-use enter selection for text
    text
        .data(formattedData)
        .text(d => {
            var threshold = getDuration() === 0 ? 15 : 2;
            if (d.value > threshold) { return d.name; }
        });

    node.select("circle")
        .transition().duration(1000)
        .attr("r", d => {
            return d.r;
        })
        .style("fill", (d, i) => {
            return color(i);
        });

    node.transition().attr("class", "node")
        .attr("transform", d => {
            return `translate(${d.x}, ${d.y})`;
        });

    node.exit().remove();
};

var renderBubbleChart = function(data) {
    var diameter = 680;

    bubble = d3.layout.pack()
        .sort(null)
        .size([diameter, diameter])
        .padding(1.5);

    svg = d3.select("#bubble-chart").append("svg")
        .attr("width", diameter)
        .attr("height", diameter)
        .attr("class", "bubble");

    var node = svg.selectAll(".node")
      .data(bubble.nodes(data).filter(d => { return !d.children; }))
      .enter().append("g")
        .attr("class", "node")
        .attr("transform", d => { return `translate(${d.x}, ${d.y})`; });

    node.append("circle")
      .attr("r", d => { return d.r; })
      .style("fill", d => { return color(d.name); })
      .on("mouseover", d => {
            return tooltip
                .style("visibility", "visible")
                .text(`${d.name} (${d.value})`);
      })
      .on("mousemove", _ => { return tooltip.style("top", (event.pageY - 10) + "px").style("left",(event.pageX + 10) + "px"); })
      .on("mouseout", _ => { return tooltip.style("visibility", "hidden"); });

    text = node.append("text")
      .attr("dy", ".3em")
      .attr("class", "bubble-text")
      .style("text-anchor", "middle")
      .style("pointer-events", "none")
      .text(d => {
        // Define a threshold for when to add some text to a bubble; with
        // all time names, we need to bump this up otherwise we will have
        // way too much text flying around in the UI.
        var threshold = getDuration() === 0 ? 15 : 2;

        if (d.value > threshold) { return d.name; }
      });

    tooltip = d3.select("#bubble-chart")
      .append("div")
      .classed("tooltip", true)
      .style("position", "absolute")
      .style("z-index", "10")
      .style("visibility", "hidden");

    d3.select(document.frameElement).style("height", `${diameter} px`);
};

var formatData = function(data) {
    var formattedData = [];

    Object.keys(data).forEach(key => {
        formattedData.push({
            name: key,
            value: data[key]
        });
    });

    return formattedData;
};

var getMostPupularNames = function(data) {
    var allPlayers = data.resultSets[0].rowSet;
    var mostPopularNames = {};

    allPlayers.forEach(player => {
        var playerFirstName = player[1].split(", ")[1];

        if (mostPopularNames.hasOwnProperty(playerFirstName)) {
            mostPopularNames[playerFirstName] += 1;
        } else {
            mostPopularNames[playerFirstName] = 1;
        }
    });

    return formatData(mostPopularNames);
};

var makeRequestAndRenderBubbleChart = function(renderFunction) {
    var nbaStatsAPI = getNbaStatsAPI();

    $.ajax(nbaStatsAPI, {
        dataType: "jsonp"
    })
    .done(function(data) {
        renderFunction({ children: getMostPupularNames(data) });
    });
};

var onDurationChange = function() {
    makeRequestAndRenderBubbleChart(updateBubbleChart);
};

// when the duration is changed, we will want to re-render
durationRadioButtons.change(onDurationChange);

makeRequestAndRenderBubbleChart(renderBubbleChart);<commit_msg>Make onmouse events easier to read<commit_after>"use strict";

import $ from "jquery";
import d3 from "d3";

// We define these up here so we can re-use them for updating
// the bubble chart once it has been created.
var svg, bubble, text, tooltip;
var color = d3.scale.category20c();

// Util for getting the duration based on what has been selected
var getDuration = function() {
    var checkedDuration = $("#duration input[type=radio]:checked").val();

    return checkedDuration === "all" ? 0 : 1;
};

var durationRadioButtons = $("#duration input[type=radio][name=duration]");

var getNbaStatsAPI = function() {
    // Although we specify a Season, that doesn't matter since IsOnlyCurrentSeason is set
    // to 0, meaning the Season is ignored. We have to specify a Season otherwise we get
    // an error from the API.
    return "http://stats.nba.com/stats/commonallplayers/?LeagueID=00&Season=2014-15&IsOnlyCurrentSeason=" + getDuration();
};

var updateBubbleChart = function(data) {
    var formattedData = bubble.nodes(data).filter(d => { return !d.children; });

    var node = svg.selectAll(".node")
        .data(formattedData);

    // Capture enter selection
    var nodeEnter = node.enter()
        .append("g")
        .attr("class", "node")
        .attr("transform", d => { return `translate(${d.x}, ${d.y})`; });

    // Re-use enter selection for circles
    nodeEnter
        .append("circle")
        .attr("r", d => { return d.r; })
        .style("fill", (d, i) => { return color(i); });

    // Re-use enter selection for text
    text
        .data(formattedData)
        .text(d => {
            var threshold = getDuration() === 0 ? 15 : 2;
            if (d.value > threshold) { return d.name; }
        });

    node.select("circle")
        .transition().duration(1000)
        .attr("r", d => {
            return d.r;
        })
        .style("fill", (d, i) => {
            return color(i);
        });

    node.transition().attr("class", "node")
        .attr("transform", d => {
            return `translate(${d.x}, ${d.y})`;
        });

    node.exit().remove();
};

var renderBubbleChart = function(data) {
    var diameter = 680;

    bubble = d3.layout.pack()
        .sort(null)
        .size([diameter, diameter])
        .padding(1.5);

    svg = d3.select("#bubble-chart").append("svg")
        .attr("width", diameter)
        .attr("height", diameter)
        .attr("class", "bubble");

    var node = svg.selectAll(".node")
      .data(bubble.nodes(data).filter(d => { return !d.children; }))
      .enter().append("g")
        .attr("class", "node")
        .attr("transform", d => { return `translate(${d.x}, ${d.y})`; });

    node.append("circle")
      .attr("r", d => { return d.r; })
      .style("fill", d => { return color(d.name); })
      .on("mouseover", d => {
            return tooltip
                .style("visibility", "visible")
                .text(`${d.name} (${d.value})`);
      })
      .on("mousemove", _ => {
            var top = (event.pageY - 10);
            var left = (event.pageX + 10);

            return tooltip
                .style("top",  `${top}px`)
                .style("left", `${left}px`);
        })
      .on("mouseout", _ => {
            return tooltip.style("visibility", "hidden");
        });

    text = node.append("text")
      .attr("dy", ".3em")
      .attr("class", "bubble-text")
      .style("text-anchor", "middle")
      .style("pointer-events", "none")
      .text(d => {
        // Define a threshold for when to add some text to a bubble; with
        // all time names, we need to bump this up otherwise we will have
        // way too much text flying around in the UI.
        var threshold = getDuration() === 0 ? 15 : 2;

        if (d.value > threshold) { return d.name; }
      });

    tooltip = d3.select("#bubble-chart")
      .append("div")
      .classed("tooltip", true)
      .style("position", "absolute")
      .style("z-index", "10")
      .style("visibility", "hidden");

    d3.select(document.frameElement).style("height", `${diameter} px`);
};

var formatData = function(data) {
    var formattedData = [];

    Object.keys(data).forEach(key => {
        formattedData.push({
            name: key,
            value: data[key]
        });
    });

    return formattedData;
};

var getMostPupularNames = function(data) {
    var allPlayers = data.resultSets[0].rowSet;
    var mostPopularNames = {};

    allPlayers.forEach(player => {
        var playerFirstName = player[1].split(", ")[1];

        if (mostPopularNames.hasOwnProperty(playerFirstName)) {
            mostPopularNames[playerFirstName] += 1;
        } else {
            mostPopularNames[playerFirstName] = 1;
        }
    });

    return formatData(mostPopularNames);
};

var makeRequestAndRenderBubbleChart = function(renderFunction) {
    var nbaStatsAPI = getNbaStatsAPI();

    $.ajax(nbaStatsAPI, {
        dataType: "jsonp"
    })
    .done(function(data) {
        renderFunction({ children: getMostPupularNames(data) });
    });
};

var onDurationChange = function() {
    makeRequestAndRenderBubbleChart(updateBubbleChart);
};

// when the duration is changed, we will want to re-render
durationRadioButtons.change(onDurationChange);

makeRequestAndRenderBubbleChart(renderBubbleChart);<|endoftext|>


<commit_before>/* global $ */

$(function () {
    const gridSize = 4;

    const pokemonNames = [
        "blastoise", "blastoise",
        "charizard", "charizard",
        "dragonite", "dragonite",
        "gengar", "gengar",
        "magikarp", "magikarp",
        "mew", "mew",
        "pikachu", "pikachu",
        "venusaur", "venusaur"
    ];

    const pokemonTiles = pokemonNames.slice();

    function renderTiles() {
        let index = 0;

        for (let row = 0; row < gridSize; row += 1) {
            const $tileRow = $("

");

            for (let column = 0; column < gridSize; column += 1) {
                const $tile = $("

");

                $tile.attr("data-index", index);
                index += 1;

                $tileRow.append($tile);
            }

            $("#tiles").append($tileRow);
        }

        assignPokemonToTiles();
    }

    function shuffle(array) {
        let counter = array.length;

        // While there are elements in the array
        while (counter > 0) {
            // Pick a random index
            let index = Math.floor(Math.random() * counter);

            // Decrease counter by 1
            counter--;

            // And swap the last element with it
            let temp = array[counter];
            array[counter] = array[index];
            array[index] = temp;
        }

        return array;
    }

    function assignPokemonToTiles() {
        shuffle(pokemonTiles);

        for (let i = 0; i < pokemonTiles.length; ++i) {
            const $tile = $(`[data-index=${i}]`);
            $tile.data("pokemon", pokemonTiles[i]);
        }
    }

    function checkMatch() {
    }

    function onClickTile() {
    }

    function reset() {
    }

    $("#tiles").empty();

    renderTiles();
});
<commit_msg>Hooked up onClickTile event handler and added basic logic<commit_after>/* global $ */

$(function () {
    const gridSize = 4;

    const pokemonNames = [
        "blastoise", "blastoise",
        "charizard", "charizard",
        "dragonite", "dragonite",
        "gengar", "gengar",
        "magikarp", "magikarp",
        "mew", "mew",
        "pikachu", "pikachu",
        "venusaur", "venusaur"
    ];

    const pokemonTiles = pokemonNames.slice();

    function renderTiles() {
        let index = 0;

        for (let row = 0; row < gridSize; row += 1) {
            const $tileRow = $("

");

            for (let column = 0; column < gridSize; column += 1) {
                const $tile = $("

");

                $tile.attr("data-index", index);
                index += 1;

                $tileRow.append($tile);
            }

            $("#tiles").append($tileRow);
        }

        assignPokemonToTiles();
    }

    function shuffle(array) {
        let counter = array.length;

        // While there are elements in the array
        while (counter > 0) {
            // Pick a random index
            let index = Math.floor(Math.random() * counter);

            // Decrease counter by 1
            counter--;

            // And swap the last element with it
            let temp = array[counter];
            array[counter] = array[index];
            array[index] = temp;
        }

        return array;
    }

    function assignPokemonToTiles() {
        shuffle(pokemonTiles);

        for (let i = 0; i < pokemonTiles.length; ++i) {
            const $tile = $(`[data-index=${i}]`);
            $tile.data("pokemon", pokemonTiles[i]);
        }
    }

    function checkMatch() {
    }

    function onClickTile() {
        const pokemon = $(this).data("pokemon");

        $(this).addClass(pokemon);
        $(this).addClass("revealed");
    }

    function reset() {
    }

    $("#tiles").empty();

    renderTiles();

    $(".tile").on("click", onClickTile);
});
<|endoftext|>


<commit_before>(function($, UI) {

    "use strict";

    UI.component('tab', {

        defaults: {
            connect: false,
            active: 0
        },

        init: function() {

            var $this = this;

            this.on("click", this.options.target, function(e) {
                e.preventDefault();
                $this.find($this.options.target).not(this).removeClass("uk-active").blur();
                $this.trigger("change", [$(this).addClass("uk-active")]);
            });

            if (this.options.connect) {
                this.connect = $(this.options.connect);
            }

            if (location.hash && location.hash.match(/^#[a-z0-9_-]+$/)) {
                var active = this.element.children().filter(window.location.hash);

                if (active.length) {
                    this.element.children().removeClass('uk-active').filter(active).addClass("uk-active");
                }
            }

            // init responsive tab

            this.responsivetab = $('

').append('

');

            this.responsivetab.dropdown = this.responsivetab.find('.uk-dropdown');
            this.responsivetab.lst      = this.responsivetab.dropdown.find('ul');

            if (this.element.hasClass("uk-tab-bottom")) this.responsivetab.dropdown.addClass("uk-dropdown-up");
            if (this.element.hasClass("uk-tab-flip"))   this.responsivetab.dropdown.addClass("uk-dropdown-flip");

            // handle click
            this.responsivetab.lst.on('click', 'a', function(e) {

                if ($this.options.connect) {
                    e.preventDefault()
                    $this.element.data("switcher").show($(this).data('index'));
                }
            });

            // init UIkit components
            UI.switcher(this.element, {"toggle": ">li:not(.uk-tab-responsive)", "connect": this.options.connect, "active": this.options.active});
            UI.dropdown(this.responsivetab, {"mode": "click"});

            this.element.append(this.responsivetab);

            this.check();

            UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){

                $this.check();

            }, 100));

        },

        check: function() {

            var children = this.element.children(':not(.uk-tab-responsive)');

            if (children.length < 2) return;

            var top = (children.eq(0).offset().top + Math.ceil(children.eq(0).height()/2)), added = 0;

            children.removeClass('uk-hidden');

            this.responsivetab.lst.empty();
            this.responsivetab.removeClass('uk-hidden');

            for (var i = children.length - 1; i > 0; i--) {

                var item = children.eq(i);

                if (item.offset().top > top || (added && this.responsivetab.offset().top > top)) {

                    var link = item.find('a');

                    if (item.css('float') != 'none' && !item.attr('uk-dropdown')) {

                        item.addClass('uk-hidden');
                        if(!item.hasClass('uk-disabled')) {
                            this.responsivetab.lst.append('
'+link.html()+'
');
                            added++;
                        }
                    }
                }
            }

            this.responsivetab[this.responsivetab.lst.children().length ? 'removeClass':'addClass']('uk-hidden');
        }
    });

    $(document).on("uk-domready", function(e) {

        $("[data-uk-tab]").each(function() {
            var tab = $(this);

            if (!tab.data("tab")) {
                var obj = UI.tab(tab, UI.Utils.options(tab.attr("data-uk-tab")));
            }
        });
    });

})(jQuery, jQuery.UIkit);<commit_msg>made jshint safe<commit_after>(function($, UI) {

    "use strict";

    UI.component('tab', {

        defaults: {
            connect: false,
            active: 0
        },

        init: function() {

            var $this = this;

            this.on("click", this.options.target, function(e) {
                e.preventDefault();
                $this.find($this.options.target).not(this).removeClass("uk-active").blur();
                $this.trigger("change", [$(this).addClass("uk-active")]);
            });

            if (this.options.connect) {
                this.connect = $(this.options.connect);
            }

            if (location.hash && location.hash.match(/^#[a-z0-9_-]+$/)) {
                var active = this.element.children().filter(window.location.hash);

                if (active.length) {
                    this.element.children().removeClass('uk-active').filter(active).addClass("uk-active");
                }
            }

            // init responsive tab

            this.responsivetab = $('

').append('

');

            this.responsivetab.dropdown = this.responsivetab.find('.uk-dropdown');
            this.responsivetab.lst      = this.responsivetab.dropdown.find('ul');

            if (this.element.hasClass("uk-tab-bottom")) this.responsivetab.dropdown.addClass("uk-dropdown-up");
            if (this.element.hasClass("uk-tab-flip"))   this.responsivetab.dropdown.addClass("uk-dropdown-flip");

            // handle click
            this.responsivetab.lst.on('click', 'a', function(e) {

                if ($this.options.connect) {
                    e.preventDefault();
                    $this.element.data("switcher").show($(this).data('index'));
                }
            });

            // init UIkit components
            UI.switcher(this.element, {"toggle": ">li:not(.uk-tab-responsive)", "connect": this.options.connect, "active": this.options.active});
            UI.dropdown(this.responsivetab, {"mode": "click"});

            this.element.append(this.responsivetab);

            this.check();

            UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){

                $this.check();

            }, 100));

        },

        check: function() {

            var children = this.element.children(':not(.uk-tab-responsive)');

            if (children.length < 2) return;

            var top = (children.eq(0).offset().top + Math.ceil(children.eq(0).height()/2)), added = 0;

            children.removeClass('uk-hidden');

            this.responsivetab.lst.empty();
            this.responsivetab.removeClass('uk-hidden');

            for (var i = children.length - 1; i > 0; i--) {

                var item = children.eq(i);

                if (item.offset().top > top || (added && this.responsivetab.offset().top > top)) {

                    var link = item.find('a');

                    if (item.css('float') != 'none' && !item.attr('uk-dropdown')) {

                        item.addClass('uk-hidden');
                        if(!item.hasClass('uk-disabled')) {
                            this.responsivetab.lst.append('
'+link.html()+'
');
                            added++;
                        }
                    }
                }
            }

            this.responsivetab[this.responsivetab.lst.children().length ? 'removeClass':'addClass']('uk-hidden');
        }
    });

    $(document).on("uk-domready", function(e) {

        $("[data-uk-tab]").each(function() {
            var tab = $(this);

            if (!tab.data("tab")) {
                var obj = UI.tab(tab, UI.Utils.options(tab.attr("data-uk-tab")));
            }
        });
    });

})(jQuery, jQuery.UIkit);<|endoftext|>


<commit_before>/**
 * Deferred Object
 *
 * Used for building up a Query
 */

var _ = require('@sailshq/lodash');
var util = require('util');
var Promise = require('bluebird');

var normalize = require('../normalize');

// Alias "catch" as "fail", for backwards compatibility with projects
// that were created using Q
Promise.prototype.fail = Promise.prototype.catch;

var Deferred = module.exports = function(context, method, wlQueryInfo) {

  if (!context) {
    throw new Error('Must supply a context to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }
  if (!method) {
    throw new Error('Must supply a method to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }

  if (!wlQueryInfo) {
    throw new Error('Must supply a third arg (`wlQueryInfo`) to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }
  if (!_.isObject(wlQueryInfo)) {
    throw new Error('Third arg (`wlQueryInfo`) must be a valid dictionary. Usage: new Deferred(context, fn, wlQueryInfo)');
  }

  this._context = context;
  this._method = method;

  // Make sure `_wlQueryInfo` is always a dictionary.
  this._wlQueryInfo = wlQueryInfo || {};

  // Make sure `_wlQueryInfo.criteria` is always a dictionary
  this._wlQueryInfo.criteria = this._wlQueryInfo.criteria || {};

  // Attach `_wlQueryInfo.using` and set it equal to the model identity.
  // TODO

  // Make sure `._wlQueryInfo.values` is `null`, rather than simply undefined or any other falsey thing..
  // (This is just for backwards compatibility.  Could be removed if proven that it's safe.)
  this._wlQueryInfo.values = this._wlQueryInfo.values || null;

  // Initialize `_deferred` to `null`.
  // (this is used for promises)
  this._deferred = null;

  return this;
};

/**
 * Populate all associations of a collection.
 *
 * @return this
 * @chainable
 */
Deferred.prototype.populateAll = function(criteria) {
  var self = this;
  this._context.associations.forEach(function(association) {
    self.populate(association.alias, criteria);
  });
  return this;
};

/**
 * Add a `joins` clause to the criteria object.
 *
 * Used for populating associations.
 *
 * @param {String|Array} key, the key to populate or array of string keys
 * @return this
 * @chainable
 */

Deferred.prototype.populate = function(keyName, criteria) {
  var self = this;

  // Adds support for arrays into keyName so that a list of
  // populates can be passed
  if (_.isArray(keyName)) {
    _.each(keyName, function(populate) {
      self.populate(populate, criteria);
    });
    return this;
  }

  this._wlQueryInfo.criteria.populates = this._wlQueryInfo.criteria.populates || {};
  this._wlQueryInfo.criteria.populates[keyName] = criteria || {};

  return this;
};

/**
 * Add projections to the parent
 *
 * @param {Array} attributes to select
 * @return this
 */

Deferred.prototype.select = function(attributes) {
  if(!_.isArray(attributes)) {
    attributes = [attributes];
  }

  var select = this._wlQueryInfo.criteria.select || [];
  select = select.concat(attributes);
  this._wlQueryInfo.criteria.select = _.uniq(select);

  return this;
};

Deferred.prototype.omit = function(attributes) {
  if(!_.isArray(attributes)) {
    attributes = [attributes];
  }

  var omit = this._wlQueryInfo.criteria.omit || [];
  omit = omit.concat(attributes);
  this._wlQueryInfo.criteria.omit = _.uniq(omit);

  return this;
};

/**
 * Add a Where clause to the criteria object
 *
 * @param {Object} criteria to append
 * @return this
 */

Deferred.prototype.where = function(criteria) {

  if (!criteria) {
    return this;
  }

  if (!_.has(this._wlQueryInfo, 'criteria')) {
    this._wlQueryInfo.criteria = {};
  }

  var where = this._wlQueryInfo.criteria.where || {};

  // Merge with existing WHERE clause
  this._wlQueryInfo.criteria.where = _.merge({}, where, criteria);

  return this;
};

/**
 * Add a Limit clause to the criteria object
 *
 * @param {Integer} number to limit
 * @return this
 */

Deferred.prototype.limit = function(limit) {
  this._wlQueryInfo.criteria.limit = limit;

  return this;
};

/**
 * Add a Skip clause to the criteria object
 *
 * @param {Integer} number to skip
 * @return this
 */

Deferred.prototype.skip = function(skip) {
  this._wlQueryInfo.criteria.skip = skip;

  return this;
};

/**
 * Add a Paginate clause to the criteria object
 *
 * This is syntatical sugar that calls skip and
 * limit from a single function.
 *
 * @param {Object} page and limit
 * @return this
 */
Deferred.prototype.paginate = function(options) {
  var defaultLimit = 10;

  if (_.isUndefined(options)) {
    options = { page: 0, limit: defaultLimit };
  }

  var page = options.page || 0;
  var limit = options.limit || defaultLimit;
  var skip = 0;

  if (page > 0 && limit === 0) {
    skip = page - 1;
  }

  if (page > 0 && limit > 0) {
    skip = (page * limit) - limit;
  }

  this
  .skip(skip)
  .limit(limit);

  return this;
};

/**
 * Add a Sort clause to the criteria object
 *
 * @param {String|Object} key and order
 * @return this
 */

Deferred.prototype.sort = function(criteria) {

  if (!criteria) {
    return this;
  }

  // Normalize criteria
  criteria = normalize.criteria({ sort: criteria });

  var sort = this._wlQueryInfo.criteria.sort || {};

  _.each(criteria.sort, function(val, key) {
    sort[key] = criteria.sort[key];
  });

  this._wlQueryInfo.criteria.sort = sort;

  return this;
};

/**
 * Add a Sum clause to the criteria object
 *
 * @param {Array|Arguments} Keys to sum over
 * @return this
 */
Deferred.prototype.sum = function() {
  buildAggregate.call(this, 'sum', Array.prototype.slice.call(arguments));
  return this;
};

/**
 * Add an Average clause to the criteria object
 *
 * @param {Array|Arguments} Keys to average over
 * @return this
 */
Deferred.prototype.avg = function(attrName) {
  this._wlQueryInfo.numericAttrName = attrName;
  return this;
};

/**
 * Add values to be used in update or create query
 *
 * @param {Object, Array} values
 * @return this
 */

Deferred.prototype.set = function(values) {
  this._wlQueryInfo.values = values;

  return this;
};

/**
 * Pass metadata down to the adapter that won't be processed or touched by Waterline
 */

Deferred.prototype.meta = function(data) {
  this._meta = data;
  return this;
};

/**
 * Pass an active connection down to the query.
 */

Deferred.prototype.usingConnection = function(leasedConnection) {
  this._meta = this._meta || {};
  this._meta.leasedConnection = leasedConnection;
  return this;
};

/**
 * Execute a Query using the method passed into the
 * constuctor.
 *
 * @param {Function} callback
 * @return callback with parameters (err, results)
 */

Deferred.prototype.exec = function(cb) {
  if (_.isUndefined(cb)) {
    console.log(
      'Error: No callback supplied. Please define a callback function when executing a query.  '+
      'See http://sailsjs.com/docs/reference/waterline-orm/queries/exec for help.'
    );
    return;
  }

  var isValidCb = _.isFunction(cb) || (_.isObject(cb) && !_.isArray(cb));
  if (!isValidCb) {
    console.log(
      'Error: Sorry, `.exec()` doesn\'t know how to handle a callback like that:\n'+
      util.inspect(cb, {depth: null})+'\n'+
      'Instead, please provide a callback function when executing a query.  '+
      'See http://sailsjs.com/docs/reference/waterline-orm/queries/exec for help.'
    );
    return;
  }

  // Otherwise, the provided callback function is pretty cool, and all is right and well.

  // Normalize callback/switchback
  cb = normalize.callback(cb);

  // Set up arguments + callback
  var args = [this._wlQueryInfo.criteria, cb];
  if (this._wlQueryInfo.values) {
    args.splice(1, 0, this._wlQueryInfo.values);
  }

  // If there is a meta value, throw it on the very end
  if(this._meta) {
    args.push(this._meta);
  }

  // Pass control to the adapter with the appropriate arguments.
  this._method.apply(this._context, args);
};

/**
 * Executes a Query, and returns a promise
 */

Deferred.prototype.toPromise = function() {
  if (!this._deferred) {
    this._deferred = Promise.promisify(this.exec).bind(this)();
  }
  return this._deferred;
};

/**
 * Executes a Query, and returns a promise that applies cb/ec to the
 * result/error.
 */

Deferred.prototype.then = function(cb, ec) {
  return this.toPromise().then(cb, ec);
};

/**
 * Applies results to function fn.apply, and returns a promise
 */

Deferred.prototype.spread = function(cb) {
  return this.toPromise().spread(cb);
};

/**
 * returns a promise and gets resolved with error
 */

Deferred.prototype.catch = function(cb) {
  return this.toPromise().catch(cb);
};

/**
 * Alias "catch" as "fail"
 */
Deferred.prototype.fail = Deferred.prototype.catch;
<commit_msg>dynamically determine what args to send based on method<commit_after>/**
 * Deferred Object
 *
 * Used for building up a Query
 */

var _ = require('@sailshq/lodash');
var util = require('util');
var Promise = require('bluebird');

var normalize = require('../normalize');

// Alias "catch" as "fail", for backwards compatibility with projects
// that were created using Q
Promise.prototype.fail = Promise.prototype.catch;

var Deferred = module.exports = function(context, method, wlQueryInfo) {

  if (!context) {
    throw new Error('Must supply a context to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }
  if (!method) {
    throw new Error('Must supply a method to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }

  if (!wlQueryInfo) {
    throw new Error('Must supply a third arg (`wlQueryInfo`) to a new Deferred object. Usage: new Deferred(context, fn, wlQueryInfo)');
  }
  if (!_.isObject(wlQueryInfo)) {
    throw new Error('Third arg (`wlQueryInfo`) must be a valid dictionary. Usage: new Deferred(context, fn, wlQueryInfo)');
  }

  this._context = context;
  this._method = method;

  // Make sure `_wlQueryInfo` is always a dictionary.
  this._wlQueryInfo = wlQueryInfo || {};

  // Make sure `_wlQueryInfo.criteria` is always a dictionary
  this._wlQueryInfo.criteria = this._wlQueryInfo.criteria || {};

  // Attach `_wlQueryInfo.using` and set it equal to the model identity.
  // TODO

  // Make sure `._wlQueryInfo.values` is `null`, rather than simply undefined or any other falsey thing..
  // (This is just for backwards compatibility.  Could be removed if proven that it's safe.)
  this._wlQueryInfo.values = this._wlQueryInfo.values || null;

  // Initialize `_deferred` to `null`.
  // (this is used for promises)
  this._deferred = null;

  return this;
};

/**
 * Populate all associations of a collection.
 *
 * @return this
 * @chainable
 */
Deferred.prototype.populateAll = function(criteria) {
  var self = this;
  this._context.associations.forEach(function(association) {
    self.populate(association.alias, criteria);
  });
  return this;
};

/**
 * Add a `joins` clause to the criteria object.
 *
 * Used for populating associations.
 *
 * @param {String|Array} key, the key to populate or array of string keys
 * @return this
 * @chainable
 */

Deferred.prototype.populate = function(keyName, criteria) {
  var self = this;

  // Adds support for arrays into keyName so that a list of
  // populates can be passed
  if (_.isArray(keyName)) {
    _.each(keyName, function(populate) {
      self.populate(populate, criteria);
    });
    return this;
  }

  this._wlQueryInfo.criteria.populates = this._wlQueryInfo.criteria.populates || {};
  this._wlQueryInfo.criteria.populates[keyName] = criteria || {};

  return this;
};

/**
 * Add projections to the parent
 *
 * @param {Array} attributes to select
 * @return this
 */

Deferred.prototype.select = function(attributes) {
  if(!_.isArray(attributes)) {
    attributes = [attributes];
  }

  var select = this._wlQueryInfo.criteria.select || [];
  select = select.concat(attributes);
  this._wlQueryInfo.criteria.select = _.uniq(select);

  return this;
};

Deferred.prototype.omit = function(attributes) {
  if(!_.isArray(attributes)) {
    attributes = [attributes];
  }

  var omit = this._wlQueryInfo.criteria.omit || [];
  omit = omit.concat(attributes);
  this._wlQueryInfo.criteria.omit = _.uniq(omit);

  return this;
};

/**
 * Add a Where clause to the criteria object
 *
 * @param {Object} criteria to append
 * @return this
 */

Deferred.prototype.where = function(criteria) {

  if (!criteria) {
    return this;
  }

  if (!_.has(this._wlQueryInfo, 'criteria')) {
    this._wlQueryInfo.criteria = {};
  }

  var where = this._wlQueryInfo.criteria.where || {};

  // Merge with existing WHERE clause
  this._wlQueryInfo.criteria.where = _.merge({}, where, criteria);

  return this;
};

/**
 * Add a Limit clause to the criteria object
 *
 * @param {Integer} number to limit
 * @return this
 */

Deferred.prototype.limit = function(limit) {
  this._wlQueryInfo.criteria.limit = limit;

  return this;
};

/**
 * Add a Skip clause to the criteria object
 *
 * @param {Integer} number to skip
 * @return this
 */

Deferred.prototype.skip = function(skip) {
  this._wlQueryInfo.criteria.skip = skip;

  return this;
};

/**
 * Add a Paginate clause to the criteria object
 *
 * This is syntatical sugar that calls skip and
 * limit from a single function.
 *
 * @param {Object} page and limit
 * @return this
 */
Deferred.prototype.paginate = function(options) {
  var defaultLimit = 10;

  if (_.isUndefined(options)) {
    options = { page: 0, limit: defaultLimit };
  }

  var page = options.page || 0;
  var limit = options.limit || defaultLimit;
  var skip = 0;

  if (page > 0 && limit === 0) {
    skip = page - 1;
  }

  if (page > 0 && limit > 0) {
    skip = (page * limit) - limit;
  }

  this
  .skip(skip)
  .limit(limit);

  return this;
};

/**
 * Add a Sort clause to the criteria object
 *
 * @param {String|Object} key and order
 * @return this
 */

Deferred.prototype.sort = function(criteria) {

  if (!criteria) {
    return this;
  }

  // Normalize criteria
  criteria = normalize.criteria({ sort: criteria });

  var sort = this._wlQueryInfo.criteria.sort || {};

  _.each(criteria.sort, function(val, key) {
    sort[key] = criteria.sort[key];
  });

  this._wlQueryInfo.criteria.sort = sort;

  return this;
};

/**
 * Add a Sum clause to the criteria object
 *
 * @param {Array|Arguments} Keys to sum over
 * @return this
 */
Deferred.prototype.sum = function() {
  buildAggregate.call(this, 'sum', Array.prototype.slice.call(arguments));
  return this;
};

/**
 * Add an Average clause to the criteria object
 *
 * @param {Array|Arguments} Keys to average over
 * @return this
 */
Deferred.prototype.avg = function(attrName) {
  this._wlQueryInfo.numericAttrName = attrName;
  return this;
};

/**
 * Add values to be used in update or create query
 *
 * @param {Object, Array} values
 * @return this
 */

Deferred.prototype.set = function(values) {
  this._wlQueryInfo.values = values;

  return this;
};

/**
 * Pass metadata down to the adapter that won't be processed or touched by Waterline
 */

Deferred.prototype.meta = function(data) {
  this._meta = data;
  return this;
};

/**
 * Pass an active connection down to the query.
 */

Deferred.prototype.usingConnection = function(leasedConnection) {
  this._meta = this._meta || {};
  this._meta.leasedConnection = leasedConnection;
  return this;
};

/**
 * Execute a Query using the method passed into the
 * constuctor.
 *
 * @param {Function} callback
 * @return callback with parameters (err, results)
 */

Deferred.prototype.exec = function(cb) {
  if (_.isUndefined(cb)) {
    console.log(
      'Error: No callback supplied. Please define a callback function when executing a query.  '+
      'See http://sailsjs.com/docs/reference/waterline-orm/queries/exec for help.'
    );
    return;
  }

  var isValidCb = _.isFunction(cb) || (_.isObject(cb) && !_.isArray(cb));
  if (!isValidCb) {
    console.log(
      'Error: Sorry, `.exec()` doesn\'t know how to handle a callback like that:\n'+
      util.inspect(cb, {depth: null})+'\n'+
      'Instead, please provide a callback function when executing a query.  '+
      'See http://sailsjs.com/docs/reference/waterline-orm/queries/exec for help.'
    );
    return;
  }

  // Otherwise, the provided callback function is pretty cool, and all is right and well.

  // Normalize callback/switchback
  cb = normalize.callback(cb);

  // Build up the arguments based on the method
  var args;
  var query = this._wlQueryInfo;

  // Deterine what arguments to send based on the method
  switch (this._wlQueryInfo.method) {
    case 'join':
    case 'find':
    case 'findOne':
      args = [query.criteria, cb, this._meta];
      break;

    case 'create':
      args = [query.values, cb, this._meta];
      break;

    case 'update':
      args = [query.criteria, query.values, cb, this._meta];
      break;

    case 'destroy':
      args = [query.criteria, cb, this._meta];
      break;

    case 'avg':
      args = [query.numericAttrName, query.criteria, {}, cb, this._meta];
      break;

    default:
      args = [query.criteria, cb, this._meta];
  }

  // Pass control to the adapter with the appropriate arguments.
  this._method.apply(this._context, args);
};

/**
 * Executes a Query, and returns a promise
 */

Deferred.prototype.toPromise = function() {
  if (!this._deferred) {
    this._deferred = Promise.promisify(this.exec).bind(this)();
  }
  return this._deferred;
};

/**
 * Executes a Query, and returns a promise that applies cb/ec to the
 * result/error.
 */

Deferred.prototype.then = function(cb, ec) {
  return this.toPromise().then(cb, ec);
};

/**
 * Applies results to function fn.apply, and returns a promise
 */

Deferred.prototype.spread = function(cb) {
  return this.toPromise().spread(cb);
};

/**
 * returns a promise and gets resolved with error
 */

Deferred.prototype.catch = function(cb) {
  return this.toPromise().catch(cb);
};

/**
 * Alias "catch" as "fail"
 */
Deferred.prototype.fail = Deferred.prototype.catch;
<|endoftext|>