<commit_before>/*global describe, it, before, after */
/*jshint laxcomma:true, node:true */
'use strict';
var should = require('should');

var telldus = require('..');
var errors = require('../lib/errors');

var SOME_REALLY_BIG_NUMBER = 100;
var NON_EXISTING_DEVICE=999;

var VALID_PROTOCOL='arctech';

/*
 * for this test to work there must be a running
 * telldusd and the first device must be a switch with
 * TURNON,TURNOFF
*/
/* example of a working config for these tests

user = 'nobody'
group = 'plugdev'
ignoreControllerConfirmation = 'false'
device {
  id = 1
  name = 'Example device'
  protocol = 'arctech'
  model = 'codeswitch'
  parameters {
    house = 'A'
    unit = '1'
  }
}
device {
  id = 2
  name = 'Nexa LKCT-614 Remote'
  protocol = 'arctech'
  model = 'selflearning'
  parameters {
    house = '11790353'
    unit = '1'
  }
}

*/

/*
 * Used to decode the values from rawDeviceEventListener
 */
function parseRaw(data) {
  var result={};
  var pairs = data.split(';');
  //all pairs end with ; including last
  for(var i = 0; i < pairs.length-1; i++) {
    var keyval = pairs[i].split(':');
    result[keyval[0]] = keyval[1];
  }
  return result;
}

describe('telldus library should', function () {

  before(function () {
    this.devices = telldus.getDevicesSync();
  });

  after(function(){
    //if you do not wan't cleanup of any created devices
    //in tellstick.conf uncomment the next line
    //return;

    var i, j, d, found, newDeviceList;
    newDeviceList = telldus.getDevicesSync();

    //remove all devices that weren't there to
    //begin with
    for(i=0; i<newDeviceList.length;i++){
      d = newDeviceList[i];
      found=false;
      for(j=0; j<this.devices.length; j++) {
        if(d.id === this.devices[j].id){
          //console.log('%s existed', d.id);
          found=true;
        }
      }
      if(!found){
        //console.log('%s is to be removed', d.id);
        if(d.id>0){
          try {
            telldus.removeDeviceSync(d.id);
            //console.log('%s is removed', d.id);
          }
          catch (ex){
            console.log('Could not remove device %s, %s', d.id, ex);

          }
        }
      }
    }
  });

  it('getDevicesSync', function () {
    var devices = this.devices;

    //if devices is zero length then
    //telldusd is probably not running
    devices.length.should.be.above(0);

    //set the environment variable VERBOSE to something if
    //you want to output the devices
    if(typeof process.env.VERBOSE !== 'undefined'){
      console.log(devices);
    }

    var dev1 = devices[0];
    dev1.should.have.property('name');
    dev1.should.have.property('methods');
    dev1.should.have.property('model');
    dev1.should.have.property('type');
    dev1.should.have.property('status');
    //test status
    dev1.status.should.have.property('status');

    //test methods
    var methods = dev1.methods;
    methods.should.be.an.instanceOf(Array);
    methods.should.include('TURNON');
    methods.should.include('TURNOFF');
  });

  describe('with config be able to', function(){

    describe('sync', function(){
      var deviceId;

      before(function(){
        deviceId = telldus.addDeviceSync();
      });

      it('addDeviceSync', function(){
        var id = telldus.addDeviceSync();
        id.should.be.above(0);
      });

      it('getNameSync', function(){
        var name = telldus.getNameSync(deviceId);
        name.should.equal('');
      });

      it('setNameSync', function(){
        var setResult = telldus.setNameSync(deviceId, 'Newly created');
        var name = telldus.getNameSync(deviceId);
        name.should.equal('Newly created');
        setResult.should.equal(true, 'set worked but did still return error');
      });

      it('getProtocolSync', function(){
        var p = telldus.getProtocolSync(deviceId);
        p.should.equal(''); //newly created device does not have a name.
      });

      it('setProtocolSync', function () {
        var result = telldus.setProtocolSync(deviceId, VALID_PROTOCOL);
        result.should.be.equal(true);
        var p = telldus.getProtocolSync(deviceId); //now it should have
        p.should.equal(VALID_PROTOCOL);
      });

    }); //sync

    describe('async', function(){
      var deviceId;

      before(function(){
        deviceId = telldus.addDeviceSync();
      });

      it('addDevice', function(done){
        telldus.addDevice(function(err, id){
          should.not.exist(err);
          should.exist(id);
          id.should.be.above(0);
          done();
        });
      });

      it('getName with proper error', function(done){
        telldus.getName(deviceId, function(err, name){
          should.exist(err);
          err.should.be.an.instanceOf(errors.TelldusError);
          err.should.have.property('message', 'Nothing to get!');
          err.should.have.property('code', '');
          should.not.exist(name);
          done();
        });
      });

      it('setName', function(done){
        telldus.setName(deviceId, 'Newly created2', function(err){
          should.not.exist(err);
          validate();
        });

        function validate() {
          var name = telldus.getNameSync(deviceId);
          name.should.equal('Newly created2', 'setName did not fail but can not get new values');
          done();
        }
      });

      it('getName', function(done){
        telldus.setNameSync(deviceId, 'Newly created3');
        telldus.getName(deviceId, function(err, name){
          should.not.exist(err);
          name.should.equal('Newly created3');
          done();
        });
      });

      it('getProtocol', function(done){
        telldus.getProtocol(deviceId, function(err, p){
          should.exist(err);
          err.should.have.property('message', 'Nothing to get!');
          should.not.exist(p);
          done();
        });
      });

      it('setProtocol', function (done) {
        telldus.setProtocol(deviceId, VALID_PROTOCOL, function(err){
          should.not.exist(err, 'setProtocol failed');

          var p = telldus.getProtocolSync(deviceId);
          p.should.equal(VALID_PROTOCOL, 'setProtocol did not fail but can not get new values');

          done(err);
        });
      });

    }); //async

  });//end with a device

  describe('support switches', function(){

    it('turnOff', function(done) {
      var device = this.devices[0];
      telldus.turnOff(device.id, function(err){
        should.not.exist(err);
        //refresh
        device = telldus.getDevicesSync()[0];
        device.status.should.have.property('status', 'OFF');
        done();
      });
    });

    it('turnOffSync', function() {
      var device = this.devices[0];
      var returnValue = telldus.turnOffSync(device.id);
      returnValue.should.be.equal(0);
      //refresh
      device = telldus.getDevicesSync()[0];
      device.status.should.have.property('status', 'OFF');
    });

    it('turnOn', function(done) {
      var device = this.devices[0];
      telldus.turnOn(device.id, function(err){
        should.not.exist(err);
        //refresh
        device = telldus.getDevicesSync()[0];
        device.status.should.have.property('status', 'ON');
        done();
      });
    });

    it('turnOnSync', function() {
      var device = this.devices[0];
      var returnValue = telldus.turnOnSync(device.id);
      returnValue.should.be.equal(0);
      //refresh
      device = telldus.getDevicesSync()[0];
      device.status.should.have.property('status', 'ON');
    });

    it('turnOn not existing should generate err', function(done){
      telldus.turnOn(NON_EXISTING_DEVICE,function(err){
        should.exist(err);
        err.should.have.property('message');
        err.message.should.be.equal('Device not found');
        done();
      });
    });
  });//switches

  describe('support events', function () {
    /*
     * For getting these tests to work something will have
     * to generate at least 1 event during each test.
     * That could be you pushing a remote.
     */
    it('using rawDeviceEventListener', function (done) {
      var seconds = 5; //for how many seconds should we wait for an event
      console.log('\nWaiting', seconds, 'seconds for some raw events.\nPlease trigger something.');
      var received = [];
      this.timeout(seconds*1000+1000); //increase the test timeout

      var listener = telldus.addRawDeviceEventListener(function (controllerId, data) {
        arguments.length.should.be.equal(2);
        should.exist(controllerId);
        should.exist(data);
        //set the environment variable VERBOSE to something if
        //you want to output the received data
        if(typeof process.env.VERBOSE !== 'undefined' ){
          console.log(data);
        }
        //do some tests
        data.should.be.type('string');
        if(! (data.indexOf(';') >= 0 && data.indexOf(':') >= 0)) {
          //need to filter some junk
          return;
        }
        //data.should.include(':');
        //data.should.include(';');
        data.length.should.be.within(20, SOME_REALLY_BIG_NUMBER);

        //save it
        received.push(data);
        //parse the string
        var parsed = parseRaw(data);
        parsed.should.have.property('class');
        parsed.should.have.property('protocol');

      });

      listener.should.be.above(0);

      setTimeout(function () {
        telldus.removeEventListener(listener, function(err){
          done(err); //consider the test done
        }); //remove the listener
        received.length.should.be.above(0); //we should have gotten at least 1 event. Likely more

      },seconds*1000);

    });//it should listen

    it('deviceEventListener', function (done) {
      var seconds = 2; // for how many seconds should we wait for an aevent
      this.timeout(seconds * 1000 + 1000);
      var count = 0;

      //listen and wait for something
      var listener = telldus.addDeviceEventListener( function (deviceId, evt) {
        if(typeof process.env.VERBOSE !== 'undefined' ){
          console.log('device:%s, event:%j', deviceId, evt);
        }
        deviceId.should.be.above(0);
        evt.should.have.property('status', 'ON');
        count++;
      });

      listener.should.be.above(0);

      //send a device event
      telldus.turnOn(1);

      setTimeout(function () {
        var returnValue = telldus.removeEventListenerSync(listener);
        var msg = telldus.getErrorStringSync(returnValue);
        returnValue.should.equal(0, 'removeEventListenerSync failed with "' + msg + '"'  );
        //we should have 1 event
        count.should.be.equal(1);
        done(); //consider the test done
      },seconds * 1000);
    });//deviceEventListener
  });//describe events
});<commit_msg>more tests and linting. relating to #2<commit_after>/*global describe, it, before, after */
/*jshint laxcomma:true, node:true */
'use strict';
var should = require('should');

var telldus = require('..');
var errors = require('../lib/errors');

var SOME_REALLY_BIG_NUMBER = 1000;
var NON_EXISTING_DEVICE = 999;

var VALID_PROTOCOL = 'arctech';
var VALID_PROTOCOLS = ['arctech'];

var VALID_MODELS = ['codeswitch'];

