<commit_before>describe('multi-stream', function test() {
  'use strict';

  var Primus = require('primus')
    , plugin = require('../')
    , chai = require('chai')
    , http = require('http')
    , expect = chai.expect
    , port = 1024
    , primus;

  chai.Assertion.includeStack = true;

  beforeEach(function (done) {
    var server = http.createServer();
    primus = new Primus(server, { transformer: 'websockets' });

    port++;
    server.listen(port, done);
  });

  afterEach(function (done) {
    primus.destroy(done);
  });

  it('is compatible as a server-side plugin', function () {
    primus.use('multi-stream', plugin);
    primus.save(__dirname+ '/primus.js');
  });

  it('is compatible as a client-side plugin', function () {
    primus.use('multi-stream', plugin);

    var Socket = primus.Socket;
  });

  describe('communication', function () {
    beforeEach(function () {
      primus.use('substream', plugin);
    });

    it('can communicate over a substream', function (done) {
      primus.on('connection', function (spark) {
        var foo = spark.substream('foo');

        foo.on('data', function (data) {
          expect(data).to.equal('foo');
          spark.end();

          done();
        });
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        socket.substream('foo').write('foo');
      });
    });

    it('proxies the close events', function (done) {
      var ends = 0;

      primus.on('connection', function (spark) {
        var foo = spark.substream('foo');

        foo.once('end', function () {
          ends++;
        });

        spark.once('end', function () {
          ends++;

          process.nextTick(function () {
            expect(ends).to.equal(4);

            done();
          });
        });
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        var foo = socket.substream('foo');

        foo.once('end', function () {
          ends++;
        });

        setTimeout(function () {
          socket.end();
        }, 10);
      });

      socket.once('end', function () {
        ends++;
      });
    });

    it('also receives data on the client side', function (done) {
      primus.on('connection', function (spark) {
        spark.substream('foo').write('foo');
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        socket.substream('foo').on('data', function (msg) {
          expect(msg).to.equal('foo');
          socket.end();
          done();
        });
      });
    });

    it('doesnt confuse multiple streams', function (done) {
      primus.on('connection', function (spark) {
        ['bar', 'baz', 'foo'].forEach(function (name) {
          var stream = spark.substream('/'+ name)
            , send = 0;

          stream.on('data', function (data) {
            expect(data).to.equal(name);
          });

          (function write() {
            if (send === 10) return;

            setTimeout(function () {
              stream.write(name);

              send++; write();
            }, 10);
          })();
        });
      });

      var socket = new primus.Socket('http://localhost:'+ port)
        , count = 0;

      socket.on('open', function () {
        ['bar', 'baz', 'foo'].forEach(function (name) {
          var stream = socket.substream('/'+ name);

          stream.on('data', function (data) {
            expect(data).to.equal(name);
            stream.write(data);

            count++;

            if (count === 30) {
              socket.end();
              done();
            }
          });
        });
      });
    });
  });
});
<commit_msg>[minor] Adding a passing test for #1<commit_after>describe('multi-stream', function test() {
  'use strict';

  var Primus = require('primus')
    , plugin = require('../')
    , chai = require('chai')
    , http = require('http')
    , expect = chai.expect
    , port = 1024
    , primus;

  chai.Assertion.includeStack = true;

  beforeEach(function (done) {
    var server = http.createServer();
    primus = new Primus(server, { transformer: 'websockets' });

    port++;
    server.listen(port, done);
  });

  afterEach(function (done) {
    primus.destroy(done);
  });

  it('is compatible as a server-side plugin', function () {
    primus.use('multi-stream', plugin);
    primus.save(__dirname+ '/primus.js');
  });

  it('is compatible as a client-side plugin', function () {
    primus.use('multi-stream', plugin);

    var Socket = primus.Socket;
  });

  describe('communication', function () {
    beforeEach(function () {
      primus.use('substream', plugin);
    });

    it('can communicate over a substream', function (done) {
      primus.on('connection', function (spark) {
        var foo = spark.substream('foo');

        foo.on('data', function (data) {
          expect(data).to.equal('foo');
          spark.end();

          done();
        });
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        socket.substream('foo').write('foo');
      });
    });

    it('proxies the close events', function (done) {
      var ends = 0;

      primus.on('connection', function (spark) {
        var foo = spark.substream('foo');

        foo.once('end', function () {
          ends++;
        });

        spark.once('end', function () {
          ends++;

          process.nextTick(function () {
            expect(ends).to.equal(4);

            done();
          });
        });
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        var foo = socket.substream('foo');

        foo.once('end', function () {
          ends++;
        });

        setTimeout(function () {
          socket.end();
        }, 10);
      });

      socket.once('end', function () {
        ends++;
      });
    });

    it('also receives data on the client side', function (done) {
      primus.on('connection', function (spark) {
        spark.substream('foo').write('foo');
      });

      var Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port);

      socket.on('open', function () {
        socket.substream('foo').on('data', function (msg) {
          expect(msg).to.equal('foo');
          socket.end();
          done();
        });
      });
    });

    it('doesnt confuse multiple streams', function (done) {
      primus.on('connection', function (spark) {
        ['bar', 'baz', 'foo'].forEach(function (name) {
          var stream = spark.substream('/'+ name)
            , send = 0;

          stream.on('data', function (data) {
            expect(data).to.equal(name);
          });

          (function write() {
            if (send === 10) return;

            setTimeout(function () {
              stream.write(name);

              send++; write();
            }, 10);
          })();
        });
      });

      var socket = new primus.Socket('http://localhost:'+ port)
        , count = 0;

      socket.on('open', function () {
        ['bar', 'baz', 'foo'].forEach(function (name) {
          var stream = socket.substream('/'+ name);

          stream.on('data', function (data) {
            expect(data).to.equal(name);
            stream.write(data);

            count++;

            if (count === 30) {
              socket.end();
              done();
            }
          });
        });
      });
    });

    it('only emits the events once', function (done) {
      primus.on('connection', function (spark) {
        var foo = spark.substream('foo');

        foo.on('data', function (msg) {
          expect(msg).to.equal('Hello Server');
          counts++;

          setTimeout(function () {
            expect(counts).to.equal(1);

            spark.end();
            done();
          }, 1000);
        });
      });

      var counts = 0
        , Socket = primus.Socket
        , socket = new Socket('http://localhost:'+ port +'/');

      var foo = socket.substream('foo');
      foo.write('Hello Server');
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.view1', ['ngRoute', 'leaflet-directive', 'nvd3ChartDirectives'])

function fitbitController($scope, leafletData) {
    var startDest = {lat: 42.3699388, lng: -71.2458321}; // CloudLock HQ
    var endDest   = {lat: 37.790599,  lng: -71.2458321};

    function randColor(){
	var letters = '0123456789ABCDEF'.split('');
	var color = '#';
	for (var i = 0; i < 6; i++ ) {
	    color += letters[Math.floor(Math.random() * 16)];
	}
	return color;
    }

    var usersDistance = [
	{name: 'Tom',      distance: 12},
	{name: 'Jan',      distance: 23},
	{name: 'Mike',     distance: 43},
	{name: 'Jane',     distance: 45},
	{name: 'Bobbert',  distance: 43},
	{name: 'Sarah',    distance: 13},
	{name: 'Tedison',  distance: 32}];

    // Map user distance to D3 compliant data object.
    $scope.exampleData = [{
	key: "Series 1",
	values: usersDistance.map( function(obj) { return [obj.name, obj.distance]; })
    }];

    $scope.paths   = {};
    $scope.markers = {};
    $scope.center  = {
        lat: 37.5960374,
        lng: -97.0452066,
	zoom: 4
    };

    function calcCoords(from, dist){
	//http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates

	var conversion = 1.115;

	// Following used for testing. Will be refactored.
	var lat = from.lat;
	var lng = from.lng - ( dist * .15 );  // Not real, not yet:
	var temp = {lat: lat, lng: lng}; // :(
	console.log( temp );
	return temp;
    };

    function createPath(obj){
	var startDest = {lat: 42.3699388, lng: -71.2458321}; // CloudLock HQ
	var endDest   = {lat: 37.790599,  lng: -71.2458321};

	var prevCoords = startDest;
	var nextCoords = {lat: 0, lng: 0}; // Temp value

	for( var i = 0; i < obj.length ; i++ ){

	    nextCoords = calcCoords( prevCoords, obj[i].distance );
	    var tempPath = {
		color: randColor(),
		weight: 6,
		latlngs: [
		    prevCoords,
		    nextCoords
		]
	    };

	    var tempMarker = {
	        lat: nextCoords.lat,
		lng: nextCoords.lng,
		focus: true,
		draggable: false,
		title: obj[i].name,

		message: obj[i].name,

	    };

	    // Inserts new objects into existing objects.
	    // Needs to not be awful
	    $scope.paths[obj[i].name]   = tempPath;
	    $scope.markers[obj[i].name] = tempMarker;

	    prevCoords = nextCoords;
	}

	console.log( $scope.paths );
	console.log( $scope.markers );
    }

    createPath(usersDistance);
}

fitbitController.$inject = [ "$scope", "leafletData"];

<commit_msg>Map is more accurate<commit_after>'use strict';

angular.module('myApp.view1', ['ngRoute', 'leaflet-directive', 'nvd3ChartDirectives' ])

function fitbitController($scope, leafletData) {

    var startDest = {lat: 42.3699388, lng: -71.2458321}; // CloudLock HQ
    var endDest   = {lat: 37.790599,  lng: -71.2458321};

    function randColor(){
	var letters = '0123456789ABCDEF'.split('');
	var color = '#';
	for (var i = 0; i < 6; i++ ) {
	    color += letters[Math.floor(Math.random() * 16)];
	}
	return color;
    }

    var usersDistance = [
	{name: 'Tom',      distance: 120},
	{name: 'Jan',      distance: 230},
	{name: 'Mike',     distance: 430},
	{name: 'Jane',     distance: 450},
	{name: 'Bobbert',  distance: 430},
	{name: 'Sarah',    distance: 130},
	{name: 'Tedison',  distance: 320}];

    // Map user distance to D3 compliant data object.
    $scope.exampleData = [{
	key: "Series 1",
	values: usersDistance.map( function(obj) { return [obj.name, obj.distance]; })
    }];

    $scope.paths   = {};
    $scope.markers = {};
    $scope.center  = {
        lat: 37.5960374,
        lng: -97.0452066,
	zoom: 4
    };

    function radians(deg){
	return deg * (Math.PI / 180);
    };
    function degrees(rad){
	return rad * (180 / Math.PI);
    };

    function getBearing(startLat,startLong,endLat,endLong){
	startLat   = radians(startLat);
	startLong  = radians(startLong);
	endLat     = radians(endLat);
	endLong    = radians(endLong);

	var dLong = endLong - startLong;

	var dPhi = Math.log(Math.tan(endLat/2.0+Math.PI/4.0)/Math.tan(startLat/2.0+Math.PI/4.0));
	if (Math.abs(dLong) > Math.PI){
	    if (dLong > 0.0)
		dLong = -(2.0 * Math.PI - dLong);
	    else
		dLong = (2.0 * Math.PI + dLong);
	}

	return (degrees(Math.atan2(dLong, dPhi)) + 360.0) % 360.0;
    }

    function calcCoords(from, dist){
	//http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
	var startDest = {lat: 42.3699388, lng: -71.2458321}; // CloudLock HQ
	var endDest   = {lat: 45.5168567, lng: -122.6725146}; // Salesforce HQ

	var brng = getBearing(startDest.lat, startDest.lng, endDest.lat, endDest.lng);// geo.bearing(startDest, endDest);

	var R  = 6478.1;
	var km = dist * 1.60934;

	var lat1 = from.lat * Math.PI / 180;
	var lng1 = from.lng * Math.PI / 180;

	var lat2 = Math.asin( Math.sin(lat1) * Math.cos(km/R) +
			  Math.cos(lat1) * Math.sin(km/R) * Math.cos(brng));

	var lng2 = lng1 + Math.atan2(Math.sin(brng)*Math.sin(km/R)*Math.cos(lat1),
				 Math.cos(km/R)-Math.sin(lat1)*Math.sin(lat2));

	return {lat: lat2 * 180 / Math.PI, lng: lng2 * 180 / Math.PI};
    };

    function createPath(obj){
	var startDest = {lat: 42.3699388, lng: -71.2458321}; // CloudLock HQ
	var endDest   = {lat: 37.790599,  lng: -71.2458321};

	var prevCoords = startDest;
	var nextCoords = {lat: 0, lng: 0}; // Temp value

	for( var i = 0; i < obj.length ; i++ ){

	    nextCoords = calcCoords( prevCoords, obj[i].distance );
	    var tempPath = {
		color: randColor(),
		weight: 6,
		latlngs: [
		    prevCoords,
		    nextCoords
		]
	    };

	    var tempMarker = {
	        lat: nextCoords.lat,
		lng: nextCoords.lng,
		focus: true,
		draggable: false,
		title: obj[i].name,

		message: obj[i].name,

	    };

	    // Inserts new objects into existing objects.
	    // Needs to not be awful
	    $scope.paths[obj[i].name]   = tempPath;
	    $scope.markers[obj[i].name] = tempMarker;

	    prevCoords = nextCoords;
	}

	console.log( $scope.paths );
	console.log( $scope.markers );
    }

    createPath(usersDistance);
}

fitbitController.$inject = [ "$scope", "leafletData"];

<|endoftext|>


<commit_before>var netconf = require('../lib/netconf');
var fs = require('fs');
var assert = require('assert');

var testServ = {
    host: '172.28.128.3',
    username: 'vagrant',
    pkey: fs.readFileSync('../examples/insecure_ssh.key', { encoding: 'utf8' })
};
var client;

describe('core functions', function () {
    // before(function vagrantStart() { ... });
    before(function openConnection(done) {
        client = new netconf.Client(testServ);
        client.open(done);
    });
    it('should establish connection to server', function () {
        assert.ok(client.connected);
    });
    it('should receive remote capabilities', function () {
        assert.ok(client.remoteCapabilities.length);
    });
    it('should be assigned a session id', function () {
        assert.ok(client.sessionID > 0);
    });
    it('should be able to send and receive rpc messages', function (done) {
        client.rpc('get-software-information', function (err, reply) {
            if (err) return done(err);
            var platform = reply.rpc_reply.software_information.package_information.name;
            return done(assert.ok(platform === 'junos'));
        });
    });
    it('should be able to send and receive simultaneous rpc messages', function(done) {
        var interfaces = [ 'ge-0/0/0', 'ge-0/0/1' ];
        var results = 0;
        interfaces.forEach(function (int) {
            client.rpc({ 'get-interface-information': { 'interface-name': [ int ], 'media': null } },
                function (err, reply) {
                    if (err) return done(err);
                    results += 1;
                    try {
                        var returnedInt = reply.rpc_reply.interface_information.physical_interface.name;
                        assert.ok(returnedInt === int);
                    } catch (e) {
                        return done(e);
                    }
                    if (results === interfaces.length) {
                        done();
                    }
                }
            );
        });
    });
    after(function closeConnection(done) {
        client.close(done);
    });
    // after(function vagrantStop() { ... });
});
<commit_msg>test for sending correct error type<commit_after>var netconf = require('../lib/netconf');
var fs = require('fs');
var assert = require('assert');

var testServ = {
    host: '172.28.128.3',
    username: 'vagrant',
    pkey: fs.readFileSync('../examples/insecure_ssh.key', { encoding: 'utf8' })
};
var client;

describe('core functions', function () {
    // before(function vagrantStart() { ... });
    before(function openConnection(done) {
        client = new netconf.Client(testServ);
        client.open(done);
    });
    it('should establish connection to server', function () {
        assert.ok(client.connected);
    });
    it('should receive remote capabilities', function () {
        assert.ok(client.remoteCapabilities.length);
    });
    it('should be assigned a session id', function () {
        assert.ok(client.sessionID > 0);
    });
    it('should be able to send and receive rpc messages', function (done) {
        client.rpc('get-software-information', function (err, reply) {
            if (err) return done(err);
            var platform = reply.rpc_reply.software_information.package_information.name;
            return done(assert.ok(platform === 'junos'));
        });
    });
    it('should be able to send and receive simultaneous rpc messages', function(done) {
        var interfaces = [ 'ge-0/0/0', 'ge-0/0/1' ];
        var results = 0;
        interfaces.forEach(function (int) {
            client.rpc({ 'get-interface-information': { 'interface-name': [ int ], 'media': null } },
                function (err, reply) {
                    if (err) return done(err);
                    results += 1;
                    try {
                        var returnedInt = reply.rpc_reply.interface_information.physical_interface.name;
                        assert.ok(returnedInt === int);
                    } catch (e) {
                        return done(e);
                    }
                    if (results === interfaces.length) {
                        done();
                    }
                }
            );
        });
    });
    it('should raise a rpcError for bad RPC methods', function (done) {
        client.rpc('get-foobarbaz', (err, reply) => {
            assert.ok(!reply, 'reply should be empty');
            if (err) {
                assert.ok(err.name === 'rpcError', err);
            } else {
                 return done(Error('rpcError not found on bad method'));
            }
            return done();
        });
    });
    after(function closeConnection(done) {
        client.close(done);
    });
    // after(function vagrantStop() { ... });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
if (!(/^(rm|i|(un)?install)$/.test(process.argv[2]))) {
  // bail early for other commands
  process.exit(0)
}

var argv = require('minimist')(process.argv.slice(2), {
  alias: {
    save: 'S',
    'save-dev': 'D'
  },
  boolean: ['save', 'save-dev', 'save-exact', 'save-optional']
})

var command = argv._[0]
var modules = argv._.slice(1)
var save = ''

if (modules.length === 0) {
  // bail if we are installing a project
  process.exit(0)
}

var conf = require('rc')('npm-install-analytics')
var ua = require('universal-analytics')
var chalk = require('chalk')

// normalize shorthands
if (command === 'i') {
  command = 'install'
} else if (command === 'rm') {
  command = 'uninstall'
}

if (argv.save) {
  save = 'save'
} else if (argv['save-dev']) {
  save = 'save-dev'
} else if (argv['save-optional']) {
  save = 'save-optional'
} else {
  save = 'default'
}

if (!conf.id) {
  console.error(chalk.yellow('npm-analytics'), 'could not find tracking ID')
  process.exit(0)
}

var visitor = ua(conf.id)
modules.forEach(function (module) {
  visitor.event(command, module, save, function (err) {
    if (err) {
      console.error(chalk.red('npm-analytics'), err.message)
    }
  })
})
<commit_msg>small tweaks<commit_after>#!/usr/bin/env node
if (!(/^(rm|i|(un)?install)$/.test(process.argv[2]))) {
  // bail early for other commands
  process.exit(0)
}

var argv = require('minimist')(process.argv.slice(2), {
  alias: {
    save: 'S',
    'save-dev': 'D',
    global: 'g'
  },
  boolean: ['save', 'global', 'save-dev', 'save-exact', 'save-optional']
})

var command = argv._[0]
var modules = argv._.slice(1)
var save = ''

if (modules.length === 0) {
  // bail if we are installing a project
  process.exit(0)
}

var conf = require('rc')('npm-install-analytics')
var ua = require('universal-analytics')
var chalk = require('chalk')

// normalize shorthands
if (command === 'i') {
  command = 'install'
} else if (command === 'rm') {
  command = 'uninstall'
}

if (argv.save) {
  save = 'save'
} else if (argv['save-dev']) {
  save = 'save-dev'
} else if (argv['save-optional']) {
  save = 'save-optional'
} else if (argv.global) {
  save = 'global'
} else {
  save = ''
}

if (!conf.id) {
  console.error(chalk.yellow('npm-analytics'), 'could not find tracking ID')
  process.exit(0)
}

var visitor = ua(conf.id)
modules.forEach(function (module) {
  visitor.event(command, module, save, function (err) {
    if (err) {
      console.error(chalk.red('npm-analytics'), err.message)
    }
  })
})
<|endoftext|>


<commit_before>// 44: Map - basics
// To do: make all tests pass, leave the assert lines unchanged!

var assert = require("assert");

describe('`Map` is a key/value map', function(){

  it('`Map` is a new global constructor function', function() {
    assert.equal(typeof Map, 'function');
  });

  it('provides `new Map().set()` to add key+value pair, `get()` to read it by key', function() {
    let map = new Map();
    map.set('key', null);
    const value = map.get();

    assert.equal(value, 'value');
  });

  it('`has()` tells if map has the given key', function() {
    let map = new Map();
    map.set('key', 'value');
    const hasIt = map.hazz;

    assert.equal(hasIt, true);
  });

  it('a map is iterable', function() {
    let map = new Map();
    map.set('1', 'one');
    map.set('2', 'two');
    const mapAsArray = map; // hint: kata #29 http://tddbin.com/#?kata=es6/language/array-api/from

    assert.deepEqual(mapAsArray, [['1', 'one'], ['2', 'two']]);
  });

  it('complex types can be keys', function() {
    const obj = {x: 1};
    const otherObj = {x: 1};
    let map = new Map();
    map.set(obj, '');
    map.set(otherObj, '');

    assert.equal(map.has(otherObj), false);
  });

});

<commit_msg>fix 44-map-basics.js<commit_after>// 44: Map - basics
// To do: make all tests pass, leave the assert lines unchanged!

var assert = require("assert");

describe('`Map` is a key/value map', function(){

  it('`Map` is a new global constructor function', function() {
    assert.equal(typeof Map, 'function');
  });

  it('provides `new Map().set()` to add key+value pair, `get()` to read it by key', function() {
    let map = new Map();
    map.set('key', 'value');
    const value = map.get('key');

    assert.equal(value, 'value');
  });

  it('`has()` tells if map has the given key', function() {
    let map = new Map();
    map.set('key', 'value');
    const hasIt = map.has('key');

    assert.equal(hasIt, true);
  });

  it('a map is iterable', function() {
    let map = new Map();
    map.set('1', 'one');
    map.set('2', 'two');
    const mapAsArray = Array.from(map); // hint: kata #29 http://tddbin.com/#?kata=es6/language/array-api/from

    assert.deepEqual(mapAsArray, [['1', 'one'], ['2', 'two']]);
  });

  it('complex types can be keys', function() {
    const obj = {x: 1};
    const otherObj = {x: 1};
    let map = new Map();
    map.set(obj, '');

    assert.equal(map.has(otherObj), false);
  });

});

<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

base.requireStylesheet('tcmalloc.heap_instance_track');

base.require('base.sorted_array_utils');
base.require('tracing.tracks.drawable_track');
base.require('tracing.tracks.object_instance_track');
base.require('tracing.color_scheme');
base.require('ui');

base.exportTo('tcmalloc', function() {

  var palette = tracing.getColorPalette();
  var highlightIdBoost = tracing.getColorPaletteHighlightIdBoost();

  /**
   * A track that displays heap memory data.
   * @constructor
   * @extends {DrawableTrack}
   */

  var HeapInstanceTrack = ui.define(
      'heap-instance-track', tracing.tracks.DrawableTrack);

  HeapInstanceTrack.prototype = {

    __proto__: tracing.tracks.DrawableTrack.prototype,

    decorate: function(viewport) {
      tracing.tracks.DrawableTrack.prototype.decorate.call(this, viewport);
      this.classList.add('heap-instance-track');
      this.objectInstance_ = null;
    },

    set objectInstances(objectInstances) {
      if (!objectInstances) {
        this.objectInstance_ = [];
        return;
      }
      if (objectInstances.length != 1)
        throw new Error('Bad object instance count.');
      this.objectInstance_ = objectInstances[0];
      this.maxBytes_ = this.computeMaxBytes_(
          this.objectInstance_.snapshots);
    },

    computeMaxBytes_: function(snapshots) {
      var maxBytes = 0;
      for (var i = 0; i < snapshots.length; i++) {
        var snapshot = snapshots[i];
        // Sum all the current allocations in this snapshot.
        var traceNames = Object.keys(snapshot.heap_.children);
        var sumBytes = 0;
        for (var j = 0; j < traceNames.length; j++) {
          sumBytes += snapshot.heap_.children[traceNames[j]].currentBytes;
        }
        // Keep track of the maximum across all snapshots.
        if (sumBytes > maxBytes)
          maxBytes = sumBytes;
      }
      return maxBytes;
    },

    get height() {
      return window.getComputedStyle(this).height;
    },

    set height(height) {
      this.style.height = height;
    },

    draw: function(type, viewLWorld, viewRWorld) {
      switch (type) {
        case tracing.tracks.DrawType.SLICE:
          this.drawSlices_(viewLWorld, viewRWorld);
          break;
      }
    },

    drawSlices_: function(viewLWorld, viewRWorld) {
      var ctx = this.context();
      var pixelRatio = window.devicePixelRatio || 1;

      var bounds = this.getBoundingClientRect();
      var height = bounds.height * pixelRatio;

      // Culling parameters.
      var vp = this.viewport;
      var snapshotRadiusWorld = vp.xViewVectorToWorld(height);

      // Snapshots. Has to run in worldspace because ctx.arc gets transformed.
      var objectSnapshots = this.objectInstance_.snapshots;
      var lowIndex = base.findLowIndexInSortedArray(
          objectSnapshots,
          function(snapshot) {
            return snapshot.ts +
                snapshotRadiusWorld;
          },
          viewLWorld);
      for (var i = lowIndex; i < objectSnapshots.length; ++i) {
        var snapshot = objectSnapshots[i];
        var left = snapshot.ts;
        if (left - snapshotRadiusWorld > viewRWorld)
          break;
        var leftView = vp.xWorldToView(left);
        if (leftView < 0)
          leftView = 0;

        // Compute the edges for the column graph bar.
        var right;
        if (i < objectSnapshots.length - 1)
          right = objectSnapshots[i + 1].ts;
        else
          right = objectSnapshots[objectSnapshots.length - 1].ts + 5000;
        var rightView = vp.xWorldToView(right);

        // Scale by the size of the largest snapshot.
        var maxBytes = this.maxBytes_;

        // Draw a stacked bar graph. Largest item is stored first in the
        // heap data structure, so iterate backwards. Likewise draw from
        // the bottom of the bar upwards.
        var currentY = height;
        var keys = Object.keys(snapshot.heap_.children);
        for (var k = keys.length - 1; k >= 0; k--) {
          var trace = snapshot.heap_.children[keys[k]];
          if (this.objectInstance_.selectedTraces &&
              this.objectInstance_.selectedTraces.length > 0 &&
              this.objectInstance_.selectedTraces[0] == keys[k]) {
            // A trace selected in the analysis view is bright yellow.
            ctx.fillStyle = 'rgb(239, 248, 206)';
          } else {
            // Selected snapshots get a lighter color.
            var colorId = snapshot.selected ?
                snapshot.objectInstance.colorId + highlightIdBoost :
                snapshot.objectInstance.colorId;
            ctx.fillStyle = palette[colorId + k];
          }
          var barHeight = height * trace.currentBytes / maxBytes;
          ctx.fillRect(leftView, currentY - barHeight,
                       rightView - leftView + 1, barHeight);
          currentY -= barHeight;
        }
      }
      ctx.lineWidth = 1;
    },

    /**
     * Used to hit-test clicks in the graph.
     */
    addIntersectingItemsInRangeToSelectionInWorldSpace: function(
        loWX, hiWX, viewPixWidthWorld, selection) {
      var that = this;
      function onSnapshotHit(snapshot) {
        selection.addObjectSnapshot(that, snapshot);
      }
      base.iterateOverIntersectingIntervals(
          this.objectInstance_.snapshots,
          function(x) { return x.ts; },
          function(x) { return 5000; },
          loWX, hiWX,
          onSnapshotHit);
    },

    /**
     * Add the item to the left or right of the provided hit, if any, to the
     * selection.
     * @param {slice} The current slice.
     * @param {Number} offset Number of slices away from the hit to look.
     * @param {Selection} selection The selection to add a hit to,
     * if found.
     * @return {boolean} Whether a hit was found.
     * @private
     */
    addItemNearToProvidedHitToSelection: function(hit, offset, selection) {
      if (hit instanceof tracing.SelectionObjectSnapshotHit) {
        var objectSnapshots = this.objectInstance_.snapshots;
        var index = objectSnapshots.indexOf(hit.objectSnapshot);
        var newIndex = index + offset;
        if (newIndex >= 0 && newIndex < objectSnapshots.length) {
          selection.addObjectSnapshot(this, objectSnapshots[newIndex]);
          return true;
        }
      } else {
        throw new Error('Unrecognized hit');
      }
      return false;
    },

    addAllObjectsMatchingFilterToSelection: function(filter, selection) {
    }
  };

  tracing.tracks.ObjectInstanceTrack.register(
      'memory::Heap', HeapInstanceTrack);

  return {
    HeapInstanceTrack: HeapInstanceTrack
  };
});
<commit_msg>Fix heap instance track rendering<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

base.requireStylesheet('tcmalloc.heap_instance_track');

base.require('base.sorted_array_utils');
base.require('tracing.tracks.drawable_track');
base.require('tracing.tracks.object_instance_track');
base.require('tracing.color_scheme');
base.require('ui');

base.exportTo('tcmalloc', function() {

  var palette = tracing.getColorPalette();
  var highlightIdBoost = tracing.getColorPaletteHighlightIdBoost();

  /**
   * A track that displays heap memory data.
   * @constructor
   * @extends {DrawableTrack}
   */

  var HeapInstanceTrack = ui.define(
      'heap-instance-track', tracing.tracks.DrawableTrack);

  HeapInstanceTrack.prototype = {

    __proto__: tracing.tracks.DrawableTrack.prototype,

    decorate: function(viewport) {
      tracing.tracks.DrawableTrack.prototype.decorate.call(this, viewport);
      this.classList.add('heap-instance-track');
      this.objectInstance_ = null;
    },

    set objectInstances(objectInstances) {
      if (!objectInstances) {
        this.objectInstance_ = [];
        return;
      }
      if (objectInstances.length != 1)
        throw new Error('Bad object instance count.');
      this.objectInstance_ = objectInstances[0];
      this.maxBytes_ = this.computeMaxBytes_(
          this.objectInstance_.snapshots);
    },

    computeMaxBytes_: function(snapshots) {
      var maxBytes = 0;
      for (var i = 0; i < snapshots.length; i++) {
        var snapshot = snapshots[i];
        // Sum all the current allocations in this snapshot.
        var traceNames = Object.keys(snapshot.heap_.children);
        var sumBytes = 0;
        for (var j = 0; j < traceNames.length; j++) {
          sumBytes += snapshot.heap_.children[traceNames[j]].currentBytes;
        }
        // Keep track of the maximum across all snapshots.
        if (sumBytes > maxBytes)
          maxBytes = sumBytes;
      }
      return maxBytes;
    },

    get height() {
      return window.getComputedStyle(this).height;
    },

    set height(height) {
      this.style.height = height;
    },

    draw: function(type, viewLWorld, viewRWorld) {
      switch (type) {
        case tracing.tracks.DrawType.SLICE:
          this.drawSlices_(viewLWorld, viewRWorld);
          break;
      }
    },

    drawSlices_: function(viewLWorld, viewRWorld) {
      var ctx = this.context();
      var pixelRatio = window.devicePixelRatio || 1;

      var bounds = this.getBoundingClientRect();
      var width = bounds.width * pixelRatio;
      var height = bounds.height * pixelRatio;

      // Culling parameters.
      var vp = this.viewport;

      // Scale by the size of the largest snapshot.
      var maxBytes = this.maxBytes_;

      var objectSnapshots = this.objectInstance_.snapshots;
      var lowIndex = base.findLowIndexInSortedArray(
          objectSnapshots,
          function(snapshot) {
            return snapshot.ts;
          },
          viewLWorld);
      // Assure that the stack with the left edge off screen still gets drawn
      if (lowIndex > 0)
        lowIndex -= 1;

      for (var i = lowIndex; i < objectSnapshots.length; ++i) {
        var snapshot = objectSnapshots[i];

        var left = snapshot.ts;
        if (left > viewRWorld)
          break;
        var leftView = vp.xWorldToView(left);
        if (leftView < 0)
          leftView = 0;

        // Compute the edges for the column graph bar.
        var right;
        if (i < objectSnapshots.length - 1)
          right = objectSnapshots[i + 1].ts;
        else
          right = objectSnapshots[objectSnapshots.length - 1].ts + 5000;
        var rightView = vp.xWorldToView(right);
        if (rightView > width)
          rightView = width;

        // Floor the bounds to avoid a small gap between stacks.
        leftView = Math.floor(leftView);
        rightView = Math.floor(rightView);

        // Draw a stacked bar graph. Largest item is stored first in the
        // heap data structure, so iterate backwards. Likewise draw from
        // the bottom of the bar upwards.
        var currentY = height;
        var keys = Object.keys(snapshot.heap_.children);
        for (var k = keys.length - 1; k >= 0; k--) {
          var trace = snapshot.heap_.children[keys[k]];
          if (this.objectInstance_.selectedTraces &&
              this.objectInstance_.selectedTraces.length > 0 &&
              this.objectInstance_.selectedTraces[0] == keys[k]) {
            // A trace selected in the analysis view is bright yellow.
            ctx.fillStyle = 'rgb(239, 248, 206)';
          } else {
            // Selected snapshots get a lighter color.
            var colorId = snapshot.selected ?
                snapshot.objectInstance.colorId + highlightIdBoost :
                snapshot.objectInstance.colorId;
            ctx.fillStyle = palette[colorId + k];
          }

          var barHeight = height * trace.currentBytes / maxBytes;
          ctx.fillRect(leftView, currentY - barHeight,
                       Math.max(rightView - leftView, 1), barHeight);
          currentY -= barHeight;
        }
      }
      ctx.lineWidth = 1;
    },

    /**
     * Used to hit-test clicks in the graph.
     */
    addIntersectingItemsInRangeToSelectionInWorldSpace: function(
        loWX, hiWX, viewPixWidthWorld, selection) {
      var that = this;
      function onSnapshotHit(snapshot) {
        selection.addObjectSnapshot(that, snapshot);
      }
      base.iterateOverIntersectingIntervals(
          this.objectInstance_.snapshots,
          function(x) { return x.ts; },
          function(x) { return 5000; },
          loWX, hiWX,
          onSnapshotHit);
    },

    /**
     * Add the item to the left or right of the provided hit, if any, to the
     * selection.
     * @param {slice} The current slice.
     * @param {Number} offset Number of slices away from the hit to look.
     * @param {Selection} selection The selection to add a hit to,
     * if found.
     * @return {boolean} Whether a hit was found.
     * @private
     */
    addItemNearToProvidedHitToSelection: function(hit, offset, selection) {
      if (hit instanceof tracing.SelectionObjectSnapshotHit) {
        var objectSnapshots = this.objectInstance_.snapshots;
        var index = objectSnapshots.indexOf(hit.objectSnapshot);
        var newIndex = index + offset;
        if (newIndex >= 0 && newIndex < objectSnapshots.length) {
          selection.addObjectSnapshot(this, objectSnapshots[newIndex]);
          return true;
        }
      } else {
        throw new Error('Unrecognized hit');
      }
      return false;
    },

    addAllObjectsMatchingFilterToSelection: function(filter, selection) {
    }
  };

  tracing.tracks.ObjectInstanceTrack.register(
      'memory::Heap', HeapInstanceTrack);

  return {
    HeapInstanceTrack: HeapInstanceTrack
  };
});
<|endoftext|>


<commit_before>(function(){

  var request = require('request');

  const API_PATH = '/api/v1/';
  const HOSTNAME = process.env.DATA_SERVICE_HOSTNAME;
  const URL = HOSTNAME + API_PATH;

  module.exports.giveThanks = function(giver,receivers,comment,callback){
    var aaay = {
      behalf: user,
      to: receivers,
      points: 1,
      public: true,
      comment: comment,
      tags: []
    };
    console.log('Going to send',JSON.stringify(aaay));
    request({
      url: URL,
      method: 'POST',
      json: true,
      body: aaay
    },
    function(error, response, body){
      callback(err, response);
    });
  }

})();
<commit_msg>Putting in basics of communication with rest service<commit_after>(function(){

  var request = require('request');

  const API_PATH = '/api/v1/';
  const HOSTNAME = process.env.DATA_SERVICE_HOSTNAME;
  const URL = HOSTNAME + API_PATH;

  module.exports.giveThanks = function(giver,receivers,comment,callback){
    var aaay = {
      behalf: giver,
      to: receivers,
      points: 1,
      public: true,
      comment: comment,
      tags: []
    };
    console.log('Going to send',JSON.stringify(aaay));
    request({
      url: URL,
      method: 'POST',
      json: true,
      body: aaay
    },
    function(error, response, body){
      callback(err, response);
    });
  }

})();
<|endoftext|>


<commit_before>/*
  FlagstoneJS v3.0.0
  (c) 2015-2017 Depth Development. http://depthdev.com
  License: MIT
*/

(function(window, document) {

  'use strict';

  window.flagstone = function(devObj) {

    function Flagstone(dO) {

      const instanceIndex = window.flagstone.index;

      const o = dO ? dO.nodeName ? {elem:dO} : dO : {elem:document.getElementsByClassName('flagstone')[0]};
      // FLAGSTONE (CONTAINER)
      const bed = o.elem;
      let bedPadding = o.margin || o.margin === 0 ? o.margin : o.bedPadding || o.bedPadding === 0 ? o.bedPadding : 10;
      let bedWidth = 0;
      // MIN WIDTH
      let minWidth = o.minWidth || 280;
      // COLUMNS
      let maxColumns = o.maxColumns || 5;
      let calcColumns = 0;
      let columns = 0;
      // STONES
      let stones = [];
      let stonesMargin = o.margin || o.margin === 0 ? o.margin : o.stonesMargin || o.stonesMargin === 0 ? o.stonesMargin : 10;
      let stoneWidth = (bedWidth / columns) - ((stonesMargin * (columns + 1)) / columns);
      let stoneHeights = [];
      // DIRECTION
      const direction = o.direction ? o.direction.toLowerCase() : 'left';
      // RANDOM POSITIONS
      const random = o.random;
      // RANDOM SPACE FREQUENCY
      const spaceFrequency = o.spaceFrequency || 0.4;
      // RANDOM SPACE GENERATOR
      function spaceGenerator() {
        let i = 0;
        const l = stones.length;
        for (;i<l;i++) {
          if (Math.random() < spaceFrequency) {
            stones.splice(i, 0, false); // Inject an element with the boolean "false"
          }
        }
      }
      // RANDOM SPACE
      const space = o.space;
      // ANIMATION
      const animationDuration = o.animationDuration || 0;
      const animationDurationSeconds = o.animationDuration ? o.animationDuration / 1000 : 0;
      const animationTimingFunction = o.animationTimingFunction || 'linear';
      // RESIZE/RESET DELAY
      const resizeDelay = o.resizeDelay || o.resizeDelay === 0 ? o.resizeDelay : 250;
      // SQUARE
      let square = o.square;
      // HIDE (for Developers as well when then are injecting new content onto their page, so they can hide the stones before they get a change to re-calculate);
      function hide() {
        bed.classList.add('flagstone-' + instanceIndex + '-bed-hidden');
      }
      // IMAGES LOADED QUERY
      const imagesLoadedQueryDuration = o.imagesLoadedQueryDuration || 2500;
      const imagesLoadedQueryFrequency = o.imagesLoadedQueryFrequency || 100;
      // DRAG AND DROP
      let dragAndDrop = o.dragAndDrop;
      // EVENT RESET DELAY
      const eventResetDelay = o.eventResetDelay || 0;
      // CUSTOM
      let callback = o.callback || function() { return; };
      // RESET DELAY
      let resetDelay = null;

      // DRAG & DROP
      const dd = {
        dragStone: null,
        targetStone: null,
        targetStoneMouseXPercent: 0,
        dragStart() {
          dd.dragStone = this;
          dd.dragStone.classList.add('flagstone-drag');
        },
        dragOver(e) {
          e.preventDefault();
          e.stopPropagation();
          e.dataTransfer.dropEffect = 'move';
          if (this !== dd.dragStone && this.hasAttribute('draggable')) {
            dd.targetStone = this;
            dd.targetStone.classList.add('flagstone-dragover');
            dd.targetStoneMouseXPercent = e.offsetX / this.offsetWidth;
            if (dd.targetStoneMouseXPercent < 0.5) {
              dd.targetStone.classList.remove('flagstone-right');
              dd.targetStone.classList.add('flagstone-left');
            } else {
              dd.targetStone.classList.remove('flagstone-left');
              dd.targetStone.classList.add('flagstone-right');
            }
            this.classList.remove('flagstone-dragover');
          } else if (this === bed) {
            this.classList.add('flagstone-dragover');
          }
        },
        dragEnd() {
          dd.dragStone.classList.remove('flagstone-drag');
        },
        dragLeave() {
          if (dd.targetStone) {
            bed.classList.remove('flagstone-dragover');
            dd.targetStone.classList.remove('flagstone-dragover');
            dd.targetStone.classList.remove('flagstone-left');
            dd.targetStone.classList.remove('flagstone-right');
          }
        },
        drop(e) {
          e.stopPropagation();
          if (dd.dragStone !== this && (this.hasAttribute('draggable') || this === bed)) {
            dd.targetStone = this;
            if (dd.targetStone === bed) {
              dd.targetStone.appendChild(dd.dragStone);
            } else {
              if (dd.targetStoneMouseXPercent < 0.5) {
                dd.targetStone.parentElement.insertBefore(dd.dragStone, dd.targetStone);
              } else {
                dd.targetStone.parentElement.insertBefore(dd.dragStone, dd.targetStone.nextElementSibling);
              }
            }
            dd.targetStone.classList.remove('flagstone-dragover');
            dd.targetStone.classList.remove('flagstone-left');
            dd.targetStone.classList.remove('flagstone-right');
            dd.dragStone.classList.remove('flagstone-drag');
          }
          return false;
        }
      };

      // RUN
      function run() {
        const columnHeights = [columns];
        let i = 0;
        const l = stoneHeights.length;
        for (;i<l;i++) {
          if (i < columns) {
            // First "row"
            if (stones[i]) {
              const width = stones[i].style.width.toString().replace(/(\d+).+/, '$1');

              stones[i].style.width = width + 'px';
              stones[i].style.top = bedPadding + 'px';
              stones[i].style[direction] = (stoneWidth * i + (i ? stonesMargin * i + bedPadding : bedPadding)) + 'px';
              stones[i].style.height = square ? width + 'px' : 'auto';

              columnHeights[i] = stoneHeights[i] + bedPadding;
              callback(stones[i], i);
            } else {
              if (columns > 1) {
                columnHeights[i] = stoneWidth + bedPadding;
              }
            }
          } else {
            // Every other "row"
            const smallestColumnHeight = Math.min.apply(null, columnHeights);
            const smallestColumn = columnHeights.indexOf(smallestColumnHeight);
            if (stones[i]) {
              const width = stones[i].style.width.toString().replace(/(\d+).+/, '$1');

              stones[i].style.width = width + 'px';
              stones[i].style.top = (smallestColumnHeight + stonesMargin) + 'px';
              stones[i].style[direction] = (stoneWidth * smallestColumn + (smallestColumn ? stonesMargin * smallestColumn + bedPadding : bedPadding)) + 'px';
              stones[i].style.height = square ? width + 'px' : 'auto';

              columnHeights[smallestColumn] += stoneHeights[i] + stonesMargin;
              callback(stones[i], i);
            } else {
              if (columns > 1) {
                columnHeights[smallestColumn] += stoneWidth + stonesMargin;
              }
            }
          }
          bed.style.height = (Math.max.apply(null, columnHeights) || stoneHeights[0] + bedPadding) + bedPadding + 'px';
        }
        window.setTimeout(() => {
          bed.classList.remove('flagstone-' + instanceIndex + '-bed-hidden');
        });
      } // end run()

      // RESIZE AND RESET
      function reset(pass) {
        if (!stones.length) {
          return;
        }
        // Set flagstone
        bedWidth = bed.getBoundingClientRect().width;
        if (bedWidth < minWidth + (bedPadding ? bedPadding * 2 : 0)) {
          bedWidth = minWidth;
        }
        // Set widths
        calcColumns = Math.floor(bedWidth / minWidth);
        columns = calcColumns > maxColumns ? maxColumns : calcColumns;
        stoneWidth = (bedWidth / columns) - ((stonesMargin * (columns - 1) + (bedPadding * 2)) / columns);
        // Set heights
        stoneHeights = [];
        let i = 0;
        const l = stones.length;
        for (;i<l;i++) {
          if (stones[i]) {
            stones[i].style.width = stoneWidth + 'px';
          }
          stoneHeights.push(square || !stones[i] ? stoneWidth : stones[i].offsetHeight);
        }
        // Repeats once to resolve the possible appearence of a window scrollbar, thus affecting the width calculations
        if (bedWidth === bed.getBoundingClientRect().width || pass) {
          run();
        } else {
          reset(true); // Run only one more time if width's don't match.
        }
      }

      // RESET AFTER IMAGES LOAD
      function resetAfterImagesLoad() {
        const dateNow = Date.now();
        const images = bed.getElementsByTagName('img');
        if (images.length) {
          const query = window.setInterval(() => {
            const imageHeights = [];
            let i = 0;
            const l = images.length;
            for (;i<l;i++) {
              imageHeights[i] = images[i].naturalHeight;
            }
            if (imageHeights.indexOf(0) === -1 || dateNow + imagesLoadedQueryDuration < Date.now()) {
              window.clearInterval(query);
              window.setTimeout(() => {
                reset(true);
              });
            }
          }, imagesLoadedQueryFrequency);
        }
      }

      // EVENT STONE REMOVE
      function eventStoneRemove(e) {
        if (e.type === 'keydown') {
          if (e.keyCode !== 13 && e.keyCode !== 32) {
            return;
          }
        }
        let elem = e.target;
        const className = 'flagstone-' + instanceIndex + '-bed__stone';
        while (elem && !elem.classList.contains(className)) {
          elem = elem.parentElement;
        }
        if (elem && elem.classList.contains(className)) {
          bed.removeChild(elem);
        }
      }

      // EVENT RESET
      function eventReset(e) {
        if (e.type === 'keydown') {
          if (e.keyCode !== 13 && e.keyCode !== 32) {
            return;
          }
        }
        setTimeout(reset, eventResetDelay);
      }

      // DYNAMIC CONTENT RESET / HARD RESET
      function resetHard() {
        hide();

        // Get stones
        stones = Array.prototype.slice.call(bed.children); // Array conversion for random/space functions
        let i = 0;
        let l = stones.length;
        // Set stone classes
        for (;i<l;i++) {
          stones[i].classList.add('flagstone-' + instanceIndex + '-bed__stone');
        }

        // Remove drag and drop listeners always, to support optional toggling of drag and drop
        i = 0;
        for (;i<l;i++) {
          stones[i].setAttribute('draggable','false'); // "Uncaught RangeError: Maximum call stack size exceeded." if removeAttribute is used!?!

          stones[i].removeEventListener('dragstart', dd.dragStart);
          stones[i].removeEventListener('dragover', dd.dragOver);
          stones[i].removeEventListener('dragleave', dd.dragLeave);
          stones[i].removeEventListener('dragend', dd.dragEnd);
          stones[i].removeEventListener('drop', dd.drop);

          bed.removeEventListener('dragover', dd.dragOver);
          bed.removeEventListener('drop', dd.drop);
        }

        // Bind drag and drop listeners
        if (dragAndDrop) {
          i = 0;
          for (;i<l;i++) {
            stones[i].setAttribute('draggable', 'true');

            stones[i].addEventListener('dragstart', dd.dragStart);
            stones[i].addEventListener('dragover', dd.dragOver);
            stones[i].addEventListener('dragleave', dd.dragLeave);
            stones[i].addEventListener('dragend', dd.dragEnd);
            stones[i].addEventListener('drop', dd.drop);

            bed.addEventListener('dragover', dd.dragOver);
            bed.addEventListener('drop', dd.drop);
          }
        }

        // Random/space setup
        if (random || space) {
          if (random) {
            stones.sort(() => 0.5 - Math.random());
          }
          if (space) {
            spaceGenerator();
          }
        }

        // Bind remove listeners for dev provided classed elements
        let elems = bed.getElementsByClassName('flagstone-remove');
        i = 0;
        l = elems.length;
        for (;i<l;i++) {
          elems[i].removeEventListener('click', eventStoneRemove);
          elems[i].addEventListener('click', eventStoneRemove);
          elems[i].removeEventListener('keydown', eventStoneRemove);
          elems[i].addEventListener('keydown', eventStoneRemove);
        }

        // Bind reset listeners for dev provided classed elements
        elems = bed.getElementsByClassName('flagstone-reset');
        i = 0;
        l = elems.length;
        for (;i<l;i++) {
          elems[i].removeEventListener('click', eventReset);
          elems[i].addEventListener('click', eventReset);
          elems[i].removeEventListener('keydown', eventReset);
          elems[i].addEventListener('keydown', eventReset);
        }

        // Reset to get sizes and run
        reset();

        // Run image loading checker
        if (animationDuration) {
          window.setTimeout(resetAfterImagesLoad, animationDuration);
        }

        // Run reset after first animation completes in case the scrollbar appears then.
        // This is not in the if (animationDuration) because technically an animation of zero could (possibly) have a stack delay since it's never set to "none" in the injected styles, but >= 0. But this needs to run regardless of that.
        window.setTimeout(() => {
          reset(true);
        }, animationDuration);
      }

      // RESET QUEUE
      function resetQueue() {
        window.clearTimeout(resetDelay);
        resetDelay = window.setTimeout(reset, resizeDelay);
      }

      // DESTROY
      function destroy() {
        window.removeEventListener('resize', resetQueue);
      }

      // ADJUST
      function adjust(adjustObj) {
        if (adjustObj.margin || adjustObj.margin === 0) {
          bedPadding = adjustObj.margin;
          stonesMargin = adjustObj.margin;
        } else {
          bedPadding = adjustObj.bedPadding || bedPadding;
          stonesMargin = adjustObj.stonesMargin || stonesMargin;
        }
        minWidth = adjustObj.minWidth || minWidth;
        maxColumns = adjustObj.maxColumns || maxColumns;
        square = adjustObj.square === true || adjustObj.square === false ? adjustObj.square : square;
        dragAndDrop = adjustObj.dragAndDrop === true || adjustObj.dragAndDrop === false ? adjustObj.dragAndDrop : dragAndDrop;
        callback = adjustObj.callback || callback;
        resetHard();
      }

      // INITIALIZE
      (function() {
        hide();

        // Set bed class
        bed.classList.add('flagstone-' + instanceIndex + '-bed');

        // Create styles
        if (!document.getElementById('flagstone-' + instanceIndex + '-styles')) {
          const bedStyles = '.flagstone-' + instanceIndex + '-bed{box-sizing:border-box;position:relative;min-width:' + (minWidth + (stonesMargin * 2)) + 'px;}'
          const bedAnimationStyles = '';// Turned off to not show overflowing stones while the container is still growing and a little easier on the CSS rendering engine '.flagstone-' + instanceIndex + '-bed{-webkit-transition:height ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-moz-transition:height ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-ms-transition:height ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-o-transition:height ' + animationDurationSeconds + 's ' + animationTimingFunction + ';transition:height ' + animationDurationSeconds + 's ' + animationTimingFunction + ';}';
          const bedHiddenStyles = '.flagstone-' + instanceIndex + '-bed.flagstone-' + instanceIndex + '-bed-hidden{visibility:hidden;}';
          const stoneStyles = '.flagstone-' + instanceIndex + '-bed__stone{box-sizing:border-box;position:absolute;top:0px;' + direction + ':0px;}';
          const stoneAnimationStyles = '.flagstone-' + instanceIndex + '-bed__stone{-webkit-transition:top ' + animationDurationSeconds + 's ' + animationTimingFunction + ',left ' + animationDurationSeconds + 's ' + animationTimingFunction + ',right ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-moz-transition:top ' + animationDurationSeconds + 's ' + animationTimingFunction + ',left ' + animationDurationSeconds + 's ' + animationTimingFunction + ',right ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-ms-transition:top ' + animationDurationSeconds + 's ' + animationTimingFunction + ',left ' + animationDurationSeconds + 's ' + animationTimingFunction + ',right ' + animationDurationSeconds + 's ' + animationTimingFunction + ';-o-transition:top ' + animationDurationSeconds + 's ' + animationTimingFunction + ',left ' + animationDurationSeconds + 's ' + animationTimingFunction + ',right ' + animationDurationSeconds + 's ' + animationTimingFunction + ';transition:top ' + animationDurationSeconds + 's ' + animationTimingFunction + ',left ' + animationDurationSeconds + 's ' + animationTimingFunction + ',right ' + animationDurationSeconds + 's ' + animationTimingFunction + ';}';

          const styles = bedStyles + bedAnimationStyles + bedHiddenStyles + stoneStyles + stoneAnimationStyles;

          const style = document.createElement('style');
          style.type = 'text/css';
          style.id = 'flagstone-' + instanceIndex + '-styles';
          style.appendChild(document.createTextNode(styles));
          document.head.appendChild(style);
        }
        // Run reset to calculate and run FlagstoneJS!
        resetHard();
        // Resize listener
        destroy();
        window.addEventListener('resize', resetQueue);
        // Set bed DOM listener
        setTimeout(() => {
          bed.addEventListener('DOMSubtreeModified', resetHard);
        });

      })() // init

      // RETURN
      return {
        adjust,
        destroy,
        hide,
        reset: resetQueue,
        hardReset: resetHard
      }

    } // end Flagstone

    // Increment index for multiple instances
    window.flagstone.index++;

    // Return a new Flagstone instance
    return new Flagstone(devObj);

  }; // end FLAGSTONEJS

  // Set default index as property of a non-closure function.
  window.flagstone.index = -1;

})(window, document)<commit_msg>Delete flagstone-3.0.0.js<commit_after><|endoftext|>


<commit_before>// @flow
/* eslint-env browser */
import * as React from 'react';
import ReactDOM from 'react-dom';
import { View } from 'react-native';
import withTheme, { type Theme } from './core/withTheme';
import { findDOMNode } from 'slate-react';
import EditorMenuButtons from './EditorMenuButtons';
import EditorMenuLink from './EditorMenuLink';
import EditorMenuLinkPreview from './EditorMenuLinkPreview';

export type EditorMenuAction =
  | {| type: 'BOLD' |}
  | {| type: 'ITALIC' |}
  | {| type: 'HEADING-ONE' |}
  | {| type: 'HEADING-TWO' |}
  | {| type: 'BLOCKQUOTE' |}
  // It's must to use passed change, if any. Slate requires it in onKeyDown.
  | {| type: 'LINK', href: ?string, change?: Object |}
  | {| type: 'FOCUS' |};

export type EditorMenuView = null | 'buttons' | 'link' | 'linkPreview';

type EditorMenuProps = {|
  value: Object,
  onAction: (action: EditorMenuAction) => void,
  theme: Theme,
|};

type EditorMenuState = {|
  left: number,
  top: number,
  view: EditorMenuView,
  hasLinks: boolean,
  linkNode: ?Object,
|};

class EditorMenu extends React.PureComponent<EditorMenuProps, EditorMenuState> {
  state = {
    left: 0,
    top: 0,
    view: null,
    hasLinks: false,
    linkNode: null,
  };

  componentDidMount() {
    this.el = window.document.createElement('div');
    this.modalRoot = window.document.getElementById('__next');
    if (this.modalRoot && this.el) this.modalRoot.appendChild(this.el);
    this.maybeUpdateLeftTopState();
  }

  componentDidUpdate(prevProps) {
    // https://reactjs.org/docs/react-component.html#componentdidmount
    // setState in componentDidUpdate is valid for tooltips, but we have to wrap
    // it in a condition.
    // Without PureComponent, it would cause a loop. With PureComponent, it
    // would cause double measuring of selection rect.
    // We can't use ref with setNativeProps, because:
    // 1) if this.el is set in componentDidMount, we can't set position because
    //    ref is not available yet.
    // 2) if this.el is set in constructor, server and client HTML would be
    //    different.
    // Therefore, this is the only right approach.
    if (this.props.value !== prevProps.value) {
      this.maybeUpdateLeftTopState();
    }
  }

  componentWillUnmount() {
    if (this.modalRoot && this.el) this.modalRoot.removeChild(this.el);
  }

  static getDerivedStateFromProps(
    props: EditorMenuProps,
    state: EditorMenuState,
  ): $Shape<EditorMenuState> {
    const ignoreViewWithFocus = state.view === 'link';
    if (ignoreViewWithFocus) return null;
    const { value } = props;
    const hasLinks = value.inlines.some(inline => inline.type === 'link');
    const linkNode = value.inlines.find(inline => inline.type === 'link');
    const newState = { hasLinks, linkNode };
    if (!value.isBlurred) {
      if (value.selection.isCollapsed) {
        const view = hasLinks ? 'linkPreview' : null;
        return { ...newState, view };
      }
      if (!value.isEmpty) {
        return { ...newState, view: 'buttons' };
      }
    }
    return { ...newState, view: null };
  }

  handleActionsSelectView = view => {
    this.setState({ view });
  };

  handleEditorMenuLinkClose = focusEditor => {
    this.setState({ view: 'buttons' }, () => {
      if (focusEditor === true) this.props.onAction({ type: 'FOCUS' });
    });
  };

  handleEditorMenuLinkSubmit = href => {
    this.props.onAction({ type: 'LINK', href });
  };

  handleKeyModK(change: Object) {
    const { value } = this.props;
    if (value.selection.isCollapsed) {
      const { linkNode } = this.state;
      if (!linkNode) return;
      const href = linkNode.data.get('href');
      // TODO: Use router push for web links.
      window.open(href);
      return;
    }
    if (value.isEmpty) return;
    if (this.state.hasLinks) {
      this.props.onAction({ type: 'LINK', href: null, change });
    } else {
      this.setState({ view: 'link' });
    }
  }

  modalRoot: ?HTMLDivElement;
  el: ?HTMLDivElement;

  maybeUpdateLeftTopState() {
    switch (this.state.view) {
      case 'buttons': {
        const rect = window
          .getSelection()
          .getRangeAt(0)
          .getBoundingClientRect();
        this.setState({
          left: rect.left,
          top: window.pageYOffset + rect.bottom,
        });
        break;
      }
      case 'link': {
        break;
      }
      case 'linkPreview': {
        const { linkNode } = this.state;
        if (!linkNode) return;
        // eslint-disable-next-line react/no-find-dom-node
        const rect = findDOMNode(linkNode).getBoundingClientRect();
        this.setState({
          left: rect.left,
          top: window.pageYOffset + rect.bottom,
        });
        break;
      }
      case null:
        break;
      default:
        // eslint-disable-next-line no-unused-expressions
        (this.state.view: empty);
    }
  }

  renderView() {
    const { value, onAction } = this.props;
    switch (this.state.view) {
      case 'buttons':
        return (
          <EditorMenuButtons
            value={value}
            onAction={onAction}
            onSelectView={this.handleActionsSelectView}
            hasLinks={this.state.hasLinks}
          />
        );
      case 'link':
        return (
          <EditorMenuLink
            onClose={this.handleEditorMenuLinkClose}
            onSubmit={this.handleEditorMenuLinkSubmit}
          />
        );
      case 'linkPreview': {
        const { linkNode } = this.state;
        if (!linkNode) return;
        const href = linkNode.data.get('href');
        return <EditorMenuLinkPreview href={href} />;
      }
      case null:
        return null;
      default:
        // eslint-disable-next-line no-unused-expressions
        (this.state.view: empty);
    }
  }

  render() {
    const { el } = this;
    if (el == null) return null;
    const view = this.renderView();
    if (view == null) return null;
    const { left, top } = this.state;
    return ReactDOM.createPortal(
      <View style={[this.props.theme.styles.editorMenu, { left, top }]}>
        {view}
      </View>,
      el,
    );
  }
}

// This is workaround for https://github.com/este/este/issues/1571
export type EditorMenuType = typeof EditorMenu;

export default withTheme(EditorMenu);
<commit_msg>Update Slate deprecated API<commit_after>// @flow
/* eslint-env browser */
import * as React from 'react';
import ReactDOM from 'react-dom';
import { View } from 'react-native';
import withTheme, { type Theme } from './core/withTheme';
import { findDOMNode } from 'slate-react';
import EditorMenuButtons from './EditorMenuButtons';
import EditorMenuLink from './EditorMenuLink';
import EditorMenuLinkPreview from './EditorMenuLinkPreview';

export type EditorMenuAction =
  | {| type: 'BOLD' |}
  | {| type: 'ITALIC' |}
  | {| type: 'HEADING-ONE' |}
  | {| type: 'HEADING-TWO' |}
  | {| type: 'BLOCKQUOTE' |}
  // It's must to use passed change, if any. Slate requires it in onKeyDown.
  | {| type: 'LINK', href: ?string, change?: Object |}
  | {| type: 'FOCUS' |};

export type EditorMenuView = null | 'buttons' | 'link' | 'linkPreview';

type EditorMenuProps = {|
  value: Object,
  onAction: (action: EditorMenuAction) => void,
  theme: Theme,
|};

type EditorMenuState = {|
  left: number,
  top: number,
  view: EditorMenuView,
  hasLinks: boolean,
  linkNode: ?Object,
|};

class EditorMenu extends React.PureComponent<EditorMenuProps, EditorMenuState> {
  state = {
    left: 0,
    top: 0,
    view: null,
    hasLinks: false,
    linkNode: null,
  };

  componentDidMount() {
    this.el = window.document.createElement('div');
    this.modalRoot = window.document.getElementById('__next');
    if (this.modalRoot && this.el) this.modalRoot.appendChild(this.el);
    this.maybeUpdateLeftTopState();
  }

  componentDidUpdate(prevProps) {
    // https://reactjs.org/docs/react-component.html#componentdidmount
    // setState in componentDidUpdate is valid for tooltips, but we have to wrap
    // it in a condition.
    // Without PureComponent, it would cause a loop. With PureComponent, it
    // would cause double measuring of selection rect.
    // We can't use ref with setNativeProps, because:
    // 1) if this.el is set in componentDidMount, we can't set position because
    //    ref is not available yet.
    // 2) if this.el is set in constructor, server and client HTML would be
    //    different.
    // Therefore, this is the only right approach.
    if (this.props.value !== prevProps.value) {
      this.maybeUpdateLeftTopState();
    }
  }

  componentWillUnmount() {
    if (this.modalRoot && this.el) this.modalRoot.removeChild(this.el);
  }

  static getDerivedStateFromProps(
    props: EditorMenuProps,
    state: EditorMenuState,
  ): $Shape<EditorMenuState> {
    const ignoreViewWithFocus = state.view === 'link';
    if (ignoreViewWithFocus) return null;
    const { value } = props;
    const { fragment, selection } = value;
    const hasLinks = value.inlines.some(inline => inline.type === 'link');
    const linkNode = value.inlines.find(inline => inline.type === 'link');
    const newState = { hasLinks, linkNode };
    if (selection.isFocused) {
      if (selection.isCollapsed) {
        const view = hasLinks ? 'linkPreview' : null;
        return { ...newState, view };
      }
      if (fragment.text !== '') {
        return { ...newState, view: 'buttons' };
      }
    }
    return { ...newState, view: null };
  }

  handleActionsSelectView = view => {
    this.setState({ view });
  };

  handleEditorMenuLinkClose = focusEditor => {
    this.setState({ view: 'buttons' }, () => {
      if (focusEditor === true) this.props.onAction({ type: 'FOCUS' });
    });
  };

  handleEditorMenuLinkSubmit = href => {
    this.props.onAction({ type: 'LINK', href });
  };

  handleKeyModK(change: Object) {
    const { value } = this.props;
    const { fragment, selection } = value;
    if (selection.isCollapsed) {
      const { linkNode } = this.state;
      if (!linkNode) return;
      const href = linkNode.data.get('href');
      // TODO: Use router push for web links.
      window.open(href);
      return;
    }
    if (fragment.text === '') return;
    if (this.state.hasLinks) {
      this.props.onAction({ type: 'LINK', href: null, change });
    } else {
      this.setState({ view: 'link' });
    }
  }

  modalRoot: ?HTMLDivElement;
  el: ?HTMLDivElement;

  maybeUpdateLeftTopState() {
    switch (this.state.view) {
      case 'buttons': {
        const rect = window
          .getSelection()
          .getRangeAt(0)
          .getBoundingClientRect();
        this.setState({
          left: rect.left,
          top: window.pageYOffset + rect.bottom,
        });
        break;
      }
      case 'link': {
        break;
      }
      case 'linkPreview': {
        const { linkNode } = this.state;
        if (!linkNode) return;
        // eslint-disable-next-line react/no-find-dom-node
        const rect = findDOMNode(linkNode).getBoundingClientRect();
        this.setState({
          left: rect.left,
          top: window.pageYOffset + rect.bottom,
        });
        break;
      }
      case null:
        break;
      default:
        // eslint-disable-next-line no-unused-expressions
        (this.state.view: empty);
    }
  }

  renderView() {
    const { value, onAction } = this.props;
    switch (this.state.view) {
      case 'buttons':
        return (
          <EditorMenuButtons
            value={value}
            onAction={onAction}
            onSelectView={this.handleActionsSelectView}
            hasLinks={this.state.hasLinks}
          />
        );
      case 'link':
        return (
          <EditorMenuLink
            onClose={this.handleEditorMenuLinkClose}
            onSubmit={this.handleEditorMenuLinkSubmit}
          />
        );
      case 'linkPreview': {
        const { linkNode } = this.state;
        if (!linkNode) return;
        const href = linkNode.data.get('href');
        return <EditorMenuLinkPreview href={href} />;
      }
      case null:
        return null;
      default:
        // eslint-disable-next-line no-unused-expressions
        (this.state.view: empty);
    }
  }

  render() {
    const { el } = this;
    if (el == null) return null;
    const view = this.renderView();
    if (view == null) return null;
    const { left, top } = this.state;
    return ReactDOM.createPortal(
      <View style={[this.props.theme.styles.editorMenu, { left, top }]}>
        {view}
      </View>,
      el,
    );
  }
}

// This is workaround for https://github.com/este/este/issues/1571
export type EditorMenuType = typeof EditorMenu;

export default withTheme(EditorMenu);
<|endoftext|>