<commit_before>/**
 * map tab shown in cartodb admin
 */

cdb.admin.MapTab = cdb.core.View.extend({

  className: 'map',

  initialize: function() {
    this.map = this.model;
    this.map_enabled = false;
    this.infowindowModel = this.options.infowindow;

    //this.add_related_model(this.options.dataLayer);
    this.add_related_model(this.map);
    this.add_related_model(this.options.table);
    this.add_related_model(this.infowindowModel);
  },

  /**
   * map can't be loaded from the beggining, it needs the DOM to be loaded
   * so we wait until is actually shown to create the mapview and show it
   */
  enableMap: function() {
    var self = this;
    if(!this.map_enabled) {
      var div = $('<div>').attr("id","map")
        , base_maps = $('<div>').attr("class","base_maps");

      this.baseLayerChooser = new cdb.admin.BaseMapChooser({
        model: this.map,
        baseLayers: this.options.baseLayers
      });

      base_maps.append(this.baseLayerChooser.render().el);

      this.$el.append(div);
      this.$el.append(base_maps);
      this.mapView = new cdb.geo.LeafletMapView({
        el: div,
        map: this.map
      });
      this.map_enabled = true;

      this.mapView.bind('newLayerView', self._bindDataLayer, self);

      var zoomControl = new cdb.geo.ui.Zoom({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/zoom_control")
      });
      this.$el.append(zoomControl.render().$el);

      self.infowindow = new cdb.admin.MapInfowindow({
        model: self.infowindowModel,
        template: cdb.templates.getTemplate('table/views/infowindow'),
        mapView: self.mapView,
        table: self.options.table
      });
      self.mapView.$el.append(self.infowindow.el);

    }
  },

  /**
   * when the layer view is created this method is called
   * to attach all the click events
   */
  _bindDataLayer: function(layer) {
    var self = this;
    if(layer.model.get('type') === 'CartoDB') {
      // unbind previos stuff
      if(self.layerDataView) {
        self.layerDataView.unbind(null, null, this);
      }

      self.layerDataView = self.mapView.getLayerByCid(self.map.get('dataLayer').cid);
      if(self.layerDataView) {
        self.layerDataView.bind('featureClick', self.featureClick, self);
      }
    }
  },

  featureClick: function(e, latlon, pxPos, data) {
    if(data.cartodb_id) {
      this.infowindow
        .setLatLng(latlon)
        .setFeatureInfo(data.cartodb_id)
        .showInfowindow();
    } else {
      cdb.log.error("can't show infowindow, no cartodb_id on data");
    }
  },

  render: function() {
    // this.$el.css({'height': '900px'});
    return this;
  }

});

<commit_msg>fixed map initialization when the models are already loaded<commit_after>/**
 * map tab shown in cartodb admin
 */

cdb.admin.MapTab = cdb.core.View.extend({

  className: 'map',

  initialize: function() {
    this.map = this.model;
    this.map_enabled = false;
    this.infowindowModel = this.options.infowindow;

    //this.add_related_model(this.options.dataLayer);
    this.add_related_model(this.map);
    this.add_related_model(this.options.table);
    this.add_related_model(this.infowindowModel);
  },

  /**
   * map can't be loaded from the beggining, it needs the DOM to be loaded
   * so we wait until is actually shown to create the mapview and show it
   */
  enableMap: function() {
    var self = this;
    if(!this.map_enabled) {
      var div = $('<div>').attr("id","map")
        , base_maps = $('<div>').attr("class","base_maps");

      this.baseLayerChooser = new cdb.admin.BaseMapChooser({
        model: this.map,
        baseLayers: this.options.baseLayers
      });

      base_maps.append(this.baseLayerChooser.render().el);

      this.$el.append(div);
      this.$el.append(base_maps);
      this.mapView = new cdb.geo.LeafletMapView({
        el: div,
        map: this.map
      });
      this.map_enabled = true;

      this.mapView.bind('newLayerView', self._bindDataLayer, self);

      // bind data layer if it is already added to the map
      var dataLayer = this.map.get('dataLayer');
      if(dataLayer) {
        var dl = this.mapView.getLayerByCid(self.map.get('dataLayer').cid);
        this._bindDataLayer(dl);
      }

      var zoomControl = new cdb.geo.ui.Zoom({
        model:    this.map,
        template: cdb.templates.getTemplate("table/views/zoom_control")
      });
      this.$el.append(zoomControl.render().$el);

      self.infowindow = new cdb.admin.MapInfowindow({
        model: self.infowindowModel,
        template: cdb.templates.getTemplate('table/views/infowindow'),
        mapView: self.mapView,
        table: self.options.table
      });
      self.mapView.$el.append(self.infowindow.el);

    }
  },

  /**
   * when the layer view is created this method is called
   * to attach all the click events
   */
  _bindDataLayer: function(layer) {
    var self = this;
    if(layer.model.get('type') === 'CartoDB') {
      // unbind previos stuff
      if(self.layerDataView) {
        self.layerDataView.unbind(null, null, this);
      }

      self.layerDataView = self.mapView.getLayerByCid(self.map.get('dataLayer').cid);
      if(self.layerDataView) {
        self.layerDataView.bind('featureClick', self.featureClick, self);
      }
    }
  },

  featureClick: function(e, latlon, pxPos, data) {
    if(data.cartodb_id) {
      this.infowindow
        .setLatLng(latlon)
        .setFeatureInfo(data.cartodb_id)
        .showInfowindow();
    } else {
      cdb.log.error("can't show infowindow, no cartodb_id on data");
    }
  },

  render: function() {
    // this.$el.css({'height': '900px'});
    return this;
  }

});

<|endoftext|>


<commit_before>// var getCoords = function() {
  // console.log('fuck');
  navigator.geolocation.getCurrentPosition(function(position) {
    console.log(position.coords.latitude, position.coords.longitude);
    makeMap({lat: position.coords.latitude, lng: position.coords.longitude});
  }, function(err) {
    console.error(err);
  });
  // console.log(navigator.geolocation);
// };
var map;
var marker;
var destinationMarker;
var makeMap = function(currentLatLngObj) {
  map = new google.maps.Map(document.getElementById('map'), {
    center: currentLatLngObj,
    zoom: 14
  });
  marker = new google.maps.Marker({
    position: currentLatLngObj,
    map: map,
    animation: google.maps.Animation.DROP,
    icon: './bolt.png'
  });
  destinationMarker = new google.maps.Marker({
    position: randomCoordsAlongCircumference(currentLatLngObj, 1),
    map: map,
    animation: google.maps.Animation.DROP,
    icon: './finish-line.png' // change to finish line image
  });
};

var randomCoordsAlongCircumference = function(originObj, radius) {
  var randomTheta = Math.random() * 2 * Math.PI;
  console.log('called');
  console.log('randomTheta: ', randomTheta);
  console.log('current lat and long: ');
  console.log(originObj);
  console.log('random lat: ', originObj.lat + (radius * Math.cos(randomTheta)));
  console.log('random lng: ', originObj.lng + (radius * Math.sin(randomTheta)));
  return {
    lat: originObj.lat + (radius / 69 * Math.cos(randomTheta)),
    lng: originObj.lng + (radius / 69 * Math.sin(randomTheta))
  };
};<commit_msg>Clean up map.js<commit_after>navigator.geolocation.getCurrentPosition(function(position) {
  makeMap({lat: position.coords.latitude, lng: position.coords.longitude});
}, function(err) {
  console.error(err);
});
var map;
var marker;
var destinationMarker;
var makeMap = function(currentLatLngObj) {
  map = new google.maps.Map(document.getElementById('map'), {
    center: currentLatLngObj,
    zoom: 13
  });
  marker = new google.maps.Marker({
    position: currentLatLngObj,
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/bolt.png'
  });
  destinationMarker = new google.maps.Marker({
    position: randomCoordsAlongCircumference(currentLatLngObj, 1),
    map: map,
    animation: google.maps.Animation.DROP,
    icon: '/assets/finish-line.png' // change to finish line image
  });
};

var randomCoordsAlongCircumference = function(originObj, radius) {
  var randomTheta = Math.random() * 2 * Math.PI;
  return {
    lat: originObj.lat + (radius / 69 * Math.cos(randomTheta)),
    lng: originObj.lng + (radius / 69 * Math.sin(randomTheta))
  };
};<|endoftext|>