/*
 * for this test to work there must be a running
 * telldusd and the first device must be a switch with
 * TURNON,TURNOFF
*/
/* example of a working config for these tests

user = 'nobody'
group = 'plugdev'
ignoreControllerConfirmation = 'false'
device {
  id = 1
  name = 'Example device'
  protocol = 'arctech'
  model = 'codeswitch'
  parameters {
    house = 'A'
    unit = '1'
  }
}
device {
  id = 2
  name = 'Nexa LKCT-614 Remote'
  protocol = 'arctech'
  model = 'selflearning'
  parameters {
    house = '11790353'
    unit = '1'
  }
}

*/

/*
 * Used to decode the values from rawDeviceEventListener
 */
function parseRaw(data) {
  var result = {};
  var pairs = data.split(';');
  //all pairs end with ; including last
  for (var i = 0; i < pairs.length - 1; i++) {
    var keyval = pairs[i].split(':');
    result[keyval[0]] = keyval[1];
  }
  return result;
}

describe('telldus library should', function () {

  before(function () {
    this.devices = telldus.getDevicesSync();
  });

  after(function () {
    //if you do not wan't cleanup of any created devices
    //in tellstick.conf uncomment the next line
    //return;

    var i, j, d, found, newDeviceList;
    newDeviceList = telldus.getDevicesSync();

    //remove all devices that weren't there to
    //begin with
    for (i = 0; i < newDeviceList.length; i++) {
      d = newDeviceList[i];
      found = false;
      for (j = 0; j < this.devices.length; j++) {
        if (d.id === this.devices[j].id) {
          //console.log('%s existed', d.id);
          found = true;
        }
      }
      if (! found) {
        //console.log('%s is to be removed', d.id);
        if (d.id > 0) {
          try {
            telldus.removeDeviceSync(d.id);
            //console.log('%s is removed', d.id);
          }
          catch (ex) {
            console.log('Could not remove device %s, %s', d.id, ex);

          }
        }
      }
    }
  });

  describe('with config be able to', function () {

    describe('sync', function () {
      var deviceId;

      before(function () {
        deviceId = telldus.addDeviceSync();
      });

      it('getDevicesSync', function () {
        var devices = telldus.getDevicesSync();

        //if devices is zero length then
        //telldusd is probably not running
        devices.length.should.be.above(0);

        //set the environment variable VERBOSE to something if
        //you want to output the devices
        if (typeof process.env.VERBOSE !== 'undefined') {
          console.log(devices);
        }

        var dev1 = devices[0];
        dev1.should.have.property('name');
        dev1.should.have.property('methods');
        dev1.should.have.property('model');
        dev1.should.have.property('type');
        dev1.should.have.property('status');
        //test status
        dev1.status.should.have.property('status');

        //test methods
        var methods = dev1.methods;
        methods.should.be.an.instanceOf(Array);
        methods.should.include('TURNON');
        methods.should.include('TURNOFF');
      });

      it('addDeviceSync', function () {
        var id = telldus.addDeviceSync();
        id.should.be.above(0);
      });

      it('getNameSync', function () {
        var result = telldus.getNameSync(1);
        result.should.not.equal('');
        result.should.not.equal('UNKNOWN');
      });

      it('getNameSync with new device and return ""', function () {
        var name = telldus.getNameSync(deviceId);
        name.should.equal('');
      });

      it('getNameSync with bad device and return UNKNOWN', function () {
        var result = telldus.getNameSync(NON_EXISTING_DEVICE);
        result.should.equal('UNKNOWN');
      });

      it('setNameSync', function () {
        var setResult = telldus.setNameSync(deviceId, 'Newly created');
        var name = telldus.getNameSync(deviceId);
        name.should.equal('Newly created');
        setResult.should.equal(true, 'set worked but did still return error');
      });

      it('setNameSync with bad device and return false', function () {
        var setResult = telldus.setNameSync(NON_EXISTING_DEVICE, 'Bad ! ');
        setResult.should.equal(false);
      });

      it('getProtocolSync', function () {
        var p = telldus.getProtocolSync(1);
        p.should.not.equal('');
        p.should.not.equal('UNKNOWN');
        VALID_PROTOCOLS.should.include(p);
      });

      it('getProtocolSync with bad device and return UNKNOWN', function () {
        var p = telldus.getProtocolSync(NON_EXISTING_DEVICE);
        p.should.equal('UNKNOWN'); //newly created device does not have a name.
      });

      it('getProtocolSync with new device and return ""', function () {
        var p = telldus.getProtocolSync(deviceId);
        p.should.equal(''); //newly created device does not have a name.
      });

      it('setProtocolSync', function () {
        var result = telldus.setProtocolSync(deviceId, VALID_PROTOCOL);
        result.should.be.equal(true);
        var p = telldus.getProtocolSync(deviceId); //now it should have
        p.should.equal(VALID_PROTOCOL);
      });

      it('getModelSync', function () {
        var result = telldus.getModelSync(1);
        result.should.not.equal('UNKNOWN');
        result.should.not.equal('');
        VALID_MODELS.should.include(result);
      });

      it('getModelSync with bad device and get UNKNOWN', function () {
        var result = telldus.getModelSync(NON_EXISTING_DEVICE);
        result.should.equal('UNKNOWN');
      });

      it('getModelSync with new device and get ""', function () {
        var result = telldus.getModelSync(NON_EXISTING_DEVICE);
        result.should.equal('UNKNOWN');
      });

      it('setModelSync', function(){
        var r = telldus.setModelSync(deviceId, VALID_MODELS[0]);
        r.should.equal(true);
        r = telldus.getModelSync(deviceId);
        r.should.equal(VALID_MODELS[0]);
      });

      it('getDeviceTypeSync', function(){
        var r = telldus.getDeviceTypeSync(1);
        r.should.be.within(1,3);
      });

      it('removeDeviceSync', function(){
        var r = telldus.removeDeviceSync(deviceId);
        r.should.be.equal(true);
      })

    }); //sync

    describe('async', function () {
      var deviceId;

      before(function () {
        deviceId = telldus.addDeviceSync();
      });

      it('addDevice', function (done) {
        telldus.addDevice(function (err, id) {
          should.not.exist(err);
          should.exist(id);
          id.should.be.above(0);
          done();
        });
      });

      it('getName with proper error', function (done) {
        telldus.getName(deviceId, function (err, name) {
          should.exist(err);
          err.should.be.an.instanceOf(errors.TelldusError);
          err.should.have.property('message', 'Nothing to get!');
          err.should.have.property('code', '');
          should.not.exist(name);
          done();
        });
      });

      it('setName', function (done) {
        telldus.setName(deviceId, 'Newly created2', function (err) {
          should.not.exist(err);
          validate();
        });

        function validate() {
          var name = telldus.getNameSync(deviceId);
          name.should.equal('Newly created2', 'setName did not fail but can not get new values');
          done();
        }
      });

      it('getName', function (done) {
        telldus.setNameSync(deviceId, 'Newly created3');
        telldus.getName(deviceId, function (err, name) {
          should.not.exist(err);
          name.should.equal('Newly created3');
          done();
        });
      });

      it('getProtocol', function (done) {
        telldus.getProtocol(deviceId, function (err, p) {
          should.exist(err);
          err.should.have.property('message', 'Nothing to get!');
          should.not.exist(p);
          done();
        });
      });

      it('setProtocol', function (done) {
        telldus.setProtocol(deviceId, VALID_PROTOCOL, function (err) {
          should.not.exist(err, 'setProtocol failed');

          var p = telldus.getProtocolSync(deviceId);
          p.should.equal(VALID_PROTOCOL, 'setProtocol did not fail but can not get new values');

          done(err);
        });
      });

    }); //async

  });//end with a device

  describe('support switches', function () {

    it('turnOff', function (done) {
      var device = this.devices[0];
      telldus.turnOff(device.id, function (err) {
        should.not.exist(err);
        //refresh
        device = telldus.getDevicesSync()[0];
        device.status.should.have.property('status', 'OFF');
        done();
      });
    });

    it('turnOffSync', function () {
      var device = this.devices[0];
      var returnValue = telldus.turnOffSync(device.id);
      returnValue.should.be.equal(0);
      //refresh
      device = telldus.getDevicesSync()[0];
      device.status.should.have.property('status', 'OFF');
    });

    it('turnOn', function (done) {
      var device = this.devices[0];
      telldus.turnOn(device.id, function (err) {
        should.not.exist(err);
        //refresh
        device = telldus.getDevicesSync()[0];
        device.status.should.have.property('status', 'ON');
        done();
      });
    });

    it('turnOnSync', function () {
      var device = this.devices[0];
      var returnValue = telldus.turnOnSync(device.id);
      returnValue.should.be.equal(0);
      //refresh
      device = telldus.getDevicesSync()[0];
      device.status.should.have.property('status', 'ON');
    });

    it('turnOn not existing should generate err', function (done) {
      telldus.turnOn(NON_EXISTING_DEVICE, function (err) {
        should.exist(err);
        err.should.have.property('message');
        err.message.should.be.equal('Device not found');
        done();
      });
    });
  });//switches

  describe('support events', function () {
    /*
     * For getting these tests to work something will have
     * to generate at least 1 event during each test.
     * That could be you pushing a remote.
     */
    it('using rawDeviceEventListener', function (done) {
      var seconds = 5; //for how many seconds should we wait for an event
      console.log('\nWaiting', seconds, 'seconds for some raw events.\nPlease trigger something.');
      var count = 0;
      this.timeout(seconds * 1000 + 1000); //increase the test timeout

      var listener = telldus.addRawDeviceEventListener(function (controllerId, data) {
        arguments.length.should.be.equal(2);
        should.exist(controllerId);
        should.exist(data);
        //set the environment variable VERBOSE to something if
        //you want to output the received data
        if (typeof process.env.VERBOSE !== 'undefined') {
          console.log(data);
        }

        //do some tests
        data.should.be.type('string');
        if ((data.indexOf(';')<0 || data.indexOf(':')<0)) {
          //need to filter some junk
          return;
        }
        //count it
        count++;

        data.length.should.be.within(20, SOME_REALLY_BIG_NUMBER);

        //parse the string
        var parsed = parseRaw(data);
        parsed.should.have.property('class');
        parsed.should.have.property('protocol');
      });

      listener.should.be.above(0);

      setTimeout(function () {
        telldus.removeEventListener(listener, function (err) {
          done(err); //consider the test done
        }); //remove the listener
        count.should.be.above(0); //we should have gotten at least 1 event. Likely more

      }, seconds * 1000);

    });//it should listen

    it('deviceEventListener', function (done) {
      var seconds = 2; // for how many seconds should we wait for an aevent
      this.timeout(seconds * 1000 + 1000);
      var count = 0;

      //listen and wait for something
      var listener = telldus.addDeviceEventListener(function (deviceId, evt) {
        if (typeof process.env.VERBOSE !== 'undefined') {
          console.log('device:%s, event:%j', deviceId, evt);
        }
        deviceId.should.be.above(0);
        evt.should.have.property('status', 'ON');
        count++;
      });

      listener.should.be.above(0);

      //send a device event
      telldus.turnOn(1);

      setTimeout(function () {
        var returnValue = telldus.removeEventListenerSync(listener);
        var msg = telldus.getErrorStringSync(returnValue);
        returnValue.should.equal(0, 'removeEventListenerSync failed with "' + msg + '"');
        //we should have 1 event
        count.should.be.equal(1);
        done(); //consider the test done
      }, seconds * 1000);
    });//deviceEventListener
  });//describe events
});<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import React, { PureComponent } from 'react';
import bisection from 'bisection';
import clamp from 'clamp';
import arrayMove from 'array-move';
import { getContentRect, getMarginRect } from '../css-geometry-tools';
import type { DOMRectLiteral } from '../dom-rect';

type Props = {|
  orient: 'horizontal' | 'vertical',
  tagName: string,
  className: string,
  order: number[],
  onChangeOrder: number[] => {},
  children?: React$Element<*>,
|};

type XY = {|
  pageXY: 'pageX' | 'pageY',
  translateXY: 'translateX' | 'translateY',
  lefttop: 'left' | 'top',
  rightbottom: 'right' | 'bottom',
|};

type EventWithPageProperties = {pageX: number, pageY: number};

class Reorderable extends PureComponent {

  props: Props;

  state: {|
    phase: 'RESTING' | 'FINISHING' | 'MANIPULATING',
    manipulatingIndex: number,
    destinationIndex: number,
    manipulationDelta: number,
    adjustPrecedingBy: number,
    adjustSucceedingBy: number,
    finalOffset: number,
  |};

  _xy: {| horizontal: XY, vertical: XY |};
  _container: ?HTMLElement;

  constructor(props: Props) {
    super(props);
    (this: any)._setContainerRef = this._setContainerRef.bind(this);
    (this: any)._onMouseDown = this._onMouseDown.bind(this);
    this.state = {
      phase: 'RESTING',
      manipulatingIndex: -1,
      destinationIndex: -1,
      manipulationDelta: 0,
      adjustPrecedingBy: 0,
      adjustSucceedingBy: 0,
      finalOffset: 0,
    };

    this._xy = {
      horizontal: {
        pageXY: 'pageX',
        translateXY: 'translateX',
        lefttop: 'left',
        rightbottom: 'right',
      },
      vertical: {
        pageXY: 'pageY',
        translateXY: 'translateY',
        lefttop: 'top',
        rightbottom: 'bottom',
      },
    };
  }

  _setContainerRef(container: HTMLElement) {
    this._container = container;
  }

  _onMouseDown(event: SyntheticMouseEvent) {
    if (
      !this._container ||
      event.target === this._container ||
      !(event.target instanceof HTMLElement)
    ) {
      return;
    }
    // Flow: Coerce the event target into an HTMLElement in combination with the above
    // `instanceof` statement.
    let element = (event.target: HTMLElement);
    if (!element.matches('.grippy, .grippy *')) {
      // Don't handle this event. Only clicking inside a grippy should start the dragging process.
      return;
    }

    while ((element instanceof HTMLElement) && element.parentNode !== this._container) {
      element = element.parentNode;
    }

    if (!(element instanceof HTMLElement)) {
      return;
    }

    // Double check the container still exists for flow.
    if (this._container) {
      this._startDraggingElement(this._container, element, event);
    }
  }

  _getXY(): XY {
    return this._xy[this.props.orient];
  }

  _startDraggingElement(
    container: HTMLElement,
    element: HTMLElement,
    event: EventWithPageProperties
  ) {
    const xy = this._getXY();
    // Coerce the SyntheticMouseEvent and DOMRect instances into an object literals
    // to dynamically access certain properties.
    const mouseDownPos = event[xy.pageXY];
    const elementRect: DOMRectLiteral = getMarginRect(element);
    const containerRect: DOMRectLiteral = getContentRect(container);
    const spaceBefore = elementRect[xy.lefttop] - containerRect[xy.lefttop];
    const spaceAfter = containerRect[xy.rightbottom] - elementRect[xy.rightbottom];

    const children = Array.from(container.children);
    if (children.length < 2) {
      return;
    }

    let isBefore = true;
    let elementIndex = -1;
    const offsets = children.map((child, childIndex) => {
      if (child === element) {
        elementIndex = childIndex;
        isBefore = false;
        return 0;
      }
      const childRect: DOMRectLiteral = getMarginRect(child);
      return isBefore ? childRect[xy.lefttop] - elementRect[xy.lefttop]
                      : childRect[xy.rightbottom] - elementRect[xy.rightbottom];
    });

    if (elementIndex === -1) {
      return;
    }

    const midPoints = offsets.map((offset, childIndex) => {
      if (childIndex === offsets.length - 1) {
        // This will be popped off at the end.
        return 0;
      }
      return (offsets[childIndex + 1] + offset) / 2;
    });
    midPoints.pop();

    const nextEdgeAfterElement = (elementIndex === children.length - 1)
      ? containerRect[xy.rightbottom]
      : (getMarginRect(children[elementIndex + 1]): DOMRectLiteral)[xy.lefttop];

    const nextEdgeBeforeElement = (elementIndex === 0)
      ? containerRect[xy.lefttop]
      : (getMarginRect(children[elementIndex - 1]): DOMRectLiteral)[xy.rightbottom];

    this.setState({
      phase: 'MANIPULATING',
      manipulatingIndex: elementIndex,
      manipulationDelta: 0,
      destinationIndex: elementIndex,
      adjustPrecedingBy: (nextEdgeAfterElement - elementRect[xy.lefttop]),
      adjustSucceedingBy: (nextEdgeBeforeElement - elementRect[xy.rightbottom]),
    });

    const mouseMoveListener = (event: EventWithPageProperties) => {
      const delta = clamp(
        event[xy.pageXY] - mouseDownPos,
        -spaceBefore,
        spaceAfter
      );
      this.setState({
        manipulationDelta: delta,
        destinationIndex: bisection.right(midPoints, delta),
      });
    };
    const mouseUpListener = (event: EventWithPageProperties) => {
      mouseMoveListener(event);
      const destinationIndex = this.state.destinationIndex;
      this.setState({
        phase: 'FINISHING',
        finalOffset: offsets[destinationIndex],
      });
      window.removeEventListener('mousemove', mouseMoveListener, true);
      window.removeEventListener('mouseup', mouseUpListener, true);
      setTimeout(() => {
        this.setState({
          phase: 'RESTING',
        });
        if (elementIndex !== destinationIndex) {
          const newOrder = arrayMove(this.props.order, elementIndex, destinationIndex);
          this.props.onChangeOrder(newOrder);
        }
      }, 200);
    };
    window.addEventListener('mousemove', mouseMoveListener, true);
    window.addEventListener('mouseup', mouseUpListener, true);
  }

  render() {
    const { className, order } = this.props;
    const children: React$Element<*>[] = React.Children.toArray(this.props.children);
    const orderedChildren = order.map(childIndex => children[childIndex]);
    const TagName = this.props.tagName;
    const xy = this._getXY();

    if (this.state.phase === 'RESTING') {
      return (
        <TagName className={className} onMouseDown={this._onMouseDown} ref={this._setContainerRef}>
          { orderedChildren }
        </TagName>
      );
    }

    const { phase, manipulatingIndex, destinationIndex, adjustPrecedingBy, adjustSucceedingBy } = this.state;
    const adjustedClassName = (phase === 'MANIPULATING') ? className + ' beingReordered' : className;
    return (
      <TagName className={adjustedClassName} ref={this._setContainerRef}>
        {
          orderedChildren.map((child, childIndex) => {
            const style = {
              transition: '200ms ease-in-out transform',
              willChange: 'transform',
              position: 'relative',
              zIndex: '1',
              transform: '',
            };
            if (childIndex === manipulatingIndex) {
              style.zIndex = '2';
              if (phase === 'MANIPULATING') {
                delete style.transition;
                style.transform = `${xy.translateXY}(${this.state.manipulationDelta}px)`;
              } else {
                style.transform = `${xy.translateXY}(${this.state.finalOffset}px)`;
              }
            } else if (childIndex < manipulatingIndex && childIndex >= destinationIndex) {
              style.transform = `${xy.translateXY}(${adjustPrecedingBy}px)`;
            } else if (childIndex > manipulatingIndex && childIndex <= destinationIndex) {
              style.transform = `${xy.translateXY}(${adjustSucceedingBy}px)`;
            }
            return React.cloneElement(child, { style });
          })
        }
      </TagName>
    );
  }

}

export default Reorderable;
<commit_msg>Restrict Reorderable component to left clicks only<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import React, { PureComponent } from 'react';
import bisection from 'bisection';
import clamp from 'clamp';
import arrayMove from 'array-move';
import { getContentRect, getMarginRect } from '../css-geometry-tools';
import type { DOMRectLiteral } from '../dom-rect';

type Props = {|
  orient: 'horizontal' | 'vertical',
  tagName: string,
  className: string,
  order: number[],
  onChangeOrder: number[] => {},
  children?: React$Element<*>,
|};

type XY = {|
  pageXY: 'pageX' | 'pageY',
  translateXY: 'translateX' | 'translateY',
  lefttop: 'left' | 'top',
  rightbottom: 'right' | 'bottom',
|};

type EventWithPageProperties = {pageX: number, pageY: number};

class Reorderable extends PureComponent {

  props: Props;

  state: {|
    phase: 'RESTING' | 'FINISHING' | 'MANIPULATING',
    manipulatingIndex: number,
    destinationIndex: number,
    manipulationDelta: number,
    adjustPrecedingBy: number,
    adjustSucceedingBy: number,
    finalOffset: number,
  |};

  _xy: {| horizontal: XY, vertical: XY |};
  _container: ?HTMLElement;