<commit_before>/*
Copyright 2016 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import sendToServer from 'merchant-server';

const SHIPPING_OPTIONS = {
  us: [
    {
      id: 'standard',
      label: 'Standard Shipping',
      price: 0
    },
    {
      id: 'express',
      label: 'Express Shipping',
      price: 10
    }
  ],
  international: [
    {
      id: 'international',
      label: 'International Shipping',
      price: 15
    }
  ]
};

export default class PaymentAPIWrapper {

  /*
  * Given a cart set up with an order, gets payment authorization.
  * Returns a promise that resolves when payment is complete, this
  * has a data object you can pass to the back-end payment server.
  */
  checkout(cart) {
    let request = this.buildPaymentRequest(cart);
    let response;
    // Show UI then continue with user payment info

    // TODO PAY-6 - display the PaymentRequest

  }

  /*
   * Creates a PaymentRequest object including the event handlers used to
   * update the payment details as the user makes choices.
   */
  buildPaymentRequest(cart) {
    // Supported payment instruments
    const supportedInstruments = [
      // TODO PAY-3 - add a list of accepted payment methods
      {
        supportedMethods: ['basic-card'],
        data: {
          supportedNetworks: []
        }
      }
    ];

    // Payment options
    const paymentOptions = {

      // TODO PAY-5 - add payment options

    };

    let shippingOptions = [];
    let selectedOption = null;

    let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);

    // TODO PAY-2.2 - initialize the PaymentRequest object

    // When user selects a shipping address, add shipping options to match
    request.addEventListener('shippingaddresschange', e => {
      e.updateWith((_ => {
        // Get the shipping options and select the least expensive
        shippingOptions = this.optionsForCountry(request.shippingAddress.country);
        selectedOption = shippingOptions[0].id;
        let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);
        return Promise.resolve(details);
      })());
    });

    // When user selects a shipping option, update cost, etc. to match
    request.addEventListener('shippingoptionchange', e => {
      e.updateWith((_ => {
        selectedOption = request.shippingOption;
        let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);
        return Promise.resolve(details);
      })());
    });

    return request;
  }

  /*
   * Creates the PaymentDetails dictionary inside the PaymentRequest.
   * This can change as the user selects shipping options.
   */
  buildPaymentDetails(cart, shippingOptions, shippingOptionId) {

    // TODO PAY-4.2 - define the display items

    let total = cart.total;

    // TODO PAY-4.3 - define the shipping options

    // TODO PAY-4.1 - define the details object
  }

  /*
   * Utility function to extract the correct shipping options for a country.
   */
  optionsForCountry(country) {
    country = country.toLowerCase();
    if (!country || !SHIPPING_OPTIONS.hasOwnProperty(country)) {
      country = 'international';
    }
    let options = SHIPPING_OPTIONS[country];
    // Sort by price, lowest first
    options.sort((a, b) => {
      return a.price - b.price;
    });
    return options;
  }

}
<commit_msg>update TODO numbering<commit_after>/*
Copyright 2016 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import sendToServer from 'merchant-server';

const SHIPPING_OPTIONS = {
  us: [
    {
      id: 'standard',
      label: 'Standard Shipping',
      price: 0
    },
    {
      id: 'express',
      label: 'Express Shipping',
      price: 10
    }
  ],
  international: [
    {
      id: 'international',
      label: 'International Shipping',
      price: 15
    }
  ]
};

export default class PaymentAPIWrapper {

  /*
  * Given a cart set up with an order, gets payment authorization.
  * Returns a promise that resolves when payment is complete, this
  * has a data object you can pass to the back-end payment server.
  */
  checkout(cart) {
    let request = this.buildPaymentRequest(cart);
    let response;
    // Show UI then continue with user payment info

    // TODO PAY-5 - display the PaymentRequest
    return request.show();
  }

  /*
   * Creates a PaymentRequest object including the event handlers used to
   * update the payment details as the user makes choices.
   */
  buildPaymentRequest(cart) {
    // Supported payment instruments
    const supportedInstruments = [
      // TODO PAY-3 - add a list of accepted payment methods
      {
        supportedMethods: ['basic-card'],
        data: {
          supportedNetworks: []
        }
      }
    ];

    // Payment options
    const paymentOptions = {

      // TODO PAY-5 - add payment options

    };

    let shippingOptions = [];
    let selectedOption = null;

    let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);

    // TODO PAY-2.2 - initialize the PaymentRequest object

    // When user selects a shipping address, add shipping options to match
    request.addEventListener('shippingaddresschange', e => {
      e.updateWith((_ => {
        // Get the shipping options and select the least expensive
        shippingOptions = this.optionsForCountry(request.shippingAddress.country);
        selectedOption = shippingOptions[0].id;
        let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);
        return Promise.resolve(details);
      })());
    });

    // When user selects a shipping option, update cost, etc. to match
    request.addEventListener('shippingoptionchange', e => {
      e.updateWith((_ => {
        selectedOption = request.shippingOption;
        let details = this.buildPaymentDetails(cart, shippingOptions, selectedOption);
        return Promise.resolve(details);
      })());
    });

    return request;
  }

  /*
   * Creates the PaymentDetails dictionary inside the PaymentRequest.
   * This can change as the user selects shipping options.
   */
  buildPaymentDetails(cart, shippingOptions, shippingOptionId) {

    // TODO PAY-4.2 - define the display items
    let displayItems = [];

    let total = cart.total;

    // TODO PAY-7.3 - allow shipping options

    let details = {
      displayItems: displayItems,
      total: {
        label: 'Total due',
        amount: {currency: 'USD', value: String(total)}
      }
      // TODO PAY-7.2 - allow shipping options
    };

    return details;
  }

  /*
   * Utility function to extract the correct shipping options for a country.
   */
  optionsForCountry(country) {
    country = country.toLowerCase();
    if (!country || !SHIPPING_OPTIONS.hasOwnProperty(country)) {
      country = 'international';
    }
    let options = SHIPPING_OPTIONS[country];
    // Sort by price, lowest first
    options.sort((a, b) => {
      return a.price - b.price;
    });
    return options;
  }

}
<|endoftext|>


<commit_before>var tab_completion = require('../');

if (process.env.VAGRANT !== 'true' || process.env.TRAVIS !== 'true') {
  throw new Error('Tests must be run in enclosed environment (e.g. Vagrant, Travis) to prevent accidents on host OS');
}

describe('tab-completion', function () {
  before(function () {
    // http://stackoverflow.com/a/9505024/1960509
    // COMP_LINE="foundry re" COMP_WORDS=(foundry re) COMP_CWORD=1 COMP_POINT=10 $(complete -p foundry | sed "s/.*-F \\([^ ]*\\) .*/\\1/") && echo ${COMPREPLY[*]}
  });

  it('', function () {

  });
});
<commit_msg>Updated comments<commit_after>// Load dependencies
var TabCompletion = require('../');

// Verify we are in a contained environment
if (process.env.VAGRANT !== 'true' && process.env.TRAVIS !== 'true') {
  throw new Error('Tests must be run in enclosed environment (e.g. Vagrant, Travis) to prevent accidents on host OS');
}

// Start our tests
describe('tab-completion', function () {
  before(function () {
    // http://stackoverflow.com/a/9505024/1960509
    // COMP_LINE="foundry re" COMP_WORDS=(foundry re) COMP_CWORD=1 COMP_POINT=10 $(complete -p foundry | sed "s/.*-F \\([^ ]*\\) .*/\\1/") && echo ${COMPREPLY[*]}
  });

  it('', function () {

  });
});
<|endoftext|>


<commit_before>var cards = {};

function Card(attributes){
	this.id = attributes.id;
    this.name = attributes.name;
    this.c_type = attributes.c_type;
    this.bonus = attributes.bonus;
    this.apr = attributes.apr;
    this.anual_fee = attributes.anual_fee;
    this.credit_needed = attributes.credit_needed;
    this.balance_transfer_apr = attributes.balance_transfer_apr;
    this.category = attributes.category.title;
    this.bank_partners = attributes.bank_partners;
    this.balance_transfer_period = attributes.balance_transfer_period;
    this.corp_url = attributes.corp_url;
};

Card.getCard = function(cardNode){
    $.ajax({
    	url: cardNode.href,
    	dataType: "json",
    	method: 'GET'
    })
    .success(function(data){
    	var newCard = Card.makeCard(data)
    	var cardModal = newCard.renderModal()
    	$('div.cards_list').append(cardModal);
    	newCard.showCard();
    })
};

Card.prototype.showCard = function(){
   $(`#modalCard${this.id}`)[0].style.display = "block";
};

Card.makeCard = function(json){
    var card = new Card(json);
    cards[card.id] = card;
    return card;
};

Card.prototype.renderModal = function(){
    return Card.modalTemplate(this)
};

function closeModal(card){
	card.parentElement.parentElement.style.display = "none"
};

$(function(){
    Card.modalTemplateSource = $('#cardModalTemplate').html();
    Card.modalTemplate = Handlebars.compile(Card.modalTemplateSource);

    Card.modalFormTemplateSource = $('#newCardFormModalTemplate').html();
    Card.formModalTemplate = Handlebars.compile(Card.modalFormTemplateSource)

	$('a.card_name').on("click", function(event){
		event.preventDefault();
	    if(cards[this.dataset.id]){
		    cards[this.dataset.id].showCard()
		}else{
			Card.getCard(this)
		}
	});

	$('div.admin_section #admin_creat_new_card').on("click", function(){

	});
})

<commit_msg>added new event handler for create new card in admin mode. added new renderFormModal function to render the form template<commit_after>var cards = {};

function Card(attributes){
	this.id = attributes.id;
    this.name = attributes.name;
    this.c_type = attributes.c_type;
    this.bonus = attributes.bonus;
    this.apr = attributes.apr;
    this.anual_fee = attributes.anual_fee;
    this.credit_needed = attributes.credit_needed;
    this.balance_transfer_apr = attributes.balance_transfer_apr;
    this.category = attributes.category.title;
    this.bank_partners = attributes.bank_partners;
    this.balance_transfer_period = attributes.balance_transfer_period;
    this.corp_url = attributes.corp_url;
};

Card.getCard = function(cardNode){
    $.ajax({
    	url: cardNode.href,
    	dataType: "json",
    	method: 'GET'
    })
    .success(function(data){
    	var newCard = Card.makeCard(data)
    	var cardModal = newCard.renderModal()
    	$('div.cards_list').append(cardModal);
    	newCard.showCard();
    })
};

Card.prototype.showCard = function(){
   $(`#modalCard${this.id}`)[0].style.display = "block";
};

Card.makeCard = function(json){
    var card = new Card(json);
    cards[card.id] = card;
    return card;
};

Card.prototype.renderModal = function(){
    return Card.modalTemplate(this)
};

//the bankPartner script depends on this function as well
function closeModal(card){
	card.parentElement.parentElement.style.display = "none"
};

Card.renderFormModal = function(){
	var formTemplate = Card.formModalTemplate({name: "cardNewForm"});
    $('#main_page').append(formTemplate);
};

$(function(){
    Card.modalTemplateSource = $('#cardModalTemplate').html();
    Card.modalTemplate = Handlebars.compile(Card.modalTemplateSource);

    Card.modalFormTemplateSource = $('#newCardFormModalTemplate').html();
    Card.formModalTemplate = Handlebars.compile(Card.modalFormTemplateSource)

	$('a.card_name').on("click", function(event){
		event.preventDefault();
	    if(cards[this.dataset.id]){
		    cards[this.dataset.id].showCard()
		}else{
			Card.getCard(this)
		}
	});

	$('div.admin_section #admin_creat_new_card').on("click", function(event){
		event.preventDefault();
		Card.renderFormModal();
	});
})

<|endoftext|>


<commit_before>import {format, formatPrefix} from "d3-format";
import {timeFormat} from "d3-time-format";

function abbreviate(n) {
  const length = n.toString().split(".")[0].length;

  if (n === 0) return "0";
  else if (length > 3) return formatPrefix(",.0", n)(n).replace("G", "B");
  else if (length === 3) return format(",f")(n);
  else if (n === parseInt(n, 10)) return format(".2")(n);
  else return format(".3g")(n);

}

export const FORMATTERS = {
  commas: format(","),
  date: timeFormat("%B %d, %Y"),
  ordinal: n => {
    if (n > 3 && n < 21) return `${n}th`; // thanks kennebec
    switch (n % 10) {
      case 1: return `${n}st`;
      case 2: return `${n}nd`;
      case 3: return `${n}rd`;
      default: return `${n}th`;
    }
  },
  round: format(",.0f"),
  share: format(".2%"),
  shareWhole: format(".0%"),
  year: y => y < 0 ? `${Math.abs(y)} BC` : y
};

export const VARIABLES = {
  harvested_area: d => `${abbreviate(d)} ha`,
  rainfall_awa_mm: d => `${FORMATTERS.round(d)}mm`,
  value_of_production: d => `Intl.$${abbreviate(d)}`,
  value_density: d => `Intl.$ ${abbreviate(d)} per ha`,
  totpop: d => abbreviate(d)
};
<commit_msg>check for invalid values and return N/A<commit_after>import {format, formatPrefix} from "d3-format";
import {timeFormat} from "d3-time-format";

function abbreviate(n) {
  if (n === undefined || n === null) return "N/A";

  const length = n.toString().split(".")[0].length;

  if (n === 0) return "0";
  else if (length > 3) return formatPrefix(",.0", n)(n).replace("G", "B");
  else if (length === 3) return format(",f")(n);
  else if (n === parseInt(n, 10)) return format(".2")(n);
  else return format(".3g")(n);

}