  constructor(props: Props) {
    super(props);
    (this: any)._setContainerRef = this._setContainerRef.bind(this);
    (this: any)._onMouseDown = this._onMouseDown.bind(this);
    this.state = {
      phase: 'RESTING',
      manipulatingIndex: -1,
      destinationIndex: -1,
      manipulationDelta: 0,
      adjustPrecedingBy: 0,
      adjustSucceedingBy: 0,
      finalOffset: 0,
    };

    this._xy = {
      horizontal: {
        pageXY: 'pageX',
        translateXY: 'translateX',
        lefttop: 'left',
        rightbottom: 'right',
      },
      vertical: {
        pageXY: 'pageY',
        translateXY: 'translateY',
        lefttop: 'top',
        rightbottom: 'bottom',
      },
    };
  }

  _setContainerRef(container: HTMLElement) {
    this._container = container;
  }

  _onMouseDown(event: SyntheticMouseEvent) {
    if (
      !this._container ||
      event.target === this._container ||
      !(event.target instanceof HTMLElement) ||
      // Only run for left clicks.
      event.button !== 0
    ) {
      return;
    }
    // Flow: Coerce the event target into an HTMLElement in combination with the above
    // `instanceof` statement.
    let element = (event.target: HTMLElement);
    if (!element.matches('.grippy, .grippy *')) {
      // Don't handle this event. Only clicking inside a grippy should start the dragging process.
      return;
    }

    while ((element instanceof HTMLElement) && element.parentNode !== this._container) {
      element = element.parentNode;
    }

    if (!(element instanceof HTMLElement)) {
      return;
    }

    // Double check the container still exists for flow.
    if (this._container) {
      this._startDraggingElement(this._container, element, event);
    }
  }

  _getXY(): XY {
    return this._xy[this.props.orient];
  }

  _startDraggingElement(
    container: HTMLElement,
    element: HTMLElement,
    event: EventWithPageProperties
  ) {
    const xy = this._getXY();
    // Coerce the SyntheticMouseEvent and DOMRect instances into an object literals
    // to dynamically access certain properties.
    const mouseDownPos = event[xy.pageXY];
    const elementRect: DOMRectLiteral = getMarginRect(element);
    const containerRect: DOMRectLiteral = getContentRect(container);
    const spaceBefore = elementRect[xy.lefttop] - containerRect[xy.lefttop];
    const spaceAfter = containerRect[xy.rightbottom] - elementRect[xy.rightbottom];

    const children = Array.from(container.children);
    if (children.length < 2) {
      return;
    }

    let isBefore = true;
    let elementIndex = -1;
    const offsets = children.map((child, childIndex) => {
      if (child === element) {
        elementIndex = childIndex;
        isBefore = false;
        return 0;
      }
      const childRect: DOMRectLiteral = getMarginRect(child);
      return isBefore ? childRect[xy.lefttop] - elementRect[xy.lefttop]
                      : childRect[xy.rightbottom] - elementRect[xy.rightbottom];
    });

    if (elementIndex === -1) {
      return;
    }

    const midPoints = offsets.map((offset, childIndex) => {
      if (childIndex === offsets.length - 1) {
        // This will be popped off at the end.
        return 0;
      }
      return (offsets[childIndex + 1] + offset) / 2;
    });
    midPoints.pop();

    const nextEdgeAfterElement = (elementIndex === children.length - 1)
      ? containerRect[xy.rightbottom]
      : (getMarginRect(children[elementIndex + 1]): DOMRectLiteral)[xy.lefttop];

    const nextEdgeBeforeElement = (elementIndex === 0)
      ? containerRect[xy.lefttop]
      : (getMarginRect(children[elementIndex - 1]): DOMRectLiteral)[xy.rightbottom];

    this.setState({
      phase: 'MANIPULATING',
      manipulatingIndex: elementIndex,
      manipulationDelta: 0,
      destinationIndex: elementIndex,
      adjustPrecedingBy: (nextEdgeAfterElement - elementRect[xy.lefttop]),
      adjustSucceedingBy: (nextEdgeBeforeElement - elementRect[xy.rightbottom]),
    });

    const mouseMoveListener = (event: EventWithPageProperties) => {
      const delta = clamp(
        event[xy.pageXY] - mouseDownPos,
        -spaceBefore,
        spaceAfter
      );
      this.setState({
        manipulationDelta: delta,
        destinationIndex: bisection.right(midPoints, delta),
      });
    };
    const mouseUpListener = (event: EventWithPageProperties) => {
      mouseMoveListener(event);
      const destinationIndex = this.state.destinationIndex;
      this.setState({
        phase: 'FINISHING',
        finalOffset: offsets[destinationIndex],
      });
      window.removeEventListener('mousemove', mouseMoveListener, true);
      window.removeEventListener('mouseup', mouseUpListener, true);
      setTimeout(() => {
        this.setState({
          phase: 'RESTING',
        });
        if (elementIndex !== destinationIndex) {
          const newOrder = arrayMove(this.props.order, elementIndex, destinationIndex);
          this.props.onChangeOrder(newOrder);
        }
      }, 200);
    };
    window.addEventListener('mousemove', mouseMoveListener, true);
    window.addEventListener('mouseup', mouseUpListener, true);
  }

  render() {
    const { className, order } = this.props;
    const children: React$Element<*>[] = React.Children.toArray(this.props.children);
    const orderedChildren = order.map(childIndex => children[childIndex]);
    const TagName = this.props.tagName;
    const xy = this._getXY();

    if (this.state.phase === 'RESTING') {
      return (
        <TagName className={className} onMouseDown={this._onMouseDown} ref={this._setContainerRef}>
          { orderedChildren }
        </TagName>
      );
    }

    const { phase, manipulatingIndex, destinationIndex, adjustPrecedingBy, adjustSucceedingBy } = this.state;
    const adjustedClassName = (phase === 'MANIPULATING') ? className + ' beingReordered' : className;
    return (
      <TagName className={adjustedClassName} ref={this._setContainerRef}>
        {
          orderedChildren.map((child, childIndex) => {
            const style = {
              transition: '200ms ease-in-out transform',
              willChange: 'transform',
              position: 'relative',
              zIndex: '1',
              transform: '',
            };
            if (childIndex === manipulatingIndex) {
              style.zIndex = '2';
              if (phase === 'MANIPULATING') {
                delete style.transition;
                style.transform = `${xy.translateXY}(${this.state.manipulationDelta}px)`;
              } else {
                style.transform = `${xy.translateXY}(${this.state.finalOffset}px)`;
              }
            } else if (childIndex < manipulatingIndex && childIndex >= destinationIndex) {
              style.transform = `${xy.translateXY}(${adjustPrecedingBy}px)`;
            } else if (childIndex > manipulatingIndex && childIndex <= destinationIndex) {
              style.transform = `${xy.translateXY}(${adjustSucceedingBy}px)`;
            }
            return React.cloneElement(child, { style });
          })
        }
      </TagName>
    );
  }

}

export default Reorderable;
<|endoftext|>


<commit_before>// Copyright 2017 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.

'use strict';

// Imports the Google Cloud client library
const {Bigtable} = require('@google-cloud/bigtable');

async function runInstanceOperations(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);

  console.log('Check Instance Exists');
  // [START bigtable_check_instance_exists]
  const [instanceExists] = await instance.exists();
  // [END bigtable_check_instance_exists]

  // Create instance if does not exists
  if (!instanceExists) {
    console.log('Creating a PRODUCTION Instance');
    // [START bigtable_create_prod_instance]
    // Creates a Production Instance with the ID "ssd-instance"
    // with cluster id "ssd-cluster", 3 nodes and location us-central1-f

    const instanceOptions = {
      clusters: [
        {
          id: clusterID,
          nodes: 3,
          location: 'us-central1-f',
          storage: 'ssd',
        },
      ],
      type: 'PRODUCTION', // Optional as default type is PRODUCTION
      labels: {'prod-label': 'prod-label'},
    };

    // Create production instance with given options
    const [prodInstance] = await instance.create(instanceOptions);
    console.log(`Created Instance: ${prodInstance.id}`);
    // [END bigtable_create_prod_instance]
  } else {
    console.log(`Instance ${instance.id} exists`);
  }

  console.log(); //for just a new-line
  console.log('Listing Instances:');
  // [START bigtable_list_instances]
  const [instances] = await bigtable.getInstances();
  instances.forEach(instance => {
    console.log(instance.id);
  });
  // [END bigtable_list_instances]

  console.log(); //for just a new-line
  console.log('Get Instance');
  // [START bigtable_get_instance]
  const [instances2] = await bigtable.instance(instanceID).get();
  console.log(`Instance ID: ${instances2.id}`);
  console.log(`Instance Meta: ${JSON.stringify(instances2.metadata)}`);
  // [END bigtable_get_instance]

  console.log(); //for just a new-line
  console.log('Listing Clusters...');
  // [START bigtable_get_clusters]
  const instance3 = bigtable.instance(instanceID);
  const [clusters] = await instance3.getClusters();
  clusters.forEach(cluster => {
    console.log(cluster.id);
  });
  // [END bigtable_get_clusters]
}

// Creates a Development instance with the ID "hdd-instance"
// with cluster ID "hdd-cluster" and location us-central1-f
// Cluster nodes should not be set while creating Development Instance
async function createDevInstance(instanceID, clusterID) {
  const bigtable = new Bigtable();

  // [START bigtable_create_dev_instance]
  console.log(); //for just a new-line
  console.log('Creating a DEVELOPMENT Instance');
  // Set options to create an Instance
  const options = {
    clusters: [
      {
        id: clusterID,
        location: 'us-central1-f',
        storage: 'hdd',
      },
    ],
    type: 'DEVELOPMENT',
    labels: {'dev-label': 'dev-label'},
  };

  // Create development instance with given options
  const [instance] = await bigtable.createInstance(instanceID, options);
  console.log(`Created development instance: ${instance.id}`);
  // [END bigtable_create_dev_instance]
}

// Delete the Instance
async function deleteInstance(instanceID) {
  // Creates a client
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);

  console.log(); //for just a new-line
  // [START bigtable_delete_instance]
  console.log('Deleting Instance');
  await instance.delete();
  console.log(`Instance deleted: ${instance.id}`);
  // [END bigtable_delete_instance]
}

// Add Cluster
async function addCluster(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);
  const [instanceExists] = await instance.exists();
  if (!instanceExists) {
    console.log('Instance does not exists');
  } else {
    console.log(); //for just a new-line
    console.log(`Adding Cluster to Instance ${instance.id}`);
    // [START bigtable_create_cluster]
    const clusterOptions = {
      location: 'us-central1-c',
      nodes: 3,
      storage: 'ssd',
    };

    const [cluster] = await instance.createCluster(clusterID, clusterOptions);
    console.log(`Cluster created: ${cluster.id}`);
    // [END bigtable_create_cluster]
  }
}

// Delete the Cluster
async function deleteCluster(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);
  const cluster = instance.cluster(clusterID);

  // [START bigtable_delete_cluster]
  console.log(); //for just a new-line
  console.log('Deleting Cluster');
  await cluster.delete();
  console.log(`Cluster deleted: ${cluster.id}`);
  // [END bigtable_delete_cluster]
}

require('yargs')
  .demand(1)
  .command(
    'run',
    'Creates an Instance(type: PRODUCTION) and run basic instance-operations',
    {},
    argv => runInstanceOperations(argv.instance, argv.cluster)
  )
  .example(
    'node $0 run --instance [instanceID] --cluster [clusterID]',
    'Run instance operations'
  )
  .command('dev-instance', 'Create Development Instance', {}, argv =>
    createDevInstance(argv.instance, argv.cluster)
  )
  .example(
    'node $0 dev-instance --instance [instanceID]',
    'Create Development Instance'
  )
  .command('del-instance', 'Delete the Instance', {}, argv =>
    deleteInstance(argv.instance)
  )
  .example(
    'node $0 del-instance --instance [instanceID]',
    'Delete the Instance.'
  )
  .command('add-cluster', 'Add Cluster', {}, argv =>
    addCluster(argv.instance, argv.cluster)
  )
  .example(
    'node $0 add-cluster --instance [instanceID] --cluster [clusterID]',
    'Add Cluster'
  )
  .command('del-cluster', 'Delete the Cluster', {}, argv =>
    deleteCluster(argv.instance, argv.cluster)
  )
  .example(
    'node $0 del-cluster --instance [instanceID] --cluster [clusterID]',
    'Delete the Cluster'
  )
  .wrap(120)
  .nargs('instance', 1)
  .nargs('cluster', 1)
  .describe('instance', 'Cloud Bigtable Instance ID')
  .describe('cluster', 'Cloud Bigtable Cluster ID')
  .recommendCommands()
  .epilogue('For more information, see https://cloud.google.com/bigtable/docs')
  .help()
  .strict().argv;
<commit_msg>fix: add operation (#1145)<commit_after>// Copyright 2017 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.

'use strict';

// Imports the Google Cloud client library
const {Bigtable} = require('@google-cloud/bigtable');

async function runInstanceOperations(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);

  console.log('Check Instance Exists');
  // [START bigtable_check_instance_exists]
  const [instanceExists] = await instance.exists();
  // [END bigtable_check_instance_exists]

  // Create instance if does not exists
  if (!instanceExists) {
    console.log('Creating a PRODUCTION Instance');
    // [START bigtable_create_prod_instance]
    // Creates a Production Instance with the ID "ssd-instance"
    // with cluster id "ssd-cluster", 3 nodes and location us-central1-f

    const instanceOptions = {
      clusters: [
        {
          id: clusterID,
          nodes: 3,
          location: 'us-central1-f',
          storage: 'ssd',
        },
      ],
      type: 'PRODUCTION', // Optional as default type is PRODUCTION
      labels: {'prod-label': 'prod-label'},
    };

    // Create production instance with given options
    const [prodInstance, operation] = await instance.create(instanceOptions);
    await operation.promise();
    console.log(`Created Instance: ${prodInstance.id}`);
    // [END bigtable_create_prod_instance]
  } else {
    console.log(`Instance ${instance.id} exists`);
  }

  console.log(); //for just a new-line
  console.log('Listing Instances:');
  // [START bigtable_list_instances]
  const [instances] = await bigtable.getInstances();
  instances.forEach(instance => {
    console.log(instance.id);
  });
  // [END bigtable_list_instances]

  console.log(); //for just a new-line
  console.log('Get Instance');
  // [START bigtable_get_instance]
  const [instances2] = await bigtable.instance(instanceID).get();
  console.log(`Instance ID: ${instances2.id}`);
  console.log(`Instance Meta: ${JSON.stringify(instances2.metadata)}`);
  // [END bigtable_get_instance]

  console.log(); //for just a new-line
  console.log('Listing Clusters...');
  // [START bigtable_get_clusters]
  const instance3 = bigtable.instance(instanceID);
  const [clusters] = await instance3.getClusters();
  clusters.forEach(cluster => {
    console.log(cluster.id);
  });
  // [END bigtable_get_clusters]
}

// Creates a Development instance with the ID "hdd-instance"
// with cluster ID "hdd-cluster" and location us-central1-f
// Cluster nodes should not be set while creating Development Instance
async function createDevInstance(instanceID, clusterID) {
  const bigtable = new Bigtable();

  // [START bigtable_create_dev_instance]
  console.log(); //for just a new-line
  console.log('Creating a DEVELOPMENT Instance');
  // Set options to create an Instance
  const options = {
    clusters: [
      {
        id: clusterID,
        location: 'us-central1-f',
        storage: 'hdd',
      },
    ],
    type: 'DEVELOPMENT',
    labels: {'dev-label': 'dev-label'},
  };

  // Create development instance with given options
  const [instance, operation] = await bigtable.createInstance(
    instanceID,
    options
  );
  await operation.promise();
  console.log(`Created development instance: ${instance.id}`);
  // [END bigtable_create_dev_instance]
}

// Delete the Instance
async function deleteInstance(instanceID) {
  // Creates a client
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);

  console.log(); //for just a new-line
  // [START bigtable_delete_instance]
  console.log('Deleting Instance');
  await instance.delete();
  console.log(`Instance deleted: ${instance.id}`);
  // [END bigtable_delete_instance]
}

// Add Cluster
async function addCluster(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);
  const [instanceExists] = await instance.exists();
  if (!instanceExists) {
    console.log('Instance does not exists');
  } else {
    console.log(); //for just a new-line
    console.log(`Adding Cluster to Instance ${instance.id}`);
    // [START bigtable_create_cluster]
    const clusterOptions = {
      location: 'us-central1-c',
      nodes: 3,
      storage: 'ssd',
    };

    const [cluster, operation] = await instance.createCluster(
      clusterID,
      clusterOptions
    );
    await operation.promise();
    console.log(`Cluster created: ${cluster.id}`);
    // [END bigtable_create_cluster]
  }
}

// Delete the Cluster
async function deleteCluster(instanceID, clusterID) {
  const bigtable = new Bigtable();
  const instance = bigtable.instance(instanceID);
  const cluster = instance.cluster(clusterID);

  // [START bigtable_delete_cluster]
  console.log(); //for just a new-line
  console.log('Deleting Cluster');
  await cluster.delete();
  console.log(`Cluster deleted: ${cluster.id}`);
  // [END bigtable_delete_cluster]
}

require('yargs')
  .demand(1)
  .command(
    'run',
    'Creates an Instance(type: PRODUCTION) and run basic instance-operations',
    {},
    argv => runInstanceOperations(argv.instance, argv.cluster)
  )
  .example(
    'node $0 run --instance [instanceID] --cluster [clusterID]',
    'Run instance operations'
  )
  .command('dev-instance', 'Create Development Instance', {}, argv =>
    createDevInstance(argv.instance, argv.cluster)
  )
  .example(
    'node $0 dev-instance --instance [instanceID]',
    'Create Development Instance'
  )
  .command('del-instance', 'Delete the Instance', {}, argv =>
    deleteInstance(argv.instance)
  )
  .example(
    'node $0 del-instance --instance [instanceID]',
    'Delete the Instance.'
  )
  .command('add-cluster', 'Add Cluster', {}, argv =>
    addCluster(argv.instance, argv.cluster)
  )
  .example(
    'node $0 add-cluster --instance [instanceID] --cluster [clusterID]',
    'Add Cluster'
  )
  .command('del-cluster', 'Delete the Cluster', {}, argv =>
    deleteCluster(argv.instance, argv.cluster)
  )
  .example(
    'node $0 del-cluster --instance [instanceID] --cluster [clusterID]',
    'Delete the Cluster'
  )
  .wrap(120)
  .nargs('instance', 1)
  .nargs('cluster', 1)
  .describe('instance', 'Cloud Bigtable Instance ID')
  .describe('cluster', 'Cloud Bigtable Cluster ID')
  .recommendCommands()
  .epilogue('For more information, see https://cloud.google.com/bigtable/docs')
  .help()
  .strict().argv;
<|endoftext|>


<commit_before>/*
 * PaySwarm JavaScript library.
 *
 * Copyright 2010-2012 Digital Bazaar, Inc.
 * License: LGPLv3.
 */

/**
 * Expands the asset information when the title is clicked.
 *
 * @param postId the identifier for the post
 */
function toggleAssetInformation(postId) {
  var assetInfo = document.getElementById('payswarm-asset-info-' + postId);
  var className = assetInfo.getAttribute('class');

  // toggle the hidden CSS state for the attribute
  if(className === 'hidden') {
    assetInfo.setAttribute('class', '');
  } else {
    assetInfo.setAttribute('class', 'hidden');
  }
}

/**
 * Sets the target of a form submission to a popup that will redirect to
 * the PaySwarm Authority.
 *
 * @param form the form that is being submitted.
 */
function showAuthorityPopup(form) {
  var width = 700;
  var height = 600;
  window.open('', 'payswarm',
    'left=' + ((screen.width-width)/2) +
    ',top=' + ((screen.height-height)/2) +
    ',width=' + width +
    ',height=' + height +
    ',resizeable,scrollbars');
  form.target = 'payswarm';
}

/**
 * Closes any pop up window and loads the given url.
 *
 * @param url the URL to load in the parent.
 */
function closePopup(url) {
  if(window.opener === null) {
    window.location = url;
  } else {
    window.close();
    window.opener.location = url;
  }
}

/**
 * Shows/hides the license input field in the payswarm meta box.
 *
 * @param container the ID of the license input container.
 * @param checkbox the ID of the default license checkbox.
 */
function toggleLicenseInput(container, checkbox) {
  container = document.getElementById(container);
  checkbox = document.getElementById(checkbox);
  container.className = (checkbox.checked ? 'hidden' : '');
}
<commit_msg>Use width of 800 for popup.<commit_after>/*
 * PaySwarm JavaScript library.
 *
 * Copyright 2010-2012 Digital Bazaar, Inc.
 * License: LGPLv3.
 */