export const FORMATTERS = {
  commas: format(","),
  date: timeFormat("%B %d, %Y"),
  ordinal: n => {
    if (n > 3 && n < 21) return `${n}th`; // thanks kennebec
    switch (n % 10) {
      case 1: return `${n}st`;
      case 2: return `${n}nd`;
      case 3: return `${n}rd`;
      default: return `${n}th`;
    }
  },
  round: format(",.0f"),
  share: format(".2%"),
  shareWhole: format(".0%"),
  year: y => y < 0 ? `${Math.abs(y)} BC` : y
};

export const VARIABLES = {
  harvested_area: d => `${abbreviate(d)} ha`,
  rainfall_awa_mm: d => `${FORMATTERS.round(d)}mm`,
  value_of_production: d => `Intl.$${abbreviate(d)}`,
  value_density: d => `Intl.$ ${abbreviate(d)} per ha`,
  totpop: d => abbreviate(d)
};
<|endoftext|>


<commit_before>
// test radial transverse plotStartDate

// seisplotjs comes from the seisplotjs standalone bundle
var wp = seisplotjs.waveformplot;
var traveltime = seisplotjs.traveltime;
var fdsnevent = seisplotjs.fdsnevent;
var fdsnstation = seisplotjs.fdsnstation;
var miniseed = seisplotjs.miniseed;

var USGS = "earthquake.usgs.gov";
var IRIS = "service.iris.edu";

fdsnstation.RSVP.on('error', function(reason) {
  console.assert(false, reason);
});

var daysAgo = 365;
var netCode = 'US';
var staCode = 'LONY';
var locCode = '--';
var chanCode = 'BH?';
var datahost = IRIS;
var quakehost = USGS;
var preOffset = 5;
var dur = 25;

var protocol = 'http:';
if ("https:" == document.location.protocol) {
  protocol = 'https:'
}
console.log("Protocol: "+protocol+"  host: "+quakehost);

var quakeQuery = new fdsnevent.EventQuery()
  .host(quakehost)
  .protocol(protocol)
  .minLat(36).maxLat(37)
  .minLon(-4).maxLon(-3)
  .startTime(new Date("2010-04-11T22:08:00.000Z"))
  .endTime(new Date("2010-04-11T22:09:00.000Z"));
wp.d3.select("div.recentQuakesUrl")
    .append("p")
    .text("Quakes URL: "+quakeQuery.formURL());

var stationQuery = new fdsnstation.StationQuery()
  .protocol(protocol)
  .networkCode(netCode)
  .stationCode(staCode)
  .channelCode(chanCode);
wp.d3.select("div.recentQuakesUrl")
    .append("p")
    .text("Stations URL: "+stationQuery.formURL(fdsnstation.LEVEL_STATION));

var stationPromise = stationQuery.queryStations().then(function(netArray) {
          staCodes = [];
          for (var i=0;i<netArray[0].stations().length; i++) {
            staCodes.push(netArray[0].stations()[i].stationCode());
          }
          console.log("sta codes: "+staCodes.join());
          return netArray[0].stations()[0];
});

var quakePromise = quakeQuery.query().then(function(quakes) {
  var q = quakes[0];
  console.log("quake: "+q.time().toISOString()+" "+q.magnitude().mag()+" "
        +q.magnitude().type()+" ("+q.latitude()+", "+q.longitude()+") "
        +(q.depth()/1000)+" km ");
  return q;
});

var bothPromise = fdsnstation.RSVP.hash({
    station: stationPromise,
    quake: quakePromise
  }).then(function(hash) {
    console.log("quake network Promise then");
    console.log("distaz for "+hash.quake.latitude()+" "+ hash.quake.longitude()+" "+ hash.station.latitude()+" "+hash.station.longitude());
    hash.distaz = seisplotjs.distaz.distaz(hash.station.latitude(), hash.station.longitude(), hash.quake.latitude(), hash.quake.longitude());
    hash.traveltime = new traveltime.TraveltimeQuery()
        .protocol(protocol)
        .evdepth( hash.quake.depth() > 0 ? hash.quake.depth()/1000 : 0)
        .evlat(hash.quake.latitude()).evlon(hash.quake.longitude())
        .stalat(hash.station.latitude()).stalon(hash.station.longitude())
        .phases('p,P,PKP,PKIKP,Pdiff,s,S,Sdiff,PKP,SKS,SKIKS')
        .query()
        .then(function(ttimes) {
          var firstP = null;
          var firstS = null;
          for (var p=0; p<ttimes.arrivals.length; p++) {
            if ((ttimes.arrivals[p].phase.startsWith('P') || ttimes.arrivals[p].phase.startsWith('p')) && ( ! firstP || firstP.time > ttimes.arrivals[p])) {
              firstP = ttimes.arrivals[p];
            }
            if ((ttimes.arrivals[p].phase.startsWith('S') || ttimes.arrivals[p].phase.startsWith('s')) && ( ! firstS || firstS.time > ttimes.arrivals[p])) {
              firstS = ttimes.arrivals[p];
            }
          }
          return { firstP: firstP, firstS: firstS, arrivals: ttimes.arrivals };
        });
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {
    hash.S_arrival = new Date(hash.quake.time().getTime()+(hash.traveltime.firstS.time)*1000);
    hash.P_arrival = new Date(hash.quake.time().getTime()+(hash.traveltime.firstP.time)*1000);
    hash.seisDates = wp.calcStartEndDates(new Date(hash.S_arrival.getTime()-preOffset*1000), null, dur, 0);
    hash.miniseed = new seisplotjs.fdsndataselect.DataSelectQuery()
      .host(IRIS)
      .nodata(404)
      .networkCode(hash.station.network().networkCode())
      .stationCode(hash.station.stationCode())
      .locationCode(locCode)
      .channelCode(chanCode)
      .startTime(hash.seisDates.start)
      .endTime(hash.seisDates.end)
      .query();
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {

    let byChannel = miniseed.byChannel(hash.miniseed);
    let keys = Array.from(byChannel.keys());
    console.log("keys: "+keys);
    hash.seismograms = [];
    for(let i=0; i<keys.length; i++) {
      let key = keys[i];
      hash.seismograms.push(miniseed.merge(byChannel.get(key)));
    }
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {
    let div = seisplotjs.d3.select("div.seismograms");
    let svgDiv = div.append("div");
    svgDiv.classed("svg-container-wide", true);
    if (hash.seismograms.length > 0) {
      console.log("hash.seismograms "+hash.seismograms.length+" "+hash.seismograms[0].length);
        var seismograph = new wp.Seismograph(svgDiv, hash.seismograms, hash.seisDates.start, hash.seisDates.end);
        titles = [hash.seismograms[0][0].codes(),
                  hash.seismograms[1][0].chanCode(),
                  hash.seismograms[2][0].chanCode()];
        seismograph.setTitle(titles);
        var markers = [];
          markers.push({ markertype: 'predicted', name: "origin", time: hash.quake.time() });
          markers.push({ markertype: 'predicted', name: hash.traveltime.firstP.phase, time: hash.P_arrival });
          markers.push({ markertype: 'predicted', name: hash.traveltime.firstS.phase, time: hash.S_arrival });

        if (hash.quake.arrivals()) {
          for ( let aNum=0; aNum < hash.quake.arrivals().length; aNum++) {
            let arrival = hash.quake.arrivals()[aNum];
            if (! arrival) {console.log("arrival is undef??? "+aNum); }
            if (arrival && arrival.pick().stationCode() == mystation.stationCode()) {
              markers.push({ markertype: 'pick', name: arrival.phase(), time: arrival.pick().time() });
              console.log("markers.push({ markertype: 'pick', name: "+arrival.phase()+", time: "+arrival.pick().time() );
            }
          }
        }
        seismograph.appendMarkers(markers);
        seismograph.draw();

        // rotated
        console.log("### Rotated");

        let rotdiv = seisplotjs.d3.select("div.rotatedseismograms");
        let rotsvgDiv = rotdiv.append("div");
        rotsvgDiv.classed("svg-container-wide", true);

        var seisZ = null;
        var seisNorth = null;
        var seisEast = null;
        for (var i = 0; i < hash.seismograms.length; i++) {
          if (hash.seismograms[i][0].chanCode().charAt(2) === "Z") {
            seisZ = hash.seismograms[i];
          }
          if (hash.seismograms[i][0].chanCode().charAt(2) === "N") {
            seisNorth = hash.seismograms[i];
          }
          if (hash.seismograms[i][0].chanCode().charAt(2) === "E") {
            seisEast = hash.seismograms[i];
          }
        }
        if ( ! seisZ || ! seisNorth || ! seisEast) {
          throw new Error("unable to find ZNE: "+seisZ+" "+seisNorth+" "+seisEast);
        }
console.log("rotate to "+hash.distaz.baz+" "+((hash.distaz.baz+180)%360) );
        var rotated = seisplotjs.filter.rotate(seisNorth[0], 0, seisEast[0], 90, (hash.distaz.baz+180)%360);
        hash.rotatedSeismograms = [seisZ, [rotated.radial], [rotated.transverse]];
console.log("first points: "+seisZ[0].yAtIndex(0)+" "+rotated.radial.yAtIndex(0)+" "+rotated.transverse.yAtIndex(0))
        var rotatedSeismograph = new wp.Seismograph(rotsvgDiv, hash.rotatedSeismograms, hash.seisDates.start, hash.seisDates.end);
        titles = [hash.rotatedSeismograms[0][0].codes(),
                  hash.rotatedSeismograms[1][0].chanCode()+" "+rotated.azimuthRadial,
                  hash.rotatedSeismograms[2][0].chanCode()+" "+rotated.azimuthTransverse];
        rotatedSeismograph.setTitle(titles);
        var rotateMarkers = [];
          rotateMarkers.push({ markertype: 'predicted', name: "origin", time: hash.quake.time() });
          rotateMarkers.push({ markertype: 'predicted', name: hash.traveltime.firstP.phase, time: hash.P_arrival });
          rotateMarkers.push({ markertype: 'predicted', name: hash.traveltime.firstS.phase, time: hash.S_arrival });

        if (hash.quake.arrivals()) {
          for ( let aNum=0; aNum < hash.quake.arrivals().length; aNum++) {
            let arrival = hash.quake.arrivals()[aNum];
            if (! arrival) {console.log("arrival is undef??? "+aNum); }
            if (arrival && arrival.pick().stationCode() == mystation.stationCode()) {
            rotateMarkers.push({ markertype: 'pick', name: arrival.phase(), time: arrival.pick().time() });
            console.log("rotateMarkers.push({ markertype: 'pick', name: "+arrival.phase()+", time: "+arrival.pick().time() );
            }
          }
        }
        rotatedSeismograph.appendMarkers(rotateMarkers);
        rotatedSeismograph.draw();
    } else{
      div.append('p').html('No data found for '+hash.station.codes());
    }
  });
<commit_msg>change offsets<commit_after>
// test radial transverse plotStartDate

// seisplotjs comes from the seisplotjs standalone bundle
var wp = seisplotjs.waveformplot;
var traveltime = seisplotjs.traveltime;
var fdsnevent = seisplotjs.fdsnevent;
var fdsnstation = seisplotjs.fdsnstation;
var miniseed = seisplotjs.miniseed;

var USGS = "earthquake.usgs.gov";
var IRIS = "service.iris.edu";

fdsnstation.RSVP.on('error', function(reason) {
  console.assert(false, reason);
});

var daysAgo = 365;
var netCode = 'US';
var staCode = 'LONY';
var locCode = '--';
var chanCode = 'BH?';
var datahost = IRIS;
var quakehost = USGS;
var preOffset = 25;
var dur = 125;

var protocol = 'http:';
if ("https:" == document.location.protocol) {
  protocol = 'https:'
}
console.log("Protocol: "+protocol+"  host: "+quakehost);

var quakeQuery = new fdsnevent.EventQuery()
  .host(quakehost)
  .protocol(protocol)
  .minLat(36).maxLat(37)
  .minLon(-4).maxLon(-3)
  .startTime(new Date("2010-04-11T22:08:00.000Z"))
  .endTime(new Date("2010-04-11T22:09:00.000Z"));
wp.d3.select("div.recentQuakesUrl")
    .append("p")
    .text("Quakes URL: "+quakeQuery.formURL());

var stationQuery = new fdsnstation.StationQuery()
  .protocol(protocol)
  .networkCode(netCode)
  .stationCode(staCode)
  .channelCode(chanCode);
wp.d3.select("div.recentQuakesUrl")
    .append("p")
    .text("Stations URL: "+stationQuery.formURL(fdsnstation.LEVEL_STATION));

var stationPromise = stationQuery.queryStations().then(function(netArray) {
          staCodes = [];
          for (var i=0;i<netArray[0].stations().length; i++) {
            staCodes.push(netArray[0].stations()[i].stationCode());
          }
          console.log("sta codes: "+staCodes.join());
          return netArray[0].stations()[0];
});

var quakePromise = quakeQuery.query().then(function(quakes) {
  var q = quakes[0];
  console.log("quake: "+q.time().toISOString()+" "+q.magnitude().mag()+" "
        +q.magnitude().type()+" ("+q.latitude()+", "+q.longitude()+") "
        +(q.depth()/1000)+" km ");
  return q;
});

var bothPromise = fdsnstation.RSVP.hash({
    station: stationPromise,
    quake: quakePromise
  }).then(function(hash) {
    console.log("quake network Promise then");
    console.log("distaz for "+hash.quake.latitude()+" "+ hash.quake.longitude()+" "+ hash.station.latitude()+" "+hash.station.longitude());
    hash.distaz = seisplotjs.distaz.distaz(hash.station.latitude(), hash.station.longitude(), hash.quake.latitude(), hash.quake.longitude());
    hash.traveltime = new traveltime.TraveltimeQuery()
        .protocol(protocol)
        .evdepth( hash.quake.depth() > 0 ? hash.quake.depth()/1000 : 0)
        .evlat(hash.quake.latitude()).evlon(hash.quake.longitude())
        .stalat(hash.station.latitude()).stalon(hash.station.longitude())
        .phases('p,P,PKP,PKIKP,Pdiff,s,S,Sdiff,PKP,SKS,SKIKS')
        .query()
        .then(function(ttimes) {
          var firstP = null;
          var firstS = null;
          for (var p=0; p<ttimes.arrivals.length; p++) {
            if ((ttimes.arrivals[p].phase.startsWith('P') || ttimes.arrivals[p].phase.startsWith('p')) && ( ! firstP || firstP.time > ttimes.arrivals[p])) {
              firstP = ttimes.arrivals[p];
            }
            if ((ttimes.arrivals[p].phase.startsWith('S') || ttimes.arrivals[p].phase.startsWith('s')) && ( ! firstS || firstS.time > ttimes.arrivals[p])) {
              firstS = ttimes.arrivals[p];
            }
          }
          return { firstP: firstP, firstS: firstS, arrivals: ttimes.arrivals };
        });
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {
    hash.S_arrival = new Date(hash.quake.time().getTime()+(hash.traveltime.firstS.time)*1000);
    hash.P_arrival = new Date(hash.quake.time().getTime()+(hash.traveltime.firstP.time)*1000);
    hash.seisDates = wp.calcStartEndDates(new Date(hash.S_arrival.getTime()-preOffset*1000), null, dur, 0);
    hash.miniseed = new seisplotjs.fdsndataselect.DataSelectQuery()
      .host(IRIS)
      .nodata(404)
      .networkCode(hash.station.network().networkCode())
      .stationCode(hash.station.stationCode())
      .locationCode(locCode)
      .channelCode(chanCode)
      .startTime(hash.seisDates.start)
      .endTime(hash.seisDates.end)
      .query();
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {

    let byChannel = miniseed.byChannel(hash.miniseed);
    let keys = Array.from(byChannel.keys());
    console.log("keys: "+keys);
    hash.seismograms = [];
    for(let i=0; i<keys.length; i++) {
      let key = keys[i];
      hash.seismograms.push(miniseed.merge(byChannel.get(key)));
    }
    return fdsnstation.RSVP.hash(hash);
  }).then(function(hash) {
    let div = seisplotjs.d3.select("div.seismograms");
    let svgDiv = div.append("div");
    svgDiv.classed("svg-container-wide", true);
    if (hash.seismograms.length > 0) {
      console.log("hash.seismograms "+hash.seismograms.length+" "+hash.seismograms[0].length);
        var seismograph = new wp.Seismograph(svgDiv, hash.seismograms, hash.seisDates.start, hash.seisDates.end);
        titles = [hash.seismograms[0][0].codes(),
                  hash.seismograms[1][0].chanCode(),
                  hash.seismograms[2][0].chanCode()];
        seismograph.setTitle(titles);
        var markers = [];
          markers.push({ markertype: 'predicted', name: "origin", time: hash.quake.time() });
          markers.push({ markertype: 'predicted', name: hash.traveltime.firstP.phase, time: hash.P_arrival });
          markers.push({ markertype: 'predicted', name: hash.traveltime.firstS.phase, time: hash.S_arrival });

        if (hash.quake.arrivals()) {
          for ( let aNum=0; aNum < hash.quake.arrivals().length; aNum++) {
            let arrival = hash.quake.arrivals()[aNum];
            if (! arrival) {console.log("arrival is undef??? "+aNum); }
            if (arrival && arrival.pick().stationCode() == mystation.stationCode()) {
              markers.push({ markertype: 'pick', name: arrival.phase(), time: arrival.pick().time() });
              console.log("markers.push({ markertype: 'pick', name: "+arrival.phase()+", time: "+arrival.pick().time() );
            }
          }
        }
        seismograph.appendMarkers(markers);
        seismograph.draw();

        // rotated
        console.log("### Rotated");

        let rotdiv = seisplotjs.d3.select("div.rotatedseismograms");
        let rotsvgDiv = rotdiv.append("div");
        rotsvgDiv.classed("svg-container-wide", true);

        var seisZ = null;
        var seisNorth = null;
        var seisEast = null;
        for (var i = 0; i < hash.seismograms.length; i++) {
          if (hash.seismograms[i][0].chanCode().charAt(2) === "Z") {
            seisZ = hash.seismograms[i];
          }
          if (hash.seismograms[i][0].chanCode().charAt(2) === "N") {
            seisNorth = hash.seismograms[i];
          }
          if (hash.seismograms[i][0].chanCode().charAt(2) === "E") {
            seisEast = hash.seismograms[i];
          }
        }
        if ( ! seisZ || ! seisNorth || ! seisEast) {
          throw new Error("unable to find ZNE: "+seisZ+" "+seisNorth+" "+seisEast);
        }
console.log("rotate to "+hash.distaz.baz+" "+((hash.distaz.baz+180)%360) );
        var rotated = seisplotjs.filter.rotate(seisNorth[0], 0, seisEast[0], 90, (hash.distaz.baz+180)%360);
        hash.rotatedSeismograms = [seisZ, [rotated.radial], [rotated.transverse]];
console.log("first points: "+seisZ[0].yAtIndex(0)+" "+rotated.radial.yAtIndex(0)+" "+rotated.transverse.yAtIndex(0))
        var rotatedSeismograph = new wp.Seismograph(rotsvgDiv, hash.rotatedSeismograms, hash.seisDates.start, hash.seisDates.end);
        titles = [hash.rotatedSeismograms[0][0].codes(),
                  hash.rotatedSeismograms[1][0].chanCode()+" "+rotated.azimuthRadial,
                  hash.rotatedSeismograms[2][0].chanCode()+" "+rotated.azimuthTransverse];
        rotatedSeismograph.setTitle(titles);
        var rotateMarkers = [];
          rotateMarkers.push({ markertype: 'predicted', name: "origin", time: hash.quake.time() });
          rotateMarkers.push({ markertype: 'predicted', name: hash.traveltime.firstP.phase, time: hash.P_arrival });
          rotateMarkers.push({ markertype: 'predicted', name: hash.traveltime.firstS.phase, time: hash.S_arrival });

        if (hash.quake.arrivals()) {
          for ( let aNum=0; aNum < hash.quake.arrivals().length; aNum++) {
            let arrival = hash.quake.arrivals()[aNum];
            if (! arrival) {console.log("arrival is undef??? "+aNum); }
            if (arrival && arrival.pick().stationCode() == mystation.stationCode()) {
            rotateMarkers.push({ markertype: 'pick', name: arrival.phase(), time: arrival.pick().time() });
            console.log("rotateMarkers.push({ markertype: 'pick', name: "+arrival.phase()+", time: "+arrival.pick().time() );
            }
          }
        }
        rotatedSeismograph.appendMarkers(rotateMarkers);
        rotatedSeismograph.draw();
    } else{
      div.append('p').html('No data found for '+hash.station.codes());
    }
  });
<|endoftext|>


<commit_before>/**
 * @module Heap
 * @fileoverview A binary heap container.
 * Based on the `heapq` module in Python's standard library.
 */

/**
 * Binary heap container.
 * @constructor
 * @param {function(*, *): boolean} [cmpFunc] A comparison function which
 *     returns whether it's first argument is less than the second argument.
 *     If this argument is not provided, then the `<` operator will be used.
 */
function Heap(cmpFunc) {
    /**
     * Comparison function.
     * @type {function(*, *): boolean}
     * @ignore
     */
    this._cmp = cmpFunc || function(a, b) {return a < b;};

    /**
     * An array as a heap.
     * @type {Array.<*>}
     * @ignore
     */
    this._heap = [];
};

/**
 * Get the top(smallest) item from the heap.
 */
Heap.prototype.top = function() {
    return this._heap[0];
};

/**
 * Get the size of the heap.
 * @return {number} The number of items in the heap.
 */
Heap.prototype.size = function() {
    return this._heap.length;
};

/**
 * Determine whether the heap is empty.
 * @return {boolean}
 */
Heap.prototype.isEmpty = function() {
    return !this.size();
};

/**
 * Push an item onto the heap.
 * @param {*} item - Item to push onto the heap.
 */
Heap.prototype.push = function(item) {
    this._heap.push(item);
    this._siftDown(0, this._heap.length - 1);
};

/**
 * Pop the smallest item off the heap.
 */
Heap.prototype.pop = function() {
    var heap, lastItem, returnItem;

    heap = this._heap;
    lastItem = heap.pop();

    if (heap.length) {
        returnItem = heap[0];
        heap[0] = lastItem;
        this._siftUp(0);
    } else {
        returnItem = lastItem;
    }
    return returnItem;
};

/**
 * Pop and return the current smallest value, and add the new item.
 *
 * This is more efficient than `pop()` followed by `push()`, and can be
 * more appropriate when using a fixed-size heap. Note that the value
 * returned may be larger than the pushed item!
 * @param {*} item - Item to replace the top one of the heap.
 */
Heap.prototype.replace = function(item) {
    var returnItem = this._heap[0];
    this._heap[0] = item;
    this._siftUp(0);
    return returnItem;
};

/**
 * Fast version of a push followed by a pop.
 * @param {*} item - Item to be pushed onto the heap.
 */
Heap.prototype.pushpop = function(item) {
    var heap = this._heap, t;

    if (heap.length && this._cmp(heap[0], item)) {
        t = heap[0];
        heap[0] = item;
        item = t;
        this._siftUp(0);
    }
    return item;
};

/**
 * Heapify the heap.
 * This method may be used when the internal data is modified.
 */
Heap.prototype.heapify = function() {
    var i, len = this._heap.length;
    for (i = Math.floor(len / 2) - 1; i >= 0; --i) {
        this._siftUp(i);
    }
};

/**
 * Sift down the possibly out-of-order value.
 * @param {number} startPos Start index of the array as a heap.
 * @param {number} pos Index of the leaf with possiblly out-of-order value.
 * @private
 */
Heap.prototype._siftDown = function(startPos, pos) {
    var heap, cmp, newItem, parentPos, parent;

    heap = this._heap;
    cmp = this._cmp;

    newItem = heap[pos];

    // Follow the path to the root, moving parents down until finding a place
    // newItem fits.
    while (pos > startPos) {
        parentPos = (pos - 1) >> 1;
        parent = heap[parentPos];
        if (cmp(newItem, parent)) {
            heap[pos] = parent;
            pos = parentPos;
            continue;
        }
        break;
    }
    heap[pos] = newItem;
};

/**
 * Sift up the possibly out-of-order value.
 * @param {number} pos Index of leaf with possibly out-of-order value.
 * @private
 */
Heap.prototype._siftUp = function(pos) {
    var heap, cmp, endPos, startPos, newItem, childPos, rightPos;

    cmp = this._cmp;
    heap = this._heap;

    endPos = heap.length;
    startPos = pos;
    newItem = heap[pos];

    // Bubble up the smaller child until hitting a leaf.
    childPos = 2 * pos + 1; // leftmost child position
    while (childPos < endPos) {
        // Set childPos to index of smaller child.
        rightPos = childPos + 1;
        if (rightPos < endPos && !cmp(heap[childPos], heap[rightPos])) {
            childPos = rightPos;
        }
        // Move the smaller child up.
        heap[pos] = heap[childPos];
        pos = childPos;
        childPos = 2 * pos + 1;
    }
    // The leaf at pos is empty now. Put newItem here, and bubble it up
    // to its final resting place (by sifting its parent down).
    heap[pos] = newItem;
    this._siftDown(startPos, pos);
};

module.exports = Heap;
<commit_msg>mod: rewrite heap<commit_after>// From https://github.com/qiao/heap.js
// Generated by CoffeeScript 1.3.1
(function() {
  var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;

  floor = Math.floor, min = Math.min;

  /*
  Default comparison function to be used
  */

  defaultCmp = function(x, y) {
    if (x < y) {
      return -1;
    }
    if (x > y) {
      return 1;
    }
    return 0;
  };

  /*
  Insert item x in list a, and keep it sorted assuming a is sorted.

  If x is already in a, insert it to the right of the rightmost x.

  Optional args lo (default 0) and hi (default a.length) bound the slice
  of a to be searched.
  */

  insort = function(a, x, lo, hi, cmp) {
    var mid;
    if (lo == null) {
      lo = 0;
    }
    if (cmp == null) {
      cmp = defaultCmp;
    }
    if (lo < 0) {
      throw new Error('lo must be non-negative');
    }
    if (hi == null) {
      hi = a.length;
    }
    while (cmp(lo, hi) < 0) {
      mid = floor((lo + hi) / 2);
      if (cmp(x, a[mid]) < 0) {
        hi = mid;
      } else {
        lo = mid + 1;
      }
    }
    return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);
  };

  /*
  Push item onto heap, maintaining the heap invariant.
  */

  heappush = function(array, item, cmp) {
    if (cmp == null) {
      cmp = defaultCmp;
    }
    array.push(item);
    return _siftdown(array, 0, array.length - 1, cmp);
  };

  /*
  Pop the smallest item off the heap, maintaining the heap invariant.
  */

  heappop = function(array, cmp) {
    var lastelt, returnitem;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    lastelt = array.pop();
    if (array.length) {
      returnitem = array[0];
      array[0] = lastelt;
      _siftup(array, 0, cmp);
    } else {
      returnitem = lastelt;
    }
    return returnitem;
  };

  /*
  Pop and return the current smallest value, and add the new item.

  This is more efficient than heappop() followed by heappush(), and can be
  more appropriate when using a fixed size heap. Note that the value
  returned may be larger than item! That constrains reasonable use of
  this routine unless written as part of a conditional replacement:
      if item > array[0]
        item = heapreplace(array, item)
  */

  heapreplace = function(array, item, cmp) {
    var returnitem;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    returnitem = array[0];
    array[0] = item;
    _siftup(array, 0, cmp);
    return returnitem;
  };

  /*
  Fast version of a heappush followed by a heappop.
  */

  heappushpop = function(array, item, cmp) {
    var _ref;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    if (array.length && cmp(array[0], item) < 0) {
      _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];
      _siftup(array, 0, cmp);
    }
    return item;
  };

  /*
  Transform list into a heap, in-place, in O(array.length) time.
  */

  heapify = function(array, cmp) {
    var i, _i, _j, _len, _ref, _ref1, _results, _results1;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    _ref1 = (function() {
      _results1 = [];
      for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }
      return _results1;
    }).apply(this).reverse();
    _results = [];
    for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
      i = _ref1[_i];
      _results.push(_siftup(array, i, cmp));
    }
    return _results;
  };

  /*
  Update the position of the given item in the heap.
  This function should be called every time the item is being modified.
  */

  updateItem = function(array, item, cmp) {
    var pos;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    pos = array.indexOf(item);
    _siftdown(array, 0, pos, cmp);
    return _siftup(array, pos, cmp);
  };

  /*
  Find the n largest elements in a dataset.
  */

  nlargest = function(array, n, cmp) {
    var elem, result, _i, _len, _ref;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    result = array.slice(0, n);
    if (!result.length) {
      return result;
    }
    heapify(result, cmp);
    _ref = array.slice(n);
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      elem = _ref[_i];
      heappushpop(result, elem, cmp);
    }
    return result.sort(cmp).reverse();
  };

  /*
  Find the n smallest elements in a dataset.
  */

  nsmallest = function(array, n, cmp) {
    var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    if (n * 10 <= array.length) {
      result = array.slice(0, n).sort(cmp);
      if (!result.length) {
        return result;
      }
      los = result[result.length - 1];
      _ref = array.slice(n);
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        elem = _ref[_i];
        if (cmp(elem, los) < 0) {
          insort(result, elem, 0, null, cmp);
          result.pop();
          los = result[result.length - 1];
        }
      }
      return result;
    }
    heapify(array, cmp);
    _results = [];
    for (i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
      _results.push(heappop(array, cmp));
    }
    return _results;
  };

  _siftdown = function(array, startpos, pos, cmp) {
    var newitem, parent, parentpos;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    newitem = array[pos];
    while (pos > startpos) {
      parentpos = (pos - 1) >> 1;
      parent = array[parentpos];
      if (cmp(newitem, parent) < 0) {
        array[pos] = parent;
        pos = parentpos;
        continue;
      }
      break;
    }
    return array[pos] = newitem;
  };

  _siftup = function(array, pos, cmp) {
    var childpos, endpos, newitem, rightpos, startpos;
    if (cmp == null) {
      cmp = defaultCmp;
    }
    endpos = array.length;
    startpos = pos;
    newitem = array[pos];
    childpos = 2 * pos + 1;
    while (childpos < endpos) {
      rightpos = childpos + 1;
      if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {
        childpos = rightpos;
      }
      array[pos] = array[childpos];
      pos = childpos;
      childpos = 2 * pos + 1;
    }
    array[pos] = newitem;
    return _siftdown(array, startpos, pos, cmp);
  };

  Heap = (function() {

    Heap.name = 'Heap';

    Heap.push = heappush;

    Heap.pop = heappop;

    Heap.replace = heapreplace;

    Heap.pushpop = heappushpop;

    Heap.heapify = heapify;

    Heap.nlargest = nlargest;

    Heap.nsmallest = nsmallest;

    function Heap(cmp) {
      this.cmp = cmp != null ? cmp : defaultCmp;
      this.nodes = [];
    }

    Heap.prototype.push = function(x) {
      return heappush(this.nodes, x, this.cmp);
    };

    Heap.prototype.pop = function() {
      return heappop(this.nodes, this.cmp);
    };

    Heap.prototype.peek = function() {
      return this.nodes[0];
    };

    Heap.prototype.contains = function(x) {
      return this.nodes.indexOf(x) !== -1;
    };

    Heap.prototype.replace = function(x) {
      return heapreplace(this.nodes, x, this.cmp);
    };

    Heap.prototype.pushpop = function(x) {
      return heappushpop(this.nodes, x, this.cmp);
    };

    Heap.prototype.heapify = function() {
      return heapify(this.nodes, this.cmp);
    };

    Heap.prototype.updateItem = function(x) {
      return updateItem(this.nodes, x, this.cmp);
    };

    Heap.prototype.clear = function() {
      return this.nodes = [];
    };

    Heap.prototype.empty = function() {
      return this.nodes.length === 0;
    };

    Heap.prototype.size = function() {
      return this.nodes.length;
    };

    Heap.prototype.clone = function() {
      var heap;
      heap = new Heap();
      heap.nodes = this.nodes.slice(0);
      return heap;
    };

    Heap.prototype.toArray = function() {
      return this.nodes.slice(0);
    };

    Heap.prototype.insert = Heap.prototype.push;

    Heap.prototype.remove = Heap.prototype.pop;

    Heap.prototype.top = Heap.prototype.peek;

    Heap.prototype.front = Heap.prototype.peek;

    Heap.prototype.has = Heap.prototype.contains;

    Heap.prototype.copy = Heap.prototype.clone;

    return Heap;

  })();

  if (typeof module !== "undefined" && module !== null ? module.exports : void 0) {
    module.exports = Heap;
  } else {
    window.Heap = Heap;
  }

}).call(this);
<|endoftext|>