/**
 * Expands the asset information when the title is clicked.
 *
 * @param postId the identifier for the post
 */
function toggleAssetInformation(postId) {
  var assetInfo = document.getElementById('payswarm-asset-info-' + postId);
  var className = assetInfo.getAttribute('class');

  // toggle the hidden CSS state for the attribute
  if(className === 'hidden') {
    assetInfo.setAttribute('class', '');
  } else {
    assetInfo.setAttribute('class', 'hidden');
  }
}

/**
 * Sets the target of a form submission to a popup that will redirect to
 * the PaySwarm Authority.
 *
 * @param form the form that is being submitted.
 */
function showAuthorityPopup(form) {
  var width = 800;
  var height = 600;
  window.open('', 'payswarm',
    'left=' + ((screen.width-width)/2) +
    ',top=' + ((screen.height-height)/2) +
    ',width=' + width +
    ',height=' + height +
    ',resizeable,scrollbars');
  form.target = 'payswarm';
}

/**
 * Closes any pop up window and loads the given url.
 *
 * @param url the URL to load in the parent.
 */
function closePopup(url) {
  if(window.opener === null) {
    window.location = url;
  } else {
    window.close();
    window.opener.location = url;
  }
}

/**
 * Shows/hides the license input field in the payswarm meta box.
 *
 * @param container the ID of the license input container.
 * @param checkbox the ID of the default license checkbox.
 */
function toggleLicenseInput(container, checkbox) {
  container = document.getElementById(container);
  checkbox = document.getElementById(checkbox);
  container.className = (checkbox.checked ? 'hidden' : '');
}
<|endoftext|>


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

exports['create'] = function (test) {
    var c = conduit.newInstance(['foo','bar']);
    test.ok(c, 'Cannot create conduit');
    test.done();
};
<commit_msg>Testing drone CI 3<commit_after>var conduit = require('../index');

exports['create'] = function (test) {
    var c = conduit.newInstance(['foo','bar']);
    test.ok(c, 'Cannot create conduit.');
    test.done();
};
<|endoftext|>


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

    (function () {
        var el = document.querySelectorAll('.input-group-btn > button');

        function toggleCode (index) {
            var name = el[index].getAttribute('data-el');
            var btnIcon = el[index].querySelector('span');

            el[index].addEventListener('click', function() {
                document.getElementById(name).classList.toggle('hidden');
                btnIcon.classList.toggle('caret-open');
            });
        }

        if (el) {
            for (var i = 0, len = el.length; i < len; i++) {
                toggleCode(i);
            }
        }
    })();

    (function () {
        var el = document.querySelectorAll('input[type="text"');

        if (el) {
            for (var i = 0, len = el.length; i < len; i++) {
                el[i].addEventListener('focus', function() {
                    this.select();
                });
                el[i].addEventListener('mouseup', function(a) {
                    a.preventDefault();
                });
            }
        }
    })();

    (function() {
        function loadGhbtns() {
            var iframeEl = document.createElement('iframe');

            iframeEl.setAttribute('src', 'https://ghbtns.com/github-btn.html?user=MaxCDN&repo=bootstrap-cdn&type=watch&count=true');
            iframeEl.title = 'Star on GitHub';
            iframeEl.style.width = '110px';
            iframeEl.style.height = '20px';

            document.getElementById('ghbtns-badge').appendChild(iframeEl);
        }

        /* eslint-disable */
        function loadTwitter() {
            window.twttr = (function(d, s, id) {
                var js, fjs = d.getElementsByTagName(s)[0],
                    t = window.twttr || {};
                if (d.getElementById(id)) return t;
                js = d.createElement(s);
                js.id = id;
                js.src = 'https://platform.twitter.com/widgets.js';
                fjs.parentNode.insertBefore(js, fjs);

                t._e = [];
                t.ready = function(f) {
                    t._e.push(f);
                };

                return t;
            }(document, 'script', 'twitter-wjs'));
        }
        /* eslint-enable */

        function onLoad() {
            loadGhbtns();
            loadTwitter();
        }

        if (window.addEventListener) {
            window.addEventListener('load', onLoad, false);
        } else if (window.attachEvent) {
            window.attachEvent('onload', onLoad);
        } else {
            window.onload = onLoad;
        }
    })();

    (function () {
        function gaEvent(e) {
            if (typeof e.target !== 'undefined') {
                var action = e.target.getAttribute('data-ga-action');
                var category = e.target.getAttribute('data-ga-category');
                var label = e.target.getAttribute('data-ga-label');
                var value = parseInt(e.target.getAttribute('data-ga-value'), 10);

                if (typeof ga !== 'undefined' && typeof category !== 'undefined' && typeof action !== 'undefined') {
                    window.ga('send', 'event', category, action, label, value, {});
                }
            }
        }

        /* eslint-disable */
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-32253110-1', 'bootstrapcdn.com');
        ga('send', 'pageview');

        if (window.addEventListener) {
            window.addEventListener('click', gaEvent, false);
        } else if (window.attachEvent) {
            window.attachEvent('click', gaEvent);
        } else {
            window.onclick = gaEvent;
        }
        /* eslint-enable */
    })();

})();
<commit_msg>Tweak main.js. (#807)<commit_after>(function mainJS() {
    'use strict';

    (function toggleInputCaret() {
        var selector = '.input-group-btn > button';
        var el = document.querySelectorAll(selector);

        function toggleCode(index) {
            var name = el[index].getAttribute('data-el');
            var btnIcon = el[index].querySelector('span');

            el[index].addEventListener('click', function() {
                document.getElementById(name).classList.toggle('hidden');
                btnIcon.classList.toggle('caret-open');
            });
        }

        for (var i = 0, len = el.length; i < len; i++) {
            toggleCode(i);
        }
    })();

    (function selectInputContent() {
        var selector = 'input[type="text"]';
        var el = document.querySelectorAll(selector);

        for (var i = 0, len = el.length; i < len; i++) {
            el[i].addEventListener('focus', function() {
                this.select();
            });
            el[i].addEventListener('mouseup', function (event) {
                event.preventDefault();
            });
        }
    })();

    (function loadScripts() {
        function loadGhbtns() {
            var iframeEl = document.createElement('iframe');

            iframeEl.setAttribute('src', 'https://ghbtns.com/github-btn.html?user=MaxCDN&repo=bootstrap-cdn&type=watch&count=true');
            iframeEl.title = 'Star on GitHub';
            iframeEl.style.width = '110px';
            iframeEl.style.height = '20px';

            document.getElementById('ghbtns-badge').appendChild(iframeEl);
        }

        /* eslint-disable */
        function loadTwitterScript() {
            window.twttr = (function(d, s, id) {
                var js, fjs = d.getElementsByTagName(s)[0],
                    t = window.twttr || {};
                if (d.getElementById(id)) return t;
                js = d.createElement(s);
                js.id = id;
                js.src = 'https://platform.twitter.com/widgets.js';
                fjs.parentNode.insertBefore(js, fjs);

                t._e = [];
                t.ready = function(f) {
                    t._e.push(f);
                };

                return t;
            }(document, 'script', 'twitter-wjs'));
        }
        /* eslint-enable */

        function onLoad() {
            loadGhbtns();
            loadTwitterScript();
        }

        window.addEventListener('load', onLoad, false);
    })();

    (function googleAnalytics() {
        function gaEvent(e) {
            if (typeof e.target !== 'undefined') {
                var action = e.target.getAttribute('data-ga-action');
                var category = e.target.getAttribute('data-ga-category');
                var label = e.target.getAttribute('data-ga-label');
                var value = parseInt(e.target.getAttribute('data-ga-value'), 10);

                if (typeof ga !== 'undefined' && typeof category !== 'undefined' && typeof action !== 'undefined') {
                    window.ga('send', 'event', category, action, label, value, {});
                }
            }
        }

        /* eslint-disable */
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-32253110-1', 'bootstrapcdn.com');
        ga('send', 'pageview');

        window.addEventListener('click', gaEvent, false);
        /* eslint-enable */
    })();

})();
<|endoftext|>


<commit_before>var glpPixelInspector = function (gl) {
  this.gl = gl;

  this.blendProp = null;
  this.blendFuncSFactor = null;
  this.blendFuncDFactor = null;
  this.depthTest = null;
  this.clearColor = null;
  this.vertexShaders = {};
  this.fragmentShaders = {};
  this.programs = [];
  this.programsMap = {};
  this.programUniformLocations = {};
  this.originalPrograms = {};
  this.locationMap = {};
  this.enabled = false;
}

/**
 * Applies uniform to WebGL context
 */
glpPixelInspector.prototype.applyUniform = function (uniform) {
  var loc = uniform.loc;
  var type = uniform.type;
  var value = uniform.value;
  if (type == this.gl.FLOAT) {
    this.gl.uniform1f(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC2) {
    this.gl.uniform2fv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC3) {
    this.gl.uniform3fv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC4) {
    this.gl.uniform4fv(loc, value);
    return;
  }
  if (type == this.gl.INT) {
    this.gl.uniform1i(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC2) {
    this.gl.uniform2iv(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC3) {
    this.gl.uniform3iv(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC4) {
    this.gl.uniform4iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL) {
    this.gl.uniform1i(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC2) {
    this.gl.uniform2iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC3) {
    this.gl.uniform3iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC4) {
    this.gl.uniform4iv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT2) {
    this.gl.uniformMatrix2fv(loc, false, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT3) {
    this.gl.uniformMatrix3fv(loc, false, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT4) {
    this.gl.uniformMatrix4fv(loc, false, value);
    return;
  }
  if (type == this.gl.SAMPLER_2D || type == this.gl.SAMPLER_CUBE) {
    this.gl.uniform1i(loc, value);
    return;
  }
}

/**
 * Enables the pixel inspector and returns the appropriate fragment shader
 * @return {WebGLShader} Pixel Inspector Shader
 */
glpPixelInspector.prototype.enable = function() {
    this.blendProp = this.gl.getParameter(this.gl.BLEND);
    this.gl.enable(this.gl.BLEND);

    this.blendFuncSFactor = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
    this.blendFuncDFactor = this.gl.getParameter(this.gl.BLEND_DST_RGB);
    this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);

    this.depthTest = this.gl.getParameter(this.gl.DEPTH_TEST);
    this.gl.disable(this.gl.DEPTH_TEST);

    this.clearColor = this.gl.getParameter(this.gl.COLOR_CLEAR_VALUE);
    this.gl.clearColor(0.0, 1.0, 0.0, 1.0);

    this.switchToProgram();

    this.enabled = true;
}

/**
 * Disable the pixel inspector and returns the appropriate fragment shader
 * @return {WebGLShader} Pixel Inspector Shader
 */
glpPixelInspector.prototype.disable = function() {
    if (!this.enabled) {
      return;
    }
    this.enabled = false;

    if (!this.blendProp) {
      this.gl.disable(this.gl.BLEND);
    } else {
      if (this.blendFuncSFactor && this.blendFuncDFactor) {
        this.gl.blendFunc(this.blendFuncSFactor, this.blendFuncDFactor);
      }
    }

    if (this.depthTest) {
      this.gl.enable(this.gl.DEPTH_TEST);
    }

    if (this.clearColor) {
      this.gl.clearColor.apply(this.gl, this.clearColor);
    }

    var currentProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
    if (currentProgram.__uuid in this.originalPrograms) {
      var newProgram = this.originalPrograms[currentProgram.__uuid];
      this.gl.useProgram(newProgram);
      this.copyUniforms(currentProgram, newProgram);
    }
}

/**
 * Copies uniforms from oldProgram to newProgram
 */
glpPixelInspector.prototype.copyUniforms = function(oldProgram, program) {
  var activeUniforms = this.gl.getProgramParameter(program, this.gl.ACTIVE_UNIFORMS);
  this.locationMap[program.__uuid] = {};

  for (var i=0; i < activeUniforms; i++) {
      var uniform = this.gl.getActiveUniform(program, i);
      var oldLocation = this.gl.getUniformLocation(oldProgram, uniform.name);
      var newLocation = this.gl.getUniformLocation(program, uniform.name);
      if (!oldLocation) {
        continue;
      }
      this.locationMap[program.__uuid][oldLocation.__uuid] = newLocation;

      uniform.loc = newLocation;
      uniform.value = this.gl.getUniform(oldProgram, oldLocation);
      if (uniform.value != null) {
        this.applyUniform(uniform);
      }
  }
}

/**
 * Copies attributes from oldProgram to newProgram
 */
glpPixelInspector.prototype.copyAttributes = function(oldProgram, program) {
  var activeAttributes = this.gl.getProgramParameter(oldProgram, this.gl.ACTIVE_ATTRIBUTES);

  for (var i=0; i < activeAttributes; i++) {
      var attribute = this.gl.getActiveAttrib(oldProgram, i);

      this.gl.bindAttribLocation(program, attribute.index, attribute.name);
      if (attribute.size > 1) {
        this.gl.vertexAttribPointer(
          attribute.index,
          attribute.size,
          attribute.type,
          attribute.normalized,
          attribute.stride,
          attribute.offset
        );
      }

      this.gl.enableVertexAttribArray(attribute.index);
  }
}

/**
 * Switches the current program to the pixel inspector program
 */
glpPixelInspector.prototype.switchToProgram = function() {
  var oldProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
  var program = this.getProgram(oldProgram);
  this.originalPrograms[program.__uuid] = oldProgram;
  this.switchProgram(oldProgram, program);
}

/**
 * Switches the current program and copies over location and attribute data
 */
glpPixelInspector.prototype.switchProgram = function(oldProgram, program) {
  if (!this.enabled) {
    return;
  }
  this.gl.useProgram(program);
  this.copyUniforms(oldProgram, program);
  this.copyAttributes(oldProgram, program);
}

glpPixelInspector.prototype.hasProgram = function(program) {
  return this.programs.indexOf(program.__uuid) >= 0;
}

/**
 * Returns the pixel inspector fragment shader
 * @return {WebGLShader} Pixel Inspector Fragment Shader
 */
glpPixelInspector.prototype.getFragShader = function() {
    var fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
    var shaderStr = 'precision mediump float;' +
        'void main(void) {' +
            'gl_FragColor = vec4(1.0, 0.0, 0.0, 0.10);' +
        '}';

    this.gl.shaderSource(fragShader, shaderStr);
    this.gl.compileShader(fragShader);

    return fragShader;
}

/**
 * Returns the appropriate pixel inspector program
 * @param {WebGLProgram} Original Program
 * @return {WebGLProgram.__uuid} Pixel Inspector Progam
 */
glpPixelInspector.prototype.getProgram = function(originalProgram) {
    if (originalProgram.__uuid in this.programsMap) {
        return this.programsMap[originalProgram.__uuid];
    }

    var program = this.gl.createProgram();

    this.gl.attachShader(program, this.vertexShaders[originalProgram.__uuid]);
    this.gl.attachShader(program, this.getFragShader());
    this.gl.linkProgram(program);
    this.gl.validateProgram(program);

    this.programs.push(program.__uuid);
    this.programsMap[originalProgram.__uuid] = program;

    return program;
}

glpPixelInspector.prototype.storeShaders = function(program, shader) {
  var shaderType = this.gl.getShaderParameter(shader, this.gl.SHADER_TYPE);

  // TODO: verify valid input
  // store vertex shaders associated with program
  if (shaderType == this.gl.VERTEX_SHADER) {
    this.vertexShaders[program.__uuid] = shader;
  } else {
    this.fragmentShaders[program.__uuid] = shader;
  }
}

glpPixelInspector.prototype.saveStates = function(arg, truth) {
  if (this.enabled) {
    if (arg == this.gl.DEPTH_TEST) {
      this.depthTest = truth;
      return true;
    } else if (arg == this.gl.BLEND) {
      this.blendProp = truth;
      return true;
    }
  }
  return this.enabled;
}

glpPixelInspector.prototype.storeBlendStates = function(sFactor, dFactor) {
  if (this.enabled) {
    this.blendFuncSFactor = sFactor;
    this.blendFuncDFactor = dFactor;
  }
  return this.enabled;
}

glpPixelInspector.prototype.storeClearColorStates = function(args) {
  // TODO: verify valid input
  if (this.enabled) {
    this.clearColor = args;
  }
  return this.enabled;
}

glpPixelInspector.prototype.uniforms = function(args) {
  if (this.enabled) {
    var program = args[0];
    var location = args[1];
    if (this.programs.indexOf(program.__uuid) >= 0) {
      if (location in this.locationMap[program.__uuid]) {
        // the program is the pixel inspector version and we're using the original location
        args[1] = this.locationMap[program.__uuid][location.__uuid];
      } else {
      }
    } else {
      // the program is not a pixel inspector
      // if they're using the wrong location, lets just swap programs
      args[0] = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
    }
  }
  return args;
}

glpPixelInspector.prototype.hasUniformLocation = function(program, name) {
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  return (name in this.programUniformLocations[program.__uuid]);
}

glpPixelInspector.prototype.getUniformLocation = function(program, name) {
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  return this.programUniformLocations[program.__uuid][name];
}

glpPixelInspector.prototype.setUniformLocation = function(program, name, location) {
  location.__uuid = glpHelpers.guid();
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  this.programUniformLocations[program.__uuid][name] = location;
  return location;
}

glpPixelInspector.prototype.remapLocations = function(args) {
  if (this.enabled) {
    if (args[0] &&
        this.programs.indexOf(this.gl.getParameter(this.gl.CURRENT_PROGRAM).__uuid) >= 0) {
      args[0] =
        this.locationMap[this.gl.getParameter(this.gl.CURRENT_PROGRAM).__uuid][args[0].__uuid];
    }
  }
  return args
}
<commit_msg>get attached shaders first.<commit_after>var glpPixelInspector = function (gl) {
  this.gl = gl;

  this.blendProp = null;
  this.blendFuncSFactor = null;
  this.blendFuncDFactor = null;
  this.depthTest = null;
  this.clearColor = null;
  this.vertexShaders = {};
  this.fragmentShaders = {};
  this.programs = [];
  this.programsMap = {};
  this.programUniformLocations = {};
  this.originalPrograms = {};
  this.locationMap = {};
  this.enabled = false;
}

/**
 * Applies uniform to WebGL context
 */
glpPixelInspector.prototype.applyUniform = function (uniform) {
  var loc = uniform.loc;
  var type = uniform.type;
  var value = uniform.value;
  if (type == this.gl.FLOAT) {
    this.gl.uniform1f(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC2) {
    this.gl.uniform2fv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC3) {
    this.gl.uniform3fv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_VEC4) {
    this.gl.uniform4fv(loc, value);
    return;
  }
  if (type == this.gl.INT) {
    this.gl.uniform1i(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC2) {
    this.gl.uniform2iv(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC3) {
    this.gl.uniform3iv(loc, value);
    return;
  }
  if (type == this.gl.INT_VEC4) {
    this.gl.uniform4iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL) {
    this.gl.uniform1i(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC2) {
    this.gl.uniform2iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC3) {
    this.gl.uniform3iv(loc, value);
    return;
  }
  if (type == this.gl.BOOL_VEC4) {
    this.gl.uniform4iv(loc, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT2) {
    this.gl.uniformMatrix2fv(loc, false, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT3) {
    this.gl.uniformMatrix3fv(loc, false, value);
    return;
  }
  if (type == this.gl.FLOAT_MAT4) {
    this.gl.uniformMatrix4fv(loc, false, value);
    return;
  }
  if (type == this.gl.SAMPLER_2D || type == this.gl.SAMPLER_CUBE) {
    this.gl.uniform1i(loc, value);
    return;
  }
}

/**
 * Enables the pixel inspector and returns the appropriate fragment shader
 * @return {WebGLShader} Pixel Inspector Shader
 */
glpPixelInspector.prototype.enable = function() {
    this.blendProp = this.gl.getParameter(this.gl.BLEND);
    this.gl.enable(this.gl.BLEND);

    this.blendFuncSFactor = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
    this.blendFuncDFactor = this.gl.getParameter(this.gl.BLEND_DST_RGB);
    this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);

    this.depthTest = this.gl.getParameter(this.gl.DEPTH_TEST);
    this.gl.disable(this.gl.DEPTH_TEST);

    this.clearColor = this.gl.getParameter(this.gl.COLOR_CLEAR_VALUE);
    this.gl.clearColor(0.0, 1.0, 0.0, 1.0);

    this.switchToProgram();

    this.enabled = true;
}

/**
 * Disable the pixel inspector and returns the appropriate fragment shader
 * @return {WebGLShader} Pixel Inspector Shader
 */
glpPixelInspector.prototype.disable = function() {
    if (!this.enabled) {
      return;
    }
    this.enabled = false;

    if (!this.blendProp) {
      this.gl.disable(this.gl.BLEND);
    } else {
      if (this.blendFuncSFactor && this.blendFuncDFactor) {
        this.gl.blendFunc(this.blendFuncSFactor, this.blendFuncDFactor);
      }
    }

    if (this.depthTest) {
      this.gl.enable(this.gl.DEPTH_TEST);
    }

    if (this.clearColor) {
      this.gl.clearColor.apply(this.gl, this.clearColor);
    }

    var currentProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
    if (currentProgram.__uuid in this.originalPrograms) {
      var newProgram = this.originalPrograms[currentProgram.__uuid];
      this.gl.useProgram(newProgram);
      this.copyUniforms(currentProgram, newProgram);
    }
}

/**
 * Copies uniforms from oldProgram to newProgram
 */
glpPixelInspector.prototype.copyUniforms = function(oldProgram, program) {
  var activeUniforms = this.gl.getProgramParameter(program, this.gl.ACTIVE_UNIFORMS);
  this.locationMap[program.__uuid] = {};

  for (var i=0; i < activeUniforms; i++) {
      var uniform = this.gl.getActiveUniform(program, i);
      var oldLocation = this.gl.getUniformLocation(oldProgram, uniform.name);
      var newLocation = this.gl.getUniformLocation(program, uniform.name);
      if (!oldLocation) {
        continue;
      }
      this.locationMap[program.__uuid][oldLocation.__uuid] = newLocation;

      uniform.loc = newLocation;
      uniform.value = this.gl.getUniform(oldProgram, oldLocation);
      if (uniform.value != null) {
        this.applyUniform(uniform);
      }
  }
}

/**
 * Copies attributes from oldProgram to newProgram
 */
glpPixelInspector.prototype.copyAttributes = function(oldProgram, program) {
  var activeAttributes = this.gl.getProgramParameter(oldProgram, this.gl.ACTIVE_ATTRIBUTES);

  for (var i=0; i < activeAttributes; i++) {
      var attribute = this.gl.getActiveAttrib(oldProgram, i);

      this.gl.bindAttribLocation(program, attribute.index, attribute.name);
      if (attribute.size > 1) {
        this.gl.vertexAttribPointer(
          attribute.index,
          attribute.size,
          attribute.type,
          attribute.normalized,
          attribute.stride,
          attribute.offset
        );
      }

      this.gl.enableVertexAttribArray(attribute.index);
  }
}

/**
 * Switches the current program to the pixel inspector program
 */
glpPixelInspector.prototype.switchToProgram = function() {
  var oldProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
  var program = this.getProgram(oldProgram);
  this.originalPrograms[program.__uuid] = oldProgram;
  this.switchProgram(oldProgram, program);
}

/**
 * Switches the current program and copies over location and attribute data
 */
glpPixelInspector.prototype.switchProgram = function(oldProgram, program) {
  if (!this.enabled) {
    return;
  }
  this.gl.useProgram(program);
  this.copyUniforms(oldProgram, program);
  this.copyAttributes(oldProgram, program);
}

glpPixelInspector.prototype.hasProgram = function(program) {
  return this.programs.indexOf(program.__uuid) >= 0;
}

/**
 * Returns the pixel inspector fragment shader
 * @return {WebGLShader} Pixel Inspector Fragment Shader
 */
glpPixelInspector.prototype.getFragShader = function() {
    var fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
    var shaderStr = 'precision mediump float;' +
        'void main(void) {' +
            'gl_FragColor = vec4(1.0, 0.0, 0.0, 0.10);' +
        '}';

    this.gl.shaderSource(fragShader, shaderStr);
    this.gl.compileShader(fragShader);

    return fragShader;
}

/**
 * Returns the appropriate pixel inspector program
 * @param {WebGLProgram} Original Program
 * @return {WebGLProgram.__uuid} Pixel Inspector Progam
 */
glpPixelInspector.prototype.getProgram = function(originalProgram) {
    if (originalProgram.__uuid in this.programsMap) {
        return this.programsMap[originalProgram.__uuid];
    }

    var program = this.gl.createProgram();

    const attachedShaders = this.gl.getAttachedShaders(originalProgram);
    attachedShaders.forEach(shader => {
      this.storeShaders(program, shader);
    });

    this.gl.attachShader(program, this.vertexShaders[originalProgram.__uuid]);
    this.gl.attachShader(program, this.getFragShader());
    this.gl.linkProgram(program);
    this.gl.validateProgram(program);

    this.programs.push(program.__uuid);
    this.programsMap[originalProgram.__uuid] = program;

    return program;
}

glpPixelInspector.prototype.storeShaders = function(program, shader) {
  var shaderType = this.gl.getShaderParameter(shader, this.gl.SHADER_TYPE);

  // TODO: verify valid input
  // store vertex shaders associated with program
  if (shaderType == this.gl.VERTEX_SHADER) {
    this.vertexShaders[program.__uuid] = shader;
  } else {
    this.fragmentShaders[program.__uuid] = shader;
  }
}

glpPixelInspector.prototype.saveStates = function(arg, truth) {
  if (this.enabled) {
    if (arg == this.gl.DEPTH_TEST) {
      this.depthTest = truth;
      return true;
    } else if (arg == this.gl.BLEND) {
      this.blendProp = truth;
      return true;
    }
  }
  return this.enabled;
}

glpPixelInspector.prototype.storeBlendStates = function(sFactor, dFactor) {
  if (this.enabled) {
    this.blendFuncSFactor = sFactor;
    this.blendFuncDFactor = dFactor;
  }
  return this.enabled;
}

glpPixelInspector.prototype.storeClearColorStates = function(args) {
  // TODO: verify valid input
  if (this.enabled) {
    this.clearColor = args;
  }
  return this.enabled;
}

glpPixelInspector.prototype.uniforms = function(args) {
  if (this.enabled) {
    var program = args[0];
    var location = args[1];
    if (this.programs.indexOf(program.__uuid) >= 0) {
      if (location in this.locationMap[program.__uuid]) {
        // the program is the pixel inspector version and we're using the original location
        args[1] = this.locationMap[program.__uuid][location.__uuid];
      } else {
      }
    } else {
      // the program is not a pixel inspector
      // if they're using the wrong location, lets just swap programs
      args[0] = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
    }
  }
  return args;
}

glpPixelInspector.prototype.hasUniformLocation = function(program, name) {
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  return (name in this.programUniformLocations[program.__uuid]);
}

glpPixelInspector.prototype.getUniformLocation = function(program, name) {
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  return this.programUniformLocations[program.__uuid][name];
}

glpPixelInspector.prototype.setUniformLocation = function(program, name, location) {
  location.__uuid = glpHelpers.guid();
  if (!(program.__uuid in this.programUniformLocations)) {
    this.programUniformLocations[program.__uuid] = {}
  }
  this.programUniformLocations[program.__uuid][name] = location;
  return location;
}

glpPixelInspector.prototype.remapLocations = function(args) {
  if (this.enabled) {
    if (args[0] &&
        this.programs.indexOf(this.gl.getParameter(this.gl.CURRENT_PROGRAM).__uuid) >= 0) {
      args[0] =
        this.locationMap[this.gl.getParameter(this.gl.CURRENT_PROGRAM).__uuid][args[0].__uuid];
    }
  }
  return args
}
<|endoftext|>


<commit_before>function setLoadingSpinner() {
  document.getElementById("loader").classList.add("fa-spin");
}

function unsetLoadingSpinner() {
  document.getElementById("loader").classList.remove("fa-spin");
}

function dropCancelHandler(event) {
  if (event.preventDefault) event.preventDefault();
  event.dataTransfer.dropEffect = 'copy';
  return false;
}

function flash(color) {
  document.body.classList.add("flash-"+color);
  window.setTimeout(function() {
    document.body.classList.remove("flash-"+color);
  }, 2100);
}

function dropHandler(category, event) {
  event.preventDefault();
  setLoadingSpinner();
  var url = event.dataTransfer.getData('Text');
  if(validUrl(url)) {
    flash("green");
    unsetLoadingSpinner();
  } else {
    flash("red");
    unsetLoadingSpinner();
  }
}

function validUrl(url) {
  /**
   * this regex is extracted from jquery-validation by Jörn Zaefferer
   * Copyright (c) 2013 Jörn Zaefferer Licensed under the MIT license.
   * See https://github.com/jzaefferer/jquery-validation
   */
  return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url);
}

document.addEventListener("DOMContentLoaded", function() {
  var dropzones = document.querySelectorAll(".dropzone");
  for(var i=0; i < dropzones.length; i++) {
    dropzones[i].addEventListener("dragenter", dropCancelHandler);
    dropzones[i].addEventListener("dragover", dropCancelHandler);
    dropzones[i].addEventListener("drop", dropHandler.bind(this, dropzones[i].id));
  }
});
<commit_msg>well, I don't really care about weird browsers...<commit_after>function setLoadingSpinner() {
  document.getElementById("loader").classList.add("fa-spin");
}

function unsetLoadingSpinner() {
  document.getElementById("loader").classList.remove("fa-spin");
}

function dropCancelHandler(event) {
  event.preventDefault();
  event.dataTransfer.dropEffect = 'copy';
  return false;
}

function flash(color) {
  document.body.classList.add("flash-"+color);
  window.setTimeout(function() {
    document.body.classList.remove("flash-"+color);
  }, 2100);
}

function dropHandler(category, event) {
  event.preventDefault();
  setLoadingSpinner();
  var url = event.dataTransfer.getData('Text');
  if(validUrl(url)) {
    flash("green");
    unsetLoadingSpinner();
  } else {
    flash("red");
    unsetLoadingSpinner();
  }
}

function validUrl(url) {
  /**
   * this regex is extracted from jquery-validation by Jörn Zaefferer
   * Copyright (c) 2013 Jörn Zaefferer Licensed under the MIT license.
   * See https://github.com/jzaefferer/jquery-validation
   */
  return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url);
}

document.addEventListener("DOMContentLoaded", function() {
  var dropzones = document.querySelectorAll(".dropzone");
  for(var i=0; i < dropzones.length; i++) {
    dropzones[i].addEventListener("dragenter", dropCancelHandler);
    dropzones[i].addEventListener("dragover", dropCancelHandler);
    dropzones[i].addEventListener("drop", dropHandler.bind(this, dropzones[i].id));
  }
});
<|endoftext|>