<commit_before>
throw new Error('not implement yet');

// all (create -> index -> update -> show -> destroy)

var fotolife = require('../'); // require('hatena-fotolife-api')

var client = fotolife({
  type: 'wsse',
  username: process.env.HATENA_USERNAME, // 'username'
  apikey: process.env.HATENA_APIKEY      // 'apikey'
});

var imageId = null;

// POST PostURI (/atom/post)
client.create({
  title: 'bouzuya\'s icon',
  file: './bouzuya.png'
})
.then(function(res) {
  console.log(res);

  // assertion
  console.log(
    'test 1 ' + (res.entry.title._ === 'bouzuya\'s icon' ? 'OK' : 'NG')
  );

  // get image id for `show()`, `update()` and `destroy()`.
  imageId = res.entry.id._.match(/^tag:[^:]+:[^-]+-[^-]+-(\d+)$/)[1];
  console.log(imageId);

  // GET FeedURI (/atom/feed)
  return client.index();
})
.then(function(res) {
  console.log(res);

  // PUT EditURI (/atom/edit/XXXXXXXXXXXXXX)
  return client.update({ id: imageId, title: 'special bouzuya\'s icon' });
})
.then(function() {
  console.log('updated');

  // GET EditURI (/atom/edit/XXXXXXXXXXXXXX)
  return client.show({ id: imageId });
})
.then(function(res) {
  console.log(res);

  // assertion
  console.log(
    'test 2 ' + (res.entry.title._ === 'special bouzuya\'s icon' ? 'OK' : 'NG')
  );

  // DELETE EditURI (/atom/edit/XXXXXXXXXXXXXX)
  return client.destroy({ id: imageId });
})
.then(function() {
  console.log('deleted');
});

// **OUTPUT**
//
// { entry:
//    { '$':
//       { xmlns: 'http://purl.org/atom/ns#',
//         'xmlns:hatena': 'http://www.hatena.ne.jp/info/xmlns#' },
//      title: { _: 'bouzuya\'s icon' },
//      link: [ [Object], [Object] ],
//      issued: { _: '2014-08-22T00:02:16+09:00' },
//      author: { name: [Object] },
//      generator: { _: 'Hatena::Fotolife', '$': [Object] },
//      'dc:subject': { '$': [Object] },
//      id: { _: 'tag:hatena.ne.jp,2005:fotolife-bouzuya-20140822000216' },
//      'hatena:imageurl': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216.png?1408633338' },
//      'hatena:imageurlmedium': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216_120.jpg?1408633338' },
//      'hatena:imageurlsmall': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216_m.jpg?1408633338' },
//      'hatena:syntax': { _: 'f:id:bouzuya:20140822000216p:image' } } }
// test 1 OK
// 20140822000216
// { feed:
//    { '$':
//       { version: '0.3',
//         xmlns: 'http://purl.org/atom/ns#',
//         'xmlns:hatena': 'http://www.hatena.ne.jp/info/xmlns#',
//         'xml:lang': 'ja' },
//      title: { _: 'bouzuya\'s fotolife' },
//      link: [ [Object], [Object] ],
//      modified: { _: '2014-08-22 00:02:18' },
//      author: { name: [Object] },
//      id: { _: 'tag:hatena.ne.jp,2005:fotolife-bouzuya' },
//      generator: { _: 'Hatena::Fotolife', '$': [Object] },
//      entry:
//       [ [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object] ] } }
// updated
// { entry:
//    { '$':
//       { xmlns: 'http://purl.org/atom/ns#',
//         'xmlns:hatena': 'http://www.hatena.ne.jp/info/xmlns#' },
//      title: { _: 'special bouzuya\'s icon' },
//      link: [ [Object], [Object] ],
//      issued: { _: '2014-08-22T00:02:16+09:00' },
//      author: { name: [Object] },
//      generator: { _: 'Hatena::Fotolife', '$': [Object] },
//      id: { _: 'tag:hatena.ne.jp,2005:fotolife-bouzuya-20140822000216' },
//      'hatena:imageurl': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216.png?1408633340' },
//      'hatena:imageurlmedium': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216_120.jpg?1408633340' },
//      'hatena:imageurlsmall': { _: 'http://f.st-hatena.com/images/fotolife/b/bouzuya/20140822/20140822000216_m.jpg?1408633340' },
//      'hatena:syntax': { _: 'f:id:bouzuya:20140822000216p:image' } } }
// test 2 OK
// deleted
//
<commit_msg>add an example (all.js)<commit_after>// all (create -> index -> update -> show -> destroy)

var blog = require('../'); // require('hatena-blog-api')

var client = blog({
  type: 'wsse',
  username: process.env.HATENA_USERNAME,
  blogId: process.env.HATENA_BLOG_ID,
  apiKey: process.env.HATENA_APIKEY
});

var entryId = null;

// POST CollectionURI (/<username>/<blog_id>/atom/entry)
client.create({
  title: 'bouzuya\'s entry',
  content: 'fun is justice!',
  draft: true
}).then(function(res) {
  console.log(res);

  // assertion
  console.log(
    'test 1 ' + (res.entry.title._ === 'bouzuya\'s entry' ? 'OK' : 'NG')
  );

  // get image id for `show()`, `update()` and `destroy()`.
  entryId = res.entry.id._.match(/^tag:[^:]+:[^-]+-[^-]+-\d+-(\d+)$/)[1];
  console.log(entryId);

  // GET CollectionURI (/<username>/<blog_id>/atom/entry)
  return client.index();
})
.then(function(res) {
  console.log(res);

  // PUT MemberURI (/<username>/<blog_id>/atom/entry/<entry_id>)
  return client.update({
    id: entryId,
    title: 'special bouzuya\'s entry',
    content: 'fun is justice!!',
    draft: true
  });
})
.then(function() {
  console.log('updated');

  // GET MemberURI (/<username>/<blog_id>/atom/entry/<entry_id>)
  return client.show({ id: entryId });
})
.then(function(res) {
  console.log(res);

  // assertion
  console.log(
    'test 2 ' + (res.entry.title._ === 'special bouzuya\'s entry' ? 'OK' : 'NG')
  );

  // DELETE MemberURI (/<username>/<blog_id>/atom/entry/<entry_id>)
  return client.destroy({ id: entryId });
})
.then(function() {
  console.log('deleted');
});

// **OUTPUT**
//
// { entry:
//    { '$':
//       { xmlns: 'http://www.w3.org/2005/Atom',
//         'xmlns:app': 'http://www.w3.org/2007/app' },
//      id: { _: 'tag:blog.hatena.ne.jp,2013:blog-bouzuya-12704346814673856423-12921228815731812899' },
//      link: [ [Object], [Object] ],
//      author: { name: [Object] },
//      title: { _: 'bouzuya\'s entry' },
//      updated: { _: '2014-09-01T23:18:18+09:00' },
//      published: { _: '2014-09-01T23:18:18+09:00' },
//      'app:edited': { _: '2014-09-01T23:18:18+09:00' },
//      summary: { _: 'fun is justice!', '$': [Object] },
//      content: { _: 'fun is justice!', '$': [Object] },
//      'hatena:formatted-content': { _: '
fun is justice!
\n', '$': [Object] },
//      'app:control': { 'app:draft': [Object] } } }
// test 1 OK
// 12921228815731812899
// { feed:
//    { '$':
//       { xmlns: 'http://www.w3.org/2005/Atom',
//         'xmlns:app': 'http://www.w3.org/2007/app' },
//      link: [ [Object], [Object], [Object] ],
//      title: { _: '15 min/d' },
//      subtitle: { _: 'http://blog.bouzuya.net/ のミラーですよ。' },
//      updated: { _: '2014-09-01T23:00:17+09:00' },
//      author: { name: [Object] },
//      generator: { _: 'Hatena::Blog', '$': [Object] },
//      id: { _: 'hatenablog://blog/12704346814673856423' },
//      entry:
//       [ [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object],
//         [Object] ] } }
// updated
// { entry:
//    { '$':
//       { xmlns: 'http://www.w3.org/2005/Atom',
//         'xmlns:app': 'http://www.w3.org/2007/app' },
//      id: { _: 'tag:blog.hatena.ne.jp,2013:blog-bouzuya-12704346814673856423-12921228815731812899' },
//      link: [ [Object], [Object] ],
//      author: { name: [Object] },
//      title: { _: 'special bouzuya\'s entry' },
//      updated: { _: '2014-09-01T23:18:30+09:00' },
//      published: { _: '2014-09-01T23:18:18+09:00' },
//      'app:edited': { _: '2014-09-01T23:18:30+09:00' },
//      summary: { _: 'fun is justice!!', '$': [Object] },
//      content: { _: 'fun is justice!!', '$': [Object] },
//      'hatena:formatted-content': { _: '
fun is justice!!
\n', '$': [Object] },
//      'app:control': { 'app:draft': [Object] } } }
// test 2 OK
// deleted
//
<|endoftext|>


<commit_before>'use strict';

const thunk = require('thunkify');
const thenifyAll = require('thenify-all');

const methods = [
    'run'
];

function thenifyTable(table){
    return thenifyAll(table, {}, ['find', 'save', 'update']);
}

function thenifyDb(db){

    let thenifiedDb = {};

    for (let table of db.tables){

        thenifiedDb[table.name] = thenifyTable(table);
    }

    methods.forEach(function(name){
        if (!db[name]) return;

        thenifiedDb[name] = thunk(db[name]).bind(db);
    });

    return thenifiedDb;
}

module.exports = thenifyDb;<commit_msg>improved massive db co-ification<commit_after>'use strict';

const thunk = require('thunkify');
const thenifyAll = require('thenify-all');

const methods = [
    'run'
];

const tableMethods = ['find', 'save', 'update','findOne', 'insert'];

function thenifyTable(table) {
    return thenifyAll(table, {}, tableMethods);
}

function thenify(source, methods) {
    let result = {};

    methods.forEach(name => {
        if (!source[name]) return;

        result[name] = thunk(source[name]).bind(source);
    });

    return result;
}

function thenifyDb(db){

    let thenifiedDb = thenify(db, methods);

    for (let table of db.tables){
        thenifiedDb[table.name] = thenify(table, tableMethods);
    }

    return thenifiedDb;
}

module.exports = thenifyDb;<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function createPresentation(title, callback) {
  // [START create_presentation]
  gapi.client.slides.presentations.create({
    title: title
  }).then((response) => {
    console.log(`Created presentation with ID: ${response.result.presentationId}`);
    // [START_EXCLUDE silent]
    callback(response);
    // [END_EXCLUDE]
  });
  // [END create_presentation]
}
function copyPresentation(presentationId, copyTitle, callback) {
  // [START copy_presentation]
  var request = {
    name: copyTitle
  };
  gapi.client.drive.files.copy({
    fileId: presentationId,
    resource: request
  }).then((driveResponse) => {
    var presentationCopyId = driveResponse.result.id;
    // [START_EXCLUDE silent]
    callback(presentationCopyId);
    // [END_EXCLUDE]
  });
  // [END copy_presentation]
}
function createSlide(presentationId, pageId, callback) {
  // [START create_slide]
  var requests = [{
    createSlide: {
      objectId: pageId,
      insertionIndex: '1',
      slideLayoutReference: {
        predefinedLayout: 'TITLE_AND_TWO_COLUMNS'
      }
    }
  }];

  // If you wish to populate the slide with elements, add element create requests here,
  // using the pageId.

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((createSlideResponse) => {
    console.log(`Created slide with ID: ${createSlideResponse.result.replies[0].createSlide.objectId}`);
    // [START_EXCLUDE silent]
    callback(createSlideResponse);
    // [END_EXCLUDE]
  });
  // [END create_slide]
}
function createTextboxWithText(presentationId, pageId, callback) {
  // [START create_textbox_with_text]
  // Create a new square textbox, using the supplied element ID.
  var elementId = 'MyTextBox_01';
  var pt350 = {
    magnitude: 350,
    unit: 'PT'
  };
  var requests = [{
    createShape: {
      objectId: elementId,
      shapeType: 'TEXT_BOX',
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: pt350,
          width: pt350
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 350,
          translateY: 100,
          unit: 'PT'
        }
      }
    }
  },

  // Insert text into the box, using the supplied element ID.
  {
    insertText: {
      objectId: elementId,
      insertionIndex: 0,
      text: 'New Box Text Inserted!'
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((createTextboxWithTextResponse) => {
    var createShapeResponse = createTextboxWithTextResponse.result.replies[0].createShape;
    console.log(`Created textbox with ID: ${createShapeResponse.objectId}`);
    // [START_EXCLUDE silent]
    callback(createTextboxWithTextResponse.result);
    // [END_EXCLUDE]
  });
  // [END create_textbox_with_text]
}

function createImage(presentationId, pageId, imageFilePath, imageMimetype, callback) {
  var imageUrl = IMAGE_URL;
  // [START create_image]
  // Temporarily upload a local image file to Drive, in order to obtain a URL
  // for the image. Alternatively, you can provide the Slides service a URL of
  // an already hosted image.
  //
  // We will use an existing image under the variable: imageUrl.
  //
  // Create a new image, using the supplied object ID, with content downloaded from imageUrl.
  var requests = [];
  var imageId = 'MyImage_01';
  var emu4M = {
    magnitude: 4000000,
    unit: 'EMU'
  };
  requests.push({
    createImage: {
      objectId: imageId,
      url: imageUrl,
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: emu4M,
          width: emu4M
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 100000,
          translateY: 100000,
          unit: 'EMU'
        }
      }
    }
  });

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((response) => {
    var createImageResponse = response.result.replies;
    console.log(`Created image with ID: ${createImageResponse[0].createImage.objectId}`);
    // [START_EXCLUDE silent]
    callback(createImageResponse);
    // [END_EXCLUDE]
  });
  // [END create_image]
}
function textMerging(templatePresentationId, dataSpreadsheetId, callback) {
  // [START text_merging]
  // Use the Sheets API to load data, one record per row.
  var responses = [];
  var dataRangeNotation = 'Customers!A2:M6';
  gapi.client.sheets.spreadsheets.values.get({
    spreadsheetId: dataSpreadsheetId,
    range: dataRangeNotation
  }).then((sheetsResponse) => {
    var values = sheetsResponse.result.values;

    // For each record, create a new merged presentation.
    for (var i = 0; i < values.length; ++i) {
      var row = values[i];
      var customerName = row[2]; // name in column 3
      var caseDescription = row[5]; // case description in column 6
      var totalPortfolio = row[11]; // total portfolio in column 12

      // Duplicate the template presentation using the Drive API.
      var copyTitle = customerName + ' presentation';
      var request = {
        name: copyTitle
      };
      gapi.client.drive.files.copy({
        fileId: templatePresentationId,
        requests: request
      }).then((driveResponse) => {
        var presentationCopyId = driveResponse.result.id;

        // Create the text merge (replaceAllText) requests for this presentation.
        var requests = [{
          replaceAllText: {
            containsText: {
              text: '{{customer-name}}',
              matchCase: true
            },
            replaceText: customerName
          }
        }, {
          replaceAllText: {
            containsText: {
              text: '{{case-description}}',
              matchCase: true
            },
            replaceText: caseDescription
          }
        }, {
          replaceAllText: {
            containsText: {
              text: '{{total-portfolio}}',
              matchCase: true
            },
            replaceText: totalPortfolio
          }
        }];

        // Execute the requests for this presentation.
        gapi.client.slides.presentations.batchUpdate({
          presentationId: presentationCopyId,
          requests: requests
        }).then((batchUpdateResponse) => {
          var result = batchUpdateResponse.result;
          // [START_EXCLUDE silent]
          responses.push(result.replies);
          // [END_EXCLUDE]
          // Count the total number of replacements made.
          var numReplacements = 0;
          for (var i = 0; i < result.replies.length; ++i) {
            numReplacements += result.replies[i].replaceAllText.occurrencesChanged;
          }
          console.log(`Created presentation for ${customerName} with ID: ${presentationCopyId}`);
          console.log(`Replaced ${numReplacements} text instances`);
          // [START_EXCLUDE silent]
          if (responses.length === values.length) { // callback for the last value
            callback(responses);
          }
          // [END_EXCLUDE]
        });
      });
    }
  });
  // [END text_merging]
}
function imageMerging(templatePresentationId, imageUrl, customerName, callback) {
  var logoUrl = imageUrl;
  var customerGraphicUrl = imageUrl;

  // [START image_merging]
  // Duplicate the template presentation using the Drive API.
  var copyTitle = customerName + ' presentation';
  gapi.client.drive.files.copy({
    fileId: templatePresentationId,
    resource: {
      name: copyTitle
    }
  }).then((driveResponse) => {
    var presentationCopyId = driveResponse.result.id;

    // Create the image merge (replaceAllShapesWithImage) requests.
    var requests = [{
      replaceAllShapesWithImage: {
        imageUrl: logoUrl,
        replaceMethod: 'CENTER_INSIDE',
        containsText: {
          text: '{{company-logo}}',
          matchCase: true
        }
      }
    }, {
      replaceAllShapesWithImage: {
        imageUrl: customerGraphicUrl,
        replaceMethod: 'CENTER_INSIDE',
        containsText: {
          text: '{{customer-graphic}}',
          matchCase: true
        }
      }
    }];

    // Execute the requests for this presentation.
    gapi.client.slides.presentations.batchUpdate({
      presentationId: presentationCopyId,
      requests: requests
    }).then((batchUpdateResponse) => {
      var numReplacements = 0;
      for (var i = 0; i < batchUpdateResponse.result.replies.length; ++i) {
        numReplacements += batchUpdateResponse.result.replies[i].replaceAllShapesWithImage.occurrencesChanged;
      }
      console.log(`Created merged presentation with ID: ${presentationCopyId}`);
      console.log(`Replaced ${numReplacements} shapes with images.`);
      // [START_EXCLUDE silent]
      callback(batchUpdateResponse.result);
      // [END_EXCLUDE]
    });
  });
  // [END image_merging]
}
function simpleTextReplace(presentationId, shapeId, replacementText, callback) {
  // [START simple_text_replace]
  // Remove existing text in the shape, then insert new text.
  var requests = [{
    deleteText: {
      objectId: shapeId,
      textRange: {
        type: 'ALL'
      }
    }
  }, {
    insertText: {
      objectId: shapeId,
      insertionIndex: 0,
      text: replacementText
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Replaced text in shape with ID: ${shapeId}`)
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END simple_text_replace]
}
function textStyleUpdate(presentationId, shapeId, callback) {
  // [START text_style_update]
  // Update the text style so that the first 5 characters are bolded
  // and italicized, the next 5 are displayed in blue 14 pt Times
  // New Roman font, and the next 5 are hyperlinked.
  var requests = [{
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 0,
        endIndex: 5
      },
      style: {
        bold: true,
        italic: true
      },
      fields: 'bold,italic'
    }
  }, {
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 5,
        endIndex: 10
      },
      style: {
        fontFamily: 'Times New Roman',
        fontSize: {
          magnitude: 14,
          unit: 'PT'
        },
        foregroundColor: {
          opaqueColor: {
            rgbColor: {
              blue: 1.0,
              green: 0.0,
              red: 0.0
            }
          }
        }
      },
      fields: 'foregroundColor,fontFamily,fontSize'
    }
  }, {
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 10,
        endIndex: 15
      },
      style: {
        link: {
          url: 'www.example.com'
        }
      },
      fields: 'link'
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Updated the text style for shape with ID: ${shapeId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END text_style_update]
}
function createBulletedText(presentationId, shapeId, callback) {
  // [START create_bulleted_text]
  // Add arrow-diamond-disc bullets to all text in the shape.
  var requests = [{
    createParagraphBullets: {
      objectId: shapeId,
      textRange: {
        type: 'ALL'
      },
      bulletPreset: 'BULLET_ARROW_DIAMOND_DISC'
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Added bullets to text in shape with ID: ${shapeId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END create_bulleted_text]

}
function createSheetsChart(presentationId, pageId, shapeId, sheetChartId, callback) {
  // [START create_sheets_chart]
  // Embed a Sheets chart (indicated by the spreadsheetId and sheetChartId) onto
  // a page in the presentation. Setting the linking mode as "LINKED" allows the
  // chart to be refreshed if the Sheets version is updated.
  var emu4M = {
    magnitude: 4000000,
    unit: 'EMU'
  };
  var presentationChartId = 'MyEmbeddedChart';
  var requests = [{
    createSheetsChart: {
      objectId: presentationChartId,
      spreadsheetId: shapeId,
      chartId: sheetChartId,
      linkingMode: 'LINKED',
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: emu4M,
          width: emu4M
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 100000,
          translateY: 100000,
          unit: 'EMU'
        }
      }
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Added a linked Sheets chart with ID: ${presentationChartId}`);
    // [END create_sheets_chart]
    callback(batchUpdateResponse.result);
  });
}
function refreshSheetsChart(presentationId, presentationChartId, callback) {
  // [START refresh_sheets_chart]
  var requests = [{
    refreshSheetsChart: {
      objectId: presentationChartId
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Refreshed a linked Sheets chart with ID: ${presentationChartId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END refresh_sheets_chart]
}
<commit_msg>Update tag `slides_create_slide`<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function createPresentation(title, callback) {
  // [START create_presentation]
  gapi.client.slides.presentations.create({
    title: title
  }).then((response) => {
    console.log(`Created presentation with ID: ${response.result.presentationId}`);
    // [START_EXCLUDE silent]
    callback(response);
    // [END_EXCLUDE]
  });
  // [END create_presentation]
}
function copyPresentation(presentationId, copyTitle, callback) {
  // [START copy_presentation]
  var request = {
    name: copyTitle
  };
  gapi.client.drive.files.copy({
    fileId: presentationId,
    resource: request
  }).then((driveResponse) => {
    var presentationCopyId = driveResponse.result.id;
    // [START_EXCLUDE silent]
    callback(presentationCopyId);
    // [END_EXCLUDE]
  });
  // [END copy_presentation]
}
function createSlide(presentationId, pageId, callback) {
  // [START slides_create_slide]
  var requests = [{
    createSlide: {
      objectId: pageId,
      insertionIndex: '1',
      slideLayoutReference: {
        predefinedLayout: 'TITLE_AND_TWO_COLUMNS'
      }
    }
  }];

  // If you wish to populate the slide with elements, add element create requests here,
  // using the pageId.

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((createSlideResponse) => {
    console.log(`Created slide with ID: ${createSlideResponse.result.replies[0].createSlide.objectId}`);
    // [START_EXCLUDE silent]
    callback(createSlideResponse);
    // [END_EXCLUDE]
  });
  // [END slides_create_slide]
}
function createTextboxWithText(presentationId, pageId, callback) {
  // [START create_textbox_with_text]
  // Create a new square textbox, using the supplied element ID.
  var elementId = 'MyTextBox_01';
  var pt350 = {
    magnitude: 350,
    unit: 'PT'
  };
  var requests = [{
    createShape: {
      objectId: elementId,
      shapeType: 'TEXT_BOX',
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: pt350,
          width: pt350
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 350,
          translateY: 100,
          unit: 'PT'
        }
      }
    }
  },

  // Insert text into the box, using the supplied element ID.
  {
    insertText: {
      objectId: elementId,
      insertionIndex: 0,
      text: 'New Box Text Inserted!'
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((createTextboxWithTextResponse) => {
    var createShapeResponse = createTextboxWithTextResponse.result.replies[0].createShape;
    console.log(`Created textbox with ID: ${createShapeResponse.objectId}`);
    // [START_EXCLUDE silent]
    callback(createTextboxWithTextResponse.result);
    // [END_EXCLUDE]
  });
  // [END create_textbox_with_text]
}

function createImage(presentationId, pageId, imageFilePath, imageMimetype, callback) {
  var imageUrl = IMAGE_URL;
  // [START create_image]
  // Temporarily upload a local image file to Drive, in order to obtain a URL
  // for the image. Alternatively, you can provide the Slides service a URL of
  // an already hosted image.
  //
  // We will use an existing image under the variable: imageUrl.
  //
  // Create a new image, using the supplied object ID, with content downloaded from imageUrl.
  var requests = [];
  var imageId = 'MyImage_01';
  var emu4M = {
    magnitude: 4000000,
    unit: 'EMU'
  };
  requests.push({
    createImage: {
      objectId: imageId,
      url: imageUrl,
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: emu4M,
          width: emu4M
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 100000,
          translateY: 100000,
          unit: 'EMU'
        }
      }
    }
  });

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((response) => {
    var createImageResponse = response.result.replies;
    console.log(`Created image with ID: ${createImageResponse[0].createImage.objectId}`);
    // [START_EXCLUDE silent]
    callback(createImageResponse);
    // [END_EXCLUDE]
  });
  // [END create_image]
}
function textMerging(templatePresentationId, dataSpreadsheetId, callback) {
  // [START text_merging]
  // Use the Sheets API to load data, one record per row.
  var responses = [];
  var dataRangeNotation = 'Customers!A2:M6';
  gapi.client.sheets.spreadsheets.values.get({
    spreadsheetId: dataSpreadsheetId,
    range: dataRangeNotation
  }).then((sheetsResponse) => {
    var values = sheetsResponse.result.values;

    // For each record, create a new merged presentation.
    for (var i = 0; i < values.length; ++i) {
      var row = values[i];
      var customerName = row[2]; // name in column 3
      var caseDescription = row[5]; // case description in column 6
      var totalPortfolio = row[11]; // total portfolio in column 12

      // Duplicate the template presentation using the Drive API.
      var copyTitle = customerName + ' presentation';
      var request = {
        name: copyTitle
      };
      gapi.client.drive.files.copy({
        fileId: templatePresentationId,
        requests: request
      }).then((driveResponse) => {
        var presentationCopyId = driveResponse.result.id;

        // Create the text merge (replaceAllText) requests for this presentation.
        var requests = [{
          replaceAllText: {
            containsText: {
              text: '{{customer-name}}',
              matchCase: true
            },
            replaceText: customerName
          }
        }, {
          replaceAllText: {
            containsText: {
              text: '{{case-description}}',
              matchCase: true
            },
            replaceText: caseDescription
          }
        }, {
          replaceAllText: {
            containsText: {
              text: '{{total-portfolio}}',
              matchCase: true
            },
            replaceText: totalPortfolio
          }
        }];

        // Execute the requests for this presentation.
        gapi.client.slides.presentations.batchUpdate({
          presentationId: presentationCopyId,
          requests: requests
        }).then((batchUpdateResponse) => {
          var result = batchUpdateResponse.result;
          // [START_EXCLUDE silent]
          responses.push(result.replies);
          // [END_EXCLUDE]
          // Count the total number of replacements made.
          var numReplacements = 0;
          for (var i = 0; i < result.replies.length; ++i) {
            numReplacements += result.replies[i].replaceAllText.occurrencesChanged;
          }
          console.log(`Created presentation for ${customerName} with ID: ${presentationCopyId}`);
          console.log(`Replaced ${numReplacements} text instances`);
          // [START_EXCLUDE silent]
          if (responses.length === values.length) { // callback for the last value
            callback(responses);
          }
          // [END_EXCLUDE]
        });
      });
    }
  });
  // [END text_merging]
}
function imageMerging(templatePresentationId, imageUrl, customerName, callback) {
  var logoUrl = imageUrl;
  var customerGraphicUrl = imageUrl;

  // [START image_merging]
  // Duplicate the template presentation using the Drive API.
  var copyTitle = customerName + ' presentation';
  gapi.client.drive.files.copy({
    fileId: templatePresentationId,
    resource: {
      name: copyTitle
    }
  }).then((driveResponse) => {
    var presentationCopyId = driveResponse.result.id;

    // Create the image merge (replaceAllShapesWithImage) requests.
    var requests = [{
      replaceAllShapesWithImage: {
        imageUrl: logoUrl,
        replaceMethod: 'CENTER_INSIDE',
        containsText: {
          text: '{{company-logo}}',
          matchCase: true
        }
      }
    }, {
      replaceAllShapesWithImage: {
        imageUrl: customerGraphicUrl,
        replaceMethod: 'CENTER_INSIDE',
        containsText: {
          text: '{{customer-graphic}}',
          matchCase: true
        }
      }
    }];

    // Execute the requests for this presentation.
    gapi.client.slides.presentations.batchUpdate({
      presentationId: presentationCopyId,
      requests: requests
    }).then((batchUpdateResponse) => {
      var numReplacements = 0;
      for (var i = 0; i < batchUpdateResponse.result.replies.length; ++i) {
        numReplacements += batchUpdateResponse.result.replies[i].replaceAllShapesWithImage.occurrencesChanged;
      }
      console.log(`Created merged presentation with ID: ${presentationCopyId}`);
      console.log(`Replaced ${numReplacements} shapes with images.`);
      // [START_EXCLUDE silent]
      callback(batchUpdateResponse.result);
      // [END_EXCLUDE]
    });
  });
  // [END image_merging]
}
function simpleTextReplace(presentationId, shapeId, replacementText, callback) {
  // [START simple_text_replace]
  // Remove existing text in the shape, then insert new text.
  var requests = [{
    deleteText: {
      objectId: shapeId,
      textRange: {
        type: 'ALL'
      }
    }
  }, {
    insertText: {
      objectId: shapeId,
      insertionIndex: 0,
      text: replacementText
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Replaced text in shape with ID: ${shapeId}`)
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END simple_text_replace]
}
function textStyleUpdate(presentationId, shapeId, callback) {
  // [START text_style_update]
  // Update the text style so that the first 5 characters are bolded
  // and italicized, the next 5 are displayed in blue 14 pt Times
  // New Roman font, and the next 5 are hyperlinked.
  var requests = [{
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 0,
        endIndex: 5
      },
      style: {
        bold: true,
        italic: true
      },
      fields: 'bold,italic'
    }
  }, {
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 5,
        endIndex: 10
      },
      style: {
        fontFamily: 'Times New Roman',
        fontSize: {
          magnitude: 14,
          unit: 'PT'
        },
        foregroundColor: {
          opaqueColor: {
            rgbColor: {
              blue: 1.0,
              green: 0.0,
              red: 0.0
            }
          }
        }
      },
      fields: 'foregroundColor,fontFamily,fontSize'
    }
  }, {
    updateTextStyle: {
      objectId: shapeId,
      textRange: {
        type: 'FIXED_RANGE',
        startIndex: 10,
        endIndex: 15
      },
      style: {
        link: {
          url: 'www.example.com'
        }
      },
      fields: 'link'
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Updated the text style for shape with ID: ${shapeId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END text_style_update]
}
function createBulletedText(presentationId, shapeId, callback) {
  // [START create_bulleted_text]
  // Add arrow-diamond-disc bullets to all text in the shape.
  var requests = [{
    createParagraphBullets: {
      objectId: shapeId,
      textRange: {
        type: 'ALL'
      },
      bulletPreset: 'BULLET_ARROW_DIAMOND_DISC'
    }
  }];

  // Execute the requests.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Added bullets to text in shape with ID: ${shapeId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END create_bulleted_text]

}
function createSheetsChart(presentationId, pageId, shapeId, sheetChartId, callback) {
  // [START create_sheets_chart]
  // Embed a Sheets chart (indicated by the spreadsheetId and sheetChartId) onto
  // a page in the presentation. Setting the linking mode as "LINKED" allows the
  // chart to be refreshed if the Sheets version is updated.
  var emu4M = {
    magnitude: 4000000,
    unit: 'EMU'
  };
  var presentationChartId = 'MyEmbeddedChart';
  var requests = [{
    createSheetsChart: {
      objectId: presentationChartId,
      spreadsheetId: shapeId,
      chartId: sheetChartId,
      linkingMode: 'LINKED',
      elementProperties: {
        pageObjectId: pageId,
        size: {
          height: emu4M,
          width: emu4M
        },
        transform: {
          scaleX: 1,
          scaleY: 1,
          translateX: 100000,
          translateY: 100000,
          unit: 'EMU'
        }
      }
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Added a linked Sheets chart with ID: ${presentationChartId}`);
    // [END create_sheets_chart]
    callback(batchUpdateResponse.result);
  });
}
function refreshSheetsChart(presentationId, presentationChartId, callback) {
  // [START refresh_sheets_chart]
  var requests = [{
    refreshSheetsChart: {
      objectId: presentationChartId
    }
  }];

  // Execute the request.
  gapi.client.slides.presentations.batchUpdate({
    presentationId: presentationId,
    requests: requests
  }).then((batchUpdateResponse) => {
    console.log(`Refreshed a linked Sheets chart with ID: ${presentationChartId}`);
    // [START_EXCLUDE silent]
    callback(batchUpdateResponse.result);
    // [END_EXCLUDE]
  });
  // [END refresh_sheets_chart]
}
<|endoftext|>