<commit_before>Termite.prototype = new Agent();
Termite.prototype.constructor = Termite;

function Termite() {
	Agent.call(this);
	this.typeId = "termite";
	this.boundingRadius = 3;
	this.perceptionRadius = 100;

	this.hasWood = false;

	this.collideTypes = ["wood_heap", "wall"];
	this.contactTypes = ["wood_heap"];

	this.heapInfos = [];
	this.wallInfos = [];
	this.wall = null;
	this.directionDelay = 0;
	this.speed = 500;
	this.updateRandomDirection();
}

Termite.prototype.updateRandomDirection = function(dt) {
	this.direction = new Vect(Math.random() * 2 - 1, Math.random() * 2 - 1);
	this.direction.normalize(1);
};
Termite.prototype.setTarget = function(x, y) {
	this.direction = new Vect(x - this.x, y - this.y);
	this.direction.normalize(1);
};

Termite.prototype.update = function(dt) {
	this.directionDelay -= dt;
	if(this.directionDelay <= 0) {
		var targetHeap = null;
		var searchTargetHeap = (Math.random() < 0.9)
		if(searchTargetHeap) {
			for(identifier in this.heapInfos) {
				var heapInfo = this.heapInfos[identifier];
				if(heapInfo.count > 0) {
					if(this.hasWood) {
						if(targetHeap == null || heapInfo.count > targetHeap.count) {
							targetHeap  = heapInfo;
						}
					} else if(!this.hasWood) {
						if(targetHeap == null || heapInfo.count < targetHeap.count) {
							targetHeap  = heapInfo;
						}
					}
				}
			}
		}
		if(targetHeap) {
			if(this.wall != null){
				var ve = this.closestWallPoint(this.wall);
				this.setTarget(ve.x, ve.y);
				this.wall = null;
			}else
				this.setTarget(targetHeap.x, targetHeap.y);
		} else {
			this.updateRandomDirection();
		}
		this.speed = 100 + Math.random() * 200;
		this.directionDelay = 100 + Math.random() * 900;
	}

	var x = this.x + this.direction.x * this.speed * dt / 1000;
	var y = this.y + this.direction.y * this.speed * dt / 1000;
	this.moveTo(x,y);
};

Termite.prototype.closestWallPoint = function(id) {
	var x = y = 10000;
	var number = 0;
	for(identifier in this.wallInfos) {
		if(id == identifier){
			var wall = this.wallInfos[identifier];
			for(var i = 0; i < wall.length; i++){
				if(Math.abs(this.x - wall[i].x) < x ){
					x = wall[i].x;
					number = i;
				}
				if(Math.abs(this.y - wall[i].y) < y ){
					y = wall[i].y
				}
			}
		}
	}
	return {"x" : x, "y" : y};
}

Termite.prototype.draw = function(context) {
	context.fillStyle = this.hasWood ? "#f00" : "#000";
	context.strokeStyle = "#000";
	context.beginPath();
	context.arc(this.x,this.y,this.boundingRadius,0,2*Math.PI);
	context.fill();
	context.stroke();
};

Termite.prototype.processCollision = function(collidedAgent) {
	if(collidedAgent){
		if(collidedAgent.typeId == "wall") {
			this.directionDelay = 0;
			this.wall = collidedAgent.identifier;
		} else if(collidedAgent.typeId == "wood_heap") {
			if(this.hasWood) {
				collidedAgent.addWood();
				this.hasWood = false;
			} else {
				collidedAgent.takeWood();
				this.hasWood = true;
			}
		}
	}
};

Termite.prototype.processPerception = function(perceivedAgent) {
	if(perceivedAgent.typeId == "wood_heap") {
		this.heapInfos[perceivedAgent.identifier] = {
			"x"		: perceivedAgent.x,
			"y"		: perceivedAgent.y,
			"count"	: perceivedAgent.woodCount,
			"date"	: Date.now()
		};
	}else if(perceivedAgent.typeId == "termite") {
		for(identifier in perceivedAgent.heapInfos) {
			var heapInfo = perceivedAgent.heapInfos[identifier];
			if(this.heapInfos[identifier] == null) {
				this.heapInfos[identifier] = heapInfo;
			}else if(heapInfo.count <= 0) {
				this.heapInfos[identifier] = heapInfo;
			} else if(this.heapInfos[identifier].date < heapInfo.date)
				this.heapInfos[identifier] = heapInfo;

		}
		for(identifier in perceivedAgent.wallInfos) {
			var wallInfo = perceivedAgent.wallInfos[identifier];
			if(this.wallInfos[identifier] == null) {
				this.wallInfos[identifier] = wallInfo;
			}
		}
	}else if(perceivedAgent.typeId == "wall") {
		this.wallInfos[perceivedAgent.identifier] = [
			{
				"x" : perceivedAgent.x - perceivedAgent.boundingWidth / 2,
				"y" : perceivedAgent.y - perceivedAgent.boundingHeight / 2
			},
			{
				"x" : perceivedAgent.x + perceivedAgent.boundingWidth / 2,
				"y" : perceivedAgent.y - perceivedAgent.boundingHeight / 2
			},
			{
				"x" : perceivedAgent.x + perceivedAgent.boundingWidth / 2,
				"y" : perceivedAgent.y + perceivedAgent.boundingHeight / 2
			},
			{
				"x" : perceivedAgent.x - perceivedAgent.boundingWidth / 2,
				"y" : perceivedAgent.y + perceivedAgent.boundingHeight / 2
			}
		];
	}
};
<commit_msg>On est presque au bout, à améliorer<commit_after>Termite.prototype = new Agent();
Termite.prototype.constructor = Termite;

function Termite() {
	Agent.call(this);
	this.typeId = "termite";
	this.boundingRadius = 3;
	this.perceptionRadius = 100;

	this.hasWood = false;

	this.collideTypes = ["wood_heap", "wall"];
	this.contactTypes = ["wood_heap", "wall"];

	this.heapInfos = [];
	this.wallInfos = [];
	this.wall = null;
	this.directionDelay = 0;
	this.speed = 500;
	this.updateRandomDirection();
}

Termite.prototype.updateRandomDirection = function(dt) {
	this.direction = new Vect(Math.random() * 2 - 1, Math.random() * 2 - 1);
	this.direction.normalize(1);
};
Termite.prototype.setTarget = function(x, y) {
	this.direction = new Vect(x - this.x, y - this.y);
	this.direction.normalize(1);
};

Termite.prototype.update = function(dt) {
	this.directionDelay -= dt;
	if(this.directionDelay <= 0) {
		var targetHeap = null;
		var searchTargetHeap = (Math.random() < 0.9)
		if(searchTargetHeap) {
			for(identifier in this.heapInfos) {
				var heapInfo = this.heapInfos[identifier];
				if(heapInfo.count > 0) {
					if(this.hasWood) {
						if(targetHeap == null || heapInfo.count > targetHeap.count) {
							targetHeap  = heapInfo;
						}
					} else if(!this.hasWood) {
						if(targetHeap == null || heapInfo.count < targetHeap.count) {
							targetHeap  = heapInfo;
						}
					}
				}
			}
		}
		if(targetHeap) {
			if(this.wall != null){
				var ve = this.closestWallPoint(this.wall);
				this.setTarget(ve.x, ve.y);
				this.wall = null;
			}else
				this.setTarget(targetHeap.x, targetHeap.y);
		} else {
			this.updateRandomDirection();
		}
		this.speed = 100 + Math.random() * 200;
		this.directionDelay = 100 + Math.random() * 900;
	}

	var x = this.x + this.direction.x * this.speed * dt / 1000;
	var y = this.y + this.direction.y * this.speed * dt / 1000;
	this.moveTo(x,y);
};

Termite.prototype.closestWallPoint = function(id) {
	var x = y = 10000;
	for(identifier in this.wallInfos) {
		if(id == identifier){
			var wall = this.wallInfos[identifier];
			for(var i = 0; i < wall.length; i++){
				if(Math.abs(this.x - wall[i].x) < x && this.isInWorld(wall[i].x) ){
					x = wall[i].x;
				}
				if(Math.abs(this.y - wall[i].y) < y && this.isInWorld(wall[i].y)){
					y = wall[i].y
				}
			}
		}
	}
	return {"x" : x, "y" : y};
}

Termite.prototype.isInWorld = function(coord) {
	return coord < 600 && coord > 0;
}

Termite.prototype.draw = function(context) {
	context.fillStyle = this.hasWood ? "#f00" : "#000";
	context.strokeStyle = "#000";
	context.beginPath();
	context.arc(this.x,this.y,this.boundingRadius,0,2*Math.PI);
	context.fill();
	context.stroke();
};

Termite.prototype.processCollision = function(collidedAgent) {
	if(collidedAgent){
		if(collidedAgent.typeId == "wall") {
			this.directionDelay = 0;
			this.wall = collidedAgent.identifier;
		} else if(collidedAgent.typeId == "wood_heap") {
			if(this.hasWood) {
				collidedAgent.addWood();
				this.hasWood = false;
			} else {
				collidedAgent.takeWood();
				this.hasWood = true;
			}
		}
	}
};

Termite.prototype.processPerception = function(perceivedAgent) {
	if(perceivedAgent.typeId == "wood_heap") {
		this.heapInfos[perceivedAgent.identifier] = {
			"x"		: perceivedAgent.x,
			"y"		: perceivedAgent.y,
			"count"	: perceivedAgent.woodCount,
			"date"	: Date.now()
		};
	}else if(perceivedAgent.typeId == "termite") {
		for(identifier in perceivedAgent.heapInfos) {
			var heapInfo = perceivedAgent.heapInfos[identifier];
			if(this.heapInfos[identifier] == null) {
				this.heapInfos[identifier] = heapInfo;
			}else if(heapInfo.count <= 0) {
				this.heapInfos[identifier] = heapInfo;
			} else if(this.heapInfos[identifier].date < heapInfo.date)
				this.heapInfos[identifier] = heapInfo;

		}
		for(identifier in perceivedAgent.wallInfos) {
			var wallInfo = perceivedAgent.wallInfos[identifier];
			if(this.wallInfos[identifier] == null) {
				this.wallInfos[identifier] = wallInfo;
			}
		}
	}else if(perceivedAgent.typeId == "wall") {
		this.wallInfos[perceivedAgent.identifier] = [
			{
				"x" : perceivedAgent.x - perceivedAgent.boundingWidth / 2 - this.boundingRadius,
				"y" : perceivedAgent.y - perceivedAgent.boundingHeight / 2 - this.boundingRadius
			},
			{
				"x" : perceivedAgent.x + perceivedAgent.boundingWidth / 2 + this.boundingRadius,
				"y" : perceivedAgent.y - perceivedAgent.boundingHeight / 2 - this.boundingRadius
			},
			{
				"x" : perceivedAgent.x + perceivedAgent.boundingWidth / 2 + this.boundingRadius,
				"y" : perceivedAgent.y + perceivedAgent.boundingHeight / 2 + this.boundingRadius
			},
			{
				"x" : perceivedAgent.x - perceivedAgent.boundingWidth / 2 - this.boundingRadius,
				"y" : perceivedAgent.y + perceivedAgent.boundingHeight / 2 + this.boundingRadius
			}
		];
	}
};
<|endoftext|>


<commit_before>'use strict';

var $ = require('jquery');
var _ = require('underscore');

var NonOverlappingLayout = function(features, totalHeight) {
	var nonOverlappingLayout = this,
		rows = [],
		rowHeight = 0,
		padding = 1,
		minHeight = 15;

	nonOverlappingLayout.totalHeight = totalHeight;

	var Row = function() {
		var row = this;

		row.rowFeatures = [];

		row.containsOverlap = function(feature) {

			var overlapping = false;
			$.each(row.rowFeatures, function(i,d){
				if((Number(feature.begin) >= Number(d.begin) && Number(feature.begin) <= Number(d.end))
					|| (Number(feature.end) >= Number(d.begin)) && (Number(feature.end) <= Number(d.end))) {
					overlapping = true;
					return false;
				}
			});
			return overlapping;
		}

		row.addFeature = function(feature) {
			row.rowFeatures.push(feature);
		}
	}

	nonOverlappingLayout.calculate = function(){
		rowHeight = ((nonOverlappingLayout.totalHeight /rows.length < minHeight)? nonOverlappingLayout.totalHeight /rows.length : minHeight ) - 2 * padding;
	};

	nonOverlappingLayout.getYPos = function(feature) {
		var yPos,
			yOffset = (nonOverlappingLayout.totalHeight /rows.length > minHeight) ? (nonOverlappingLayout.totalHeight - (rows.length*minHeight))/2 : 0;
		_.each(rows, function(row, i) {
			_.each(row.rowFeatures, function(currFeature){
				if(currFeature === feature) {
					yPos = (i * (rowHeight + 2*padding)
						+ yOffset);
				}
			});
		});
		return yPos;
	}

	nonOverlappingLayout.getRows = function() {
		return rows;
	}

	nonOverlappingLayout.getFeatureHeight = function() {
		return rowHeight;
	}

	$.each(features, function(i, feature){
		var createNewRow = true;
		$.each(rows, function(i, row){
			if(!row.containsOverlap(feature)) {
				row.addFeature(feature);
				createNewRow = false;
				return false;
			}
		});
		if(createNewRow) {
			var row = new Row();
			row.addFeature(feature);
			rows.push(row);
		}
	});
}

module.exports = NonOverlappingLayout;<commit_msg>Add missing semi-colons<commit_after>'use strict';

var $ = require('jquery');
var _ = require('underscore');

var NonOverlappingLayout = function(features, totalHeight) {
	var nonOverlappingLayout = this,
		rows = [],
		rowHeight = 0,
		padding = 1,
		minHeight = 15;

	nonOverlappingLayout.totalHeight = totalHeight;

	var Row = function() {
		var row = this;

		row.rowFeatures = [];

		row.containsOverlap = function(feature) {
			var overlapping = false;
			$.each(row.rowFeatures, function(i,d){
				if((Number(feature.begin) >= Number(d.begin) && Number(feature.begin) <= Number(d.end))
					|| (Number(feature.end) >= Number(d.begin)) && (Number(feature.end) <= Number(d.end))) {
					overlapping = true;
					return false;
				}
			});
			return overlapping;
		};

		row.addFeature = function(feature) {
			row.rowFeatures.push(feature);
		};
	};

	nonOverlappingLayout.calculate = function(){
		rowHeight = ((nonOverlappingLayout.totalHeight /rows.length < minHeight)? nonOverlappingLayout.totalHeight /rows.length : minHeight ) - 2 * padding;
	};

	nonOverlappingLayout.getYPos = function(feature) {
		var yPos,
			yOffset = (nonOverlappingLayout.totalHeight /rows.length > minHeight) ? (nonOverlappingLayout.totalHeight - (rows.length*minHeight))/2 : 0;
		_.each(rows, function(row, i) {
			_.each(row.rowFeatures, function(currFeature){
				if(currFeature === feature) {
					yPos = (i * (rowHeight + 2*padding)
						+ yOffset);
				}
			});
		});
		return yPos;
	};

	nonOverlappingLayout.getRows = function() {
		return rows;
	};

	nonOverlappingLayout.getFeatureHeight = function() {
		return rowHeight;
	};

	$.each(features, function(i, feature){
		var createNewRow = true;
		$.each(rows, function(i, row){
			if(!row.containsOverlap(feature)) {
				row.addFeature(feature);
				createNewRow = false;
				return false;
			}
		});
		if(createNewRow) {
			var row = new Row();
			row.addFeature(feature);
			rows.push(row);
		}
	});
};

module.exports = NonOverlappingLayout;<|endoftext|>


<commit_before>"use strict";
/*jshint mocha: true*/
/*eslint-env mocha*/
/*global assert*/

describe("fs", function () {

    if (null === gpf.fs.host()) {
        return; // No host
    }

    describe("Data generator", function () {

        it("file.bin", function (done) {
            var fs = gpf.fs.host();
            fs.getInfo("test/data/file.bin", function (infoEvent) {
                if (infoEvent.type === gpf.events.EVENT_READY && infoEvent.get("info").type === gpf.fs.TYPE_FILE) {
                    done(); // Already exists
                    return;
                }
                // File does not exist, generates
                var count = 0,
                    wStream;
                function loop(event) {
                    assert(!event || gpf.events.EVENT_READY === event.type);
                    if (256 === count) {
                        fs.close(wStream, function () {});
                        done();
                    }
                    wStream.write([count++], loop);
                }
                // Current path is always root of gpf-js
                fs.writeAsBinaryStream("test/data/file.bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    wStream = event.get("stream");
                    loop();
                });
            });
        });

    });

    describe("gpf.fs.host", function () {

        var gpfI = gpf.interfaces,
            iFs;

        beforeEach(function () {
            iFs = gpf.fs.host();
        });

        it("gives access to a IFileStorage interface", function () {
            assert(null !== iFs);
            if (null !== iFs) {
                assert(gpfI.isImplementedBy(iFs, gpfI.IFileStorage));
            }
        });

        describe("getInfo", function () {

            function checkInfo(info) {
                assert(null !== info);
                assert("object" === typeof info);
                assert("number" === typeof info.type);
                assert("string" === typeof info.fileName);
                assert("string" === typeof info.filePath);
                assert("number" === typeof info.size);
                assert("object" === typeof info.createdDateTime);
                assert("object" === typeof info.modifiedDateTime);
            }

            it("tells if a file exists", function (done) {
                iFs.getInfo("src/fs.js", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    checkInfo(info);
                    assert(info.type === gpf.fs.TYPE_FILE);
                    assert(info.size > 0);
                    done();
                });
            });

            it("tells if a directory exists", function (done) {
                iFs.getInfo("src", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    checkInfo(info);
                    assert(info.type === gpf.fs.TYPE_DIRECTORY);
                    // size is not relevant
                    done();
                });
            });

            it("tells if a path does not exists", function (done) {
                iFs.getInfo("null", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    assert(null !== info);
                    assert("object" === typeof info);
                    assert(info.type === gpf.fs.TYPE_NOT_FOUND);
                    done();
                });
            });

        });

        function _close(stream) {
            iFs.close(stream, function () {}); // ignore
        }

        describe("readAsBinaryStream", function () {

            it("reads binary files", function (done) {
                iFs.readAsBinaryStream("test/data/file.bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var rStream = event.get("stream");
                    rStream.read(1, function (readEvent) {
                        assert(gpf.events.EVENT_DATA === readEvent.type);
                        var buffer = readEvent.get("buffer");
                        assert(1 === buffer.length);
                        assert(0 === buffer[0]);
                        _close(rStream);
                        done();
                    });
                });
            });

        });

        describe("writeAsBinaryStream", function () {

            it("writes binary files", function (done) {
                iFs.writeAsBinaryStream("tmp/test/fs_" + gpf.host() + ".bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var wStream = event.get("stream");
                    wStream.write([0, 34, 75, 0, 128, 255], function (writeEvent) {
                        assert(gpf.events.EVENT_READY === writeEvent.type);
                        _close(wStream);
                        done();
                    });
                });
            });

        });

        describe("explore", function () {

            it("fails on a file", function (done) {
                iFs.explore("src/fs.js", function (event) {
                    assert(gpf.events.EVENT_ERROR === event.type);
                    done();
                });
            });

            it("gets an IEnumerator on a folder", function (done) {
                iFs.explore("src", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var enumerator = event.get("enumerator");
                    assert(null !== enumerator);
                    assert(gpf.interfaces.isImplementedBy(enumerator, gpf.interfaces.IEnumerator));
                    done();
                });
            });

        });

    });

});
<commit_msg>Eslint fixes<commit_after>"use strict";
/*jshint mocha: true*/
/*eslint-env mocha*/
/*global assert*/

/*eslint-disable max-nested-callbacks*/

describe("fs", function () {

    if (null === gpf.fs.host()) {
        return; // No host
    }

    describe("Data generator", function () {

        it("file.bin", function (done) {
            var fs = gpf.fs.host();
            fs.getInfo("test/data/file.bin", function (infoEvent) {
                if (infoEvent.type === gpf.events.EVENT_READY && infoEvent.get("info").type === gpf.fs.TYPE_FILE) {
                    done(); // Already exists
                    return;
                }
                // File does not exist, generates
                var count = 0,
                    wStream;
                function loop (event) {
                    assert(!event || gpf.events.EVENT_READY === event.type);
                    if (256 === count) {
                        fs.close(wStream, function () {});
                        done();
                    }
                    wStream.write([count++], loop);
                }
                // Current path is always root of gpf-js
                fs.writeAsBinaryStream("test/data/file.bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    wStream = event.get("stream");
                    loop();
                });
            });
        });

    });

    describe("gpf.fs.host", function () {

        var gpfI = gpf.interfaces,
            iFs;

        beforeEach(function () {
            iFs = gpf.fs.host();
        });

        it("gives access to a IFileStorage interface", function () {
            assert(null !== iFs);
            if (null !== iFs) {
                assert(gpfI.isImplementedBy(iFs, gpfI.IFileStorage));
            }
        });

        describe("getInfo", function () {

            function checkInfo (info) {
                assert(null !== info);
                assert("object" === typeof info);
                assert("number" === typeof info.type);
                assert("string" === typeof info.fileName);
                assert("string" === typeof info.filePath);
                assert("number" === typeof info.size);
                assert("object" === typeof info.createdDateTime);
                assert("object" === typeof info.modifiedDateTime);
            }

            it("tells if a file exists", function (done) {
                iFs.getInfo("src/fs.js", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    checkInfo(info);
                    assert(info.type === gpf.fs.TYPE_FILE);
                    assert(info.size > 0);
                    done();
                });
            });

            it("tells if a directory exists", function (done) {
                iFs.getInfo("src", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    checkInfo(info);
                    assert(info.type === gpf.fs.TYPE_DIRECTORY);
                    // size is not relevant
                    done();
                });
            });

            it("tells if a path does not exists", function (done) {
                iFs.getInfo("null", function (event) {
                    assert(event.type === gpf.events.EVENT_READY);
                    var info = event.get("info");
                    assert(null !== info);
                    assert("object" === typeof info);
                    assert(info.type === gpf.fs.TYPE_NOT_FOUND);
                    done();
                });
            });

        });

        function _close (stream) {
            iFs.close(stream, function () {}); // ignore
        }

        describe("readAsBinaryStream", function () {

            it("reads binary files", function (done) {
                iFs.readAsBinaryStream("test/data/file.bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var rStream = event.get("stream");
                    rStream.read(1, function (readEvent) {
                        assert(gpf.events.EVENT_DATA === readEvent.type);
                        var buffer = readEvent.get("buffer");
                        assert(1 === buffer.length);
                        assert(0 === buffer[0]);
                        _close(rStream);
                        done();
                    });
                });
            });

        });

        describe("writeAsBinaryStream", function () {

            it("writes binary files", function (done) {
                iFs.writeAsBinaryStream("tmp/test/fs_" + gpf.host() + ".bin", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var wStream = event.get("stream");
                    wStream.write([0, 34, 75, 0, 128, 255], function (writeEvent) {
                        assert(gpf.events.EVENT_READY === writeEvent.type);
                        _close(wStream);
                        done();
                    });
                });
            });

        });

        describe("explore", function () {

            it("fails on a file", function (done) {
                iFs.explore("src/fs.js", function (event) {
                    assert(gpf.events.EVENT_ERROR === event.type);
                    done();
                });
            });

            it("gets an IEnumerator on a folder", function (done) {
                iFs.explore("src", function (event) {
                    assert(gpf.events.EVENT_READY === event.type);
                    var enumerator = event.get("enumerator");
                    assert(null !== enumerator);
                    assert(gpf.interfaces.isImplementedBy(enumerator, gpf.interfaces.IEnumerator));
                    done();
                });
            });

        });

    });

});
<|endoftext|>


<commit_before>/**
 * @file RemoteAutoComplete component
 * @author chao(chao.zhang@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Event from '../_vendors/Event';
import classNames from 'classnames';

import TextField from '../TextField/TextField';
import CircularLoading from '../CircularLoading/CircularLoading';
import Popup from '../Popup';

class RemoteAutoComplete extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value,
            focus: false,
            loading: props.loading
        };

        this.liHeight = 40;
        this.maxHeight = 401;
        this.inputHeight = 50;
        this.borderWidth = 1;

        this.onChange = ::this.onChange;
        this.onClick = ::this.onClick;
        this.getClassName = ::this.getClassName;
        this.onFocus = ::this.onFocus;

    }

    /**
     * 获取当前元素及父元素的类名
     */
    getClassName(element) {
        let className = element.className;
        let current = element.offsetParent;
        while (current !== null) {
            className += current.className;
            current = current.offsetParent;
        }
        return className;
    }

    /**
     * input变化时改变loading状态并触发onChange
     */
    onChange(text) {
        const {onChange} = this.props;

        this.setState({
            value: text
        }, () => {
            this.setState({
                loading: true
            }, () => {
                onChange && onChange(text, true);
            });
        });
    }

    /**
     * 获得焦点时触发onFocus
     */
    onFocus() {
        const {onFocus} = this.props;

        this.setState({
            focus: true
        }, () => {
            onFocus && onFocus();
        });
    }

    /**
     * 点击下拉选项时自动填充且不再auto complete
     */
    onClick(ev) {
        const {onBlur} = this.props;
        const className = this.getClassName(ev.target);

        if (className.indexOf('auto-complete-li') > -1) {
            const {onChange} = this.props;
            let oEvent = ev.srcElement ? ev.srcElement : ev.target;

            this.setState({
                focus: true
            }, () => {
                onChange && onChange(oEvent.innerText, false);
            });
        } else if (className.indexOf('text-field') > -1) {
            return false;
        } else {
            this.setState({
                focus: false
            }, () => {
                onBlur && onBlur(this.state.value);
            });
        }
    }

    /**
     * 接收新的props，如果input或loading有变化，则setState
     */
    componentWillReceiveProps(nextProps) {
        const {value, loading} = this.state;

        if (nextProps.value !== value || nextProps.loading !== loading) {
            this.setState({
                value: nextProps.value,
                loading: nextProps.loading
            });
        }
    }

    componentDidMount() {
        Event.addEvent(document, 'click', this.onClick);
        this.triggerEl = require('react-dom').findDOMNode(this.refs.trigger);
    }

    componentWillUnmount() {
        Event.removeEvent(document, 'click', this.onClick);
    }

    render() {

        const {data, className, style, placeholder} = this.props,
            {value, focus, loading} = this.state,
            {liHeight, maxHeight, inputHeight, borderWidth} = this,

            fieldClassName = classNames('remote-auto-complete', {
                [className]: className
            }),

            innerClassName = classNames('auto-complete-inner', {
                focused: focus
            }),

            ulHeight = loading ? 50 : ((data.length > 0) ? data.length * liHeight + borderWidth : 0),

            ulStyle = {
                height: ulHeight > maxHeight ? maxHeight : ulHeight
            },
            innerStyle = {
                height: inputHeight
            },
            liStyle = {
                height: liHeight,
                lineHeight: liHeight + 'px'
            },
            inputStyle = {
                height: inputHeight
            };

        return (

                    <TextField ref="trigger"
                               style={inputStyle}
                               value={value}
                               onFocus={this.onFocus}
                               placeholder={placeholder}
                               onChange={this.onChange}/>

                    <Popup visible={focus}
                           triggerEl={this.triggerEl}
                           hasTriangle={false}
                           triggerMode={Popup.TriggerMode.OPEN}
                           style={{width: this.triggerEl && getComputedStyle(this.triggerEl).width}}>

                            {
                                loading ?

                                        <CircularLoading className="loading"
                                                         size={CircularLoading.Size.DEFAULT}/>

                                    :
                                    data.length > 0 ?
                                        data.map(value =>

{value}

                                        )
                                        :
                                        null
                            }

                    </Popup>

        );
    }
};

RemoteAutoComplete.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The value of input.
     */
    value: PropTypes.string,

    /**
     * The options data.
     */
    data: PropTypes.array,

    /**
     * If true, the list is loading.
     */
    loading: PropTypes.bool,

    /**
     * The placeholder of input.
     */
    placeholder: PropTypes.string,

    /**
     * Callback function fired when value change.
     */
    onChange: PropTypes.func,

    /**
     * Callback function fired when input blur.
     */
    onBlur: PropTypes.func,

    /**
     * Callback function fired when input focus.
     */
    onFocus: PropTypes.func
};

RemoteAutoComplete.defaultProps = {
    className: '',
    style: {},

    value: '',
    data: [],
    searchLength: 1,
    loading: false
};

export default RemoteAutoComplete;<commit_msg>update RemoteAutoComplete<commit_after>/**
 * @file RemoteAutoComplete component
 * @author chao(chao.zhang@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Event from '../_vendors/Event';
import classNames from 'classnames';

import TextField from '../TextField/TextField';
import CircularLoading from '../CircularLoading/CircularLoading';
import Popup from '../Popup';

class RemoteAutoComplete extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value,
            focus: false,
            loading: props.loading
        };

        this.liHeight = 40;
        this.maxHeight = 401;
        this.inputHeight = 50;
        this.borderWidth = 1;

        this.onChange = ::this.onChange;
        this.onClick = ::this.onClick;
        this.getClassName = ::this.getClassName;
        this.onFocus = ::this.onFocus;

    }

    /**
     * 获取当前元素及父元素的类名
     */
    getClassName(element) {
        let className = element.className;
        let current = element.offsetParent;
        while (current !== null) {
            className += current.className;
            current = current.offsetParent;
        }
        return className;
    }

    /**
     * input变化时改变loading状态并触发onChange
     */
    onChange(text) {
        const {onChange} = this.props;

        this.setState({
            value: text
        }, () => {
            this.setState({
                loading: true
            }, () => {
                onChange && onChange(text, true);
            });
        });
    }

    /**
     * 获得焦点时触发onFocus
     */
    onFocus() {
        const {onFocus} = this.props;

        this.setState({
            focus: true
        }, () => {
            onFocus && onFocus();
        });
    }

    /**
     * 点击下拉选项时自动填充且不再auto complete
     */
    onClick(ev) {
        const {onBlur} = this.props;
        const className = this.getClassName(ev.target);

        if (className.indexOf('auto-complete-li') > -1) {
            const {onChange} = this.props;
            let oEvent = ev.srcElement ? ev.srcElement : ev.target;

            this.setState({
                focus: true
            }, () => {
                onChange && onChange(oEvent.innerText, false);
            });
        } else if (className.indexOf('text-field') > -1) {
            return false;
        } else {
            this.setState({
                focus: false
            }, () => {
                onBlur && onBlur(this.state.value);
            });
        }
    }

    /**
     * 接收新的props，如果input或loading有变化，则setState
     */
    componentWillReceiveProps(nextProps) {
        const {value, loading} = this.state;

        if (nextProps.value !== value || nextProps.loading !== loading) {
            this.setState({
                value: nextProps.value,
                loading: nextProps.loading
            });
        }
    }

    componentDidMount() {
        Event.addEvent(document, 'click', this.onClick);
        this.triggerEl = require('react-dom').findDOMNode(this.refs.trigger);
    }

    componentWillUnmount() {
        Event.removeEvent(document, 'click', this.onClick);
    }

    render() {

        const {data, className, style, placeholder} = this.props,
            {value, focus, loading} = this.state,
            {liHeight, maxHeight, inputHeight, borderWidth} = this,

            fieldClassName = classNames('remote-auto-complete', {
                [className]: className
            }),

            innerClassName = classNames('auto-complete-inner', {
                focused: focus
            }),

            ulHeight = loading ? 50 : ((data.length > 0) ? data.length * liHeight + borderWidth : 0),

            ulStyle = {
                height: ulHeight > maxHeight ? maxHeight : ulHeight
            },
            innerStyle = {
                height: inputHeight
            },
            liStyle = {
                height: liHeight,
                lineHeight: liHeight + 'px'
            },
            inputStyle = {
                height: inputHeight
            };

        return (

                    <TextField ref="trigger"
                               style={inputStyle}
                               value={value}
                               onFocus={this.onFocus}
                               placeholder={placeholder}
                               onChange={this.onChange}/>

                    <Popup visible={focus}
                           triggerEl={this.triggerEl}
                           hasTriangle={false}
                           style={{width: this.triggerEl && getComputedStyle(this.triggerEl).width}}>

                            {
                                loading ?

                                        <CircularLoading className="loading"
                                                         size={CircularLoading.Size.DEFAULT}/>

                                    :
                                    data.length > 0 ?
                                        data.map(value =>

{value}

                                        )
                                        :
                                        null
                            }

                    </Popup>

        );
    }
};

RemoteAutoComplete.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The value of input.
     */
    value: PropTypes.string,

    /**
     * The options data.
     */
    data: PropTypes.array,

    /**
     * If true, the list is loading.
     */
    loading: PropTypes.bool,

    /**
     * The placeholder of input.
     */
    placeholder: PropTypes.string,

    /**
     * Callback function fired when value change.
     */
    onChange: PropTypes.func,

    /**
     * Callback function fired when input blur.
     */
    onBlur: PropTypes.func,

    /**
     * Callback function fired when input focus.
     */
    onFocus: PropTypes.func
};

RemoteAutoComplete.defaultProps = {
    className: '',
    style: {},

    value: '',
    data: [],
    searchLength: 1,
    loading: false
};

export default RemoteAutoComplete;<|endoftext|>


<commit_before>const assert = require('assert')

function createTexture2D (ctx, opts) {
  const gl = ctx.gl

  // TODO: implement filtering options

  const texture = {
    class: 'texture2D',
    handle: gl.createTexture(),
    target: opts.target,
    width: 0,
    height: 0,
    _update: updateTexture2D
  }

  updateTexture2D(ctx, texture, opts)

  return texture
}

// opts = { src, width, height }
// opts = { data, width, height, format, flipY }
function updateTexture2D (ctx, texture, opts) {
  const gl = ctx.gl
  const PixelFormat = ctx.PixelFormat

  let data = null
  let width = 0
  let height = 0
  let lod = 0
  let internalFormat = gl.RGBA
  let format = gl.RGBA
  let type = gl.UNSIGNED_BYTE
  let flipY = opts.flipY || false
  let target = opts.target || texture.target

  gl.getExtension('WEBGL_depth_texture')

  const textureUnit = 0
  gl.activeTexture(gl.TEXTURE0 + textureUnit)
  gl.bindTexture(texture.target, texture.handle)
  // TODO: push state (current texture binding)

  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)
  gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  gl.texParameteri(target, gl.TEXTURE_WRAP_S, opts.wrap || gl.CLAMP_TO_EDGE)
  gl.texParameteri(target, gl.TEXTURE_WRAP_T, opts.wrap || gl.CLAMP_TO_EDGE)

  // just an image
  // opts = HTMLImage

  // image with flags
  // opts = { data: HTMLImage, flipY: Boolean }

  // pixel data
  // opts = { data: Array, width: Number, height: Number, flipY: Boolean }

  // pixel data with flags
  // opts = { data: { data: Array, width: Number, height: Number }, flipY: Boolean },

  // array of images for cubemaps (and array textures in webgl2)
  // opts = { data: [ HTMLImage, ... ], width: Number, height: Number, flipY: Boolean }

  // array of pixel data for cubemaps (and array texture in webgl2)
  // opts = { data: [ { data: Array, width: Number, height: Number }, ..], flipY: Boolean }

  const img = opts.data ? opts.data : opts
  if (opts.nodeName || (opts.data && opts.data.nodeName)) {
    assert(img instanceof window.HTMLImageElement ||
      img instanceof window.HTMLCanvasElement,
      'Texture2D.update opts has to be Image, Canvas or Video element')
    // TODO: add support for HTMLVideoElement with videoWidth and videoHeight
    width = img.width
    height = img.height
    gl.texImage2D(target, lod, internalFormat, format, type, img)
  } else if (typeof opts === 'object') {
    assert(!data || Array.isArray(opts.data) ||
      opts.data instanceof Uint8Array ||
      opts.data instanceof Float32Array,
      'Texture2D.update opts.data has to be null or an Array, Uint8Array or Float32Array')

    data = opts.data.data || opts.data

    assert(opts.width && opts.height,
      'Texture2D.update opts.width and opts.height are required when providing opts.data')

    width = opts.width
    height = opts.height

    if (opts.format === PixelFormat.Depth) {
      format = gl.DEPTH_COMPONENT
      internalFormat = gl.DEPTH_COMPONENT
      type = gl.UNSIGNED_SHORT
    } else if (opts.format === PixelFormat.RGBA32F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.FLOAT
    } else if (opts.format === PixelFormat.R32F) {
      format = gl.ALPHA
      internalFormat = gl.ALPHA
      type = gl.FLOAT
    } else if (opts.format) {
      assert.fail(`Unknown texture format: ${opts.format}`)
    }

    if (Array.isArray(data)) {
      if (type === gl.UNSIGNED_BYTE) {
        data = new Uint8Array(data)
      } else if (type === gl.FLOAT) {
        data = new Float32Array(data)
      }
    }

    gl.texImage2D(target, lod, internalFormat, width, height, 0, format, type, data)
  } else {
    // TODO: should i assert of throw new Error(msg)?
    assert.fail('Texture2D.update opts has to be a HTMLElement or Object')
  }

  texture.target = target
  texture.data = data
  texture.width = width
  texture.height = height
  texture.format = format
  texture.internalFormat = internalFormat
  texture.type = type
  return texture
}

module.exports = createTexture2D
<commit_msg>Enable all required texture extensions<commit_after>const assert = require('assert')

function createTexture2D (ctx, opts) {
  const gl = ctx.gl

  // TODO: implement filtering options

  const texture = {
    class: 'texture2D',
    handle: gl.createTexture(),
    target: opts.target,
    width: 0,
    height: 0,
    _update: updateTexture2D
  }

  updateTexture2D(ctx, texture, opts)

  return texture
}

// opts = { src, width, height }
// opts = { data, width, height, format, flipY }
function updateTexture2D (ctx, texture, opts) {
  const gl = ctx.gl
  const PixelFormat = ctx.PixelFormat

  let data = null
  let width = 0
  let height = 0
  let lod = 0
  let internalFormat = gl.RGBA
  let format = gl.RGBA
  let type = gl.UNSIGNED_BYTE
  let flipY = opts.flipY || false
  let target = opts.target || texture.target

  gl.getExtension('WEBGL_depth_texture')
  gl.getExtension('EXT_shader_texture_lod')
  gl.getExtension('OES_texture_float')
  gl.getExtension('OES_texture_float_linear')
  gl.getExtension('OES_texture_half_float')
  gl.getExtension('OES_texture_half_float_linear')

  const textureUnit = 0
  gl.activeTexture(gl.TEXTURE0 + textureUnit)
  gl.bindTexture(texture.target, texture.handle)
  // TODO: push state (current texture binding)

  if (opts.mipmap) {
    if (opts.data || opts.width || opts.height) {
      throw new Error('Updating and generating mipmaps at the same time is currently not supported')
    }
    gl.generateMipmap(texture.target)
    return
  }

  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)
  gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, opts.min || gl.NEAREST)
  gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, opts.mag || gl.NEAREST)
  gl.texParameteri(target, gl.TEXTURE_WRAP_S, opts.wrap || gl.CLAMP_TO_EDGE)
  gl.texParameteri(target, gl.TEXTURE_WRAP_T, opts.wrap || gl.CLAMP_TO_EDGE)

  // just an image
  // opts = HTMLImage

  // image with flags
  // opts = { data: HTMLImage, flipY: Boolean }

  // pixel data
  // opts = { data: Array, width: Number, height: Number, flipY: Boolean }

  // pixel data with flags
  // opts = { data: { data: Array, width: Number, height: Number }, flipY: Boolean },

  // array of images for cubemaps (and array textures in webgl2)
  // opts = { data: [ HTMLImage, ... ], width: Number, height: Number, flipY: Boolean }

  // array of pixel data for cubemaps (and array texture in webgl2)
  // opts = { data: [ { data: Array, width: Number, height: Number }, ..], flipY: Boolean }

  const img = opts.data ? opts.data : opts
  if (opts.nodeName || (opts.data && opts.data.nodeName)) {
    assert(img instanceof window.HTMLImageElement ||
      img instanceof window.HTMLCanvasElement,
      'Texture2D.update opts has to be Image, Canvas or Video element')
    // TODO: add support for HTMLVideoElement with videoWidth and videoHeight
    width = img.width
    height = img.height
    gl.texImage2D(target, lod, internalFormat, format, type, img)
  } else if (typeof opts === 'object') {
    assert(!data || Array.isArray(opts.data) ||
      opts.data instanceof Uint8Array ||
      opts.data instanceof Float32Array,
      'Texture2D.update opts.data has to be null or an Array, Uint8Array or Float32Array')

    data = opts.data.data || opts.data

    assert(opts.width && opts.height,
      'Texture2D.update opts.width and opts.height are required when providing opts.data')

    width = opts.width
    height = opts.height

    if (opts.format === PixelFormat.Depth) {
      format = gl.DEPTH_COMPONENT
      internalFormat = gl.DEPTH_COMPONENT
      type = gl.UNSIGNED_SHORT
    } else if (opts.format === PixelFormat.RGBA32F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.FLOAT
    } else if (opts.format === PixelFormat.R32F) {
      format = gl.ALPHA
      internalFormat = gl.ALPHA
      type = gl.FLOAT
    } else if (opts.format) {
      assert.fail(`Unknown texture format: ${opts.format}`)
    }

    if (Array.isArray(data)) {
      if (type === gl.UNSIGNED_BYTE) {
        data = new Uint8Array(data)
      } else if (type === gl.FLOAT) {
        data = new Float32Array(data)
      }
    }

    gl.texImage2D(target, lod, internalFormat, width, height, 0, format, type, data)
  } else {
    // TODO: should i assert of throw new Error(msg)?
    assert.fail('Texture2D.update opts has to be a HTMLElement or Object')
  }

  texture.target = target
  texture.data = data
  texture.width = width
  texture.height = height
  texture.format = format
  texture.internalFormat = internalFormat
  texture.type = type
  return texture
}

module.exports = createTexture2D
<|endoftext|>


<commit_before>'use strict';

var logger = require('./logger');
var aws = require('aws-sdk');
var _minRetryIntervalMs;
var _maxRetries;
var _retryWindow;

function getWrappedService(sdkOptions, options) {
    _minRetryIntervalMs = options && options.minRetryIntervalMs || 1000;
    _maxRetries = options && options.maxRetries || 8;
    _retryWindow = options && options.retryWindow || 2000;

    var apiGateway = new aws.APIGateway(sdkOptions);
    _wrapMethods(apiGateway);

    return apiGateway;
}

function _wrapMethods(apiGateway) {
    var methodsToWrap = [
        'getBasePathMapping',
        'createBasePathMapping',
        'deleteBasePathMapping',
        'updateBasePathMapping',
        'getDomainName',
        'createDomainName',
        'deleteDomainName',
        'updateDomainName',
        'getMethod',
        'deleteMethod',
        'putMethod',
        'putIntegration',
        'putMethodResponse',
        'updateMethodResponse',
        'putIntegrationResponse',
        'updateIntegrationResponse',
        'getModel',
        'createModel',
        'deleteModel',
        'updateModel',
        'getResource',
        'createResource',
        'deleteResource',
        'updateResource',
        'getResources',
        'getRestApi',
        'createRestApi',
        'deleteRestApi',
        'updateRestApi',
        'getRestApis'
    ];

    for (var i = 0; i < methodsToWrap.length; i++) {
        var methodName = methodsToWrap[i];
        var method = apiGateway[methodName];
        _wrapMethod(apiGateway, methodName, method);
    }
}

function _wrapMethod(apiGateway, methodName, method) {
    apiGateway[methodName] = _getWrappedMethod(apiGateway, methodName, method);
}

function _getWrappedMethod(apiGateway, methodName, method) {
    return function (params, callback) {
        var invocationData = {
            apiGateway: apiGateway,
            methodName: methodName,
            method: method,
            retryCount: 0,
            params: params,
            originalCallback: callback
        };

        // Invoke original method repeatedly until no TooManyRequestsException or max retry limit hit.
        _invokeInnerMethod(invocationData);
    };
}

function _invokeInnerMethod(invocationData) {
    // Replace the original callback with our own to check for TooManyRequests exceptions.
    var retryCheck = function (error, data) { //eslint-disable-line func-style

        if (error && _isRetryableError(error)) {
            if (++invocationData.retryCount <= _maxRetries) {
                // Wait then retry.
                var retryIntervalMs = _getRetryInterval();
                logger.log(invocationData.methodName + ' failed with a retry-able error. Retrying in ' + retryIntervalMs, { error: error });

                setTimeout(function () {
                    logger.log('Retrying ' + invocationData.methodName);
                    _invokeInnerMethod(invocationData);
                }, retryIntervalMs);

                // Drop out so we don't invoke the original callback.
                return;
            }

            // Too many retries - abandon ship.
            logger.log(invocationData.methodName + ' failed with a retryable error and reached max retry count (' + _maxRetries + ')');
        }

        // If we reach here, the call either:
        //  - succeeded (yay);
        //  - failed with an error other than TooManyRequests;
        //  - reached the max retry count after numerous TooManyRequests errors.
        // Whichever, we still need to invoke the original callback.
        invocationData.originalCallback(error, data);
    };

    invocationData.method.call(invocationData.apiGateway, invocationData.params, retryCheck);
}

function _isRetryableErrorMessage(message) {
  return error.message && error.message.indexOf('Please try again later') > -1
}

function _isRetryableError(error) {
    return error
        && (error.code === 'TooManyRequestsException'
            || _isRetryableErrorMessage(error.message))
        || error.retryable;
}

function _getRetryInterval() {
    return _minRetryIntervalMs
        + Math.random() * _retryWindow;
}

module.exports = getWrappedService;
<commit_msg>fix typos<commit_after>'use strict';

var logger = require('./logger');
var aws = require('aws-sdk');
var _minRetryIntervalMs;
var _maxRetries;
var _retryWindow;

function getWrappedService(sdkOptions, options) {
    _minRetryIntervalMs = options && options.minRetryIntervalMs || 1000;
    _maxRetries = options && options.maxRetries || 8;
    _retryWindow = options && options.retryWindow || 2000;

    var apiGateway = new aws.APIGateway(sdkOptions);
    _wrapMethods(apiGateway);

    return apiGateway;
}

function _wrapMethods(apiGateway) {
    var methodsToWrap = [
        'getBasePathMapping',
        'createBasePathMapping',
        'deleteBasePathMapping',
        'updateBasePathMapping',
        'getDomainName',
        'createDomainName',
        'deleteDomainName',
        'updateDomainName',
        'getMethod',
        'deleteMethod',
        'putMethod',
        'putIntegration',
        'putMethodResponse',
        'updateMethodResponse',
        'putIntegrationResponse',
        'updateIntegrationResponse',
        'getModel',
        'createModel',
        'deleteModel',
        'updateModel',
        'getResource',
        'createResource',
        'deleteResource',
        'updateResource',
        'getResources',
        'getRestApi',
        'createRestApi',
        'deleteRestApi',
        'updateRestApi',
        'getRestApis'
    ];

    for (var i = 0; i < methodsToWrap.length; i++) {
        var methodName = methodsToWrap[i];
        var method = apiGateway[methodName];
        _wrapMethod(apiGateway, methodName, method);
    }
}

function _wrapMethod(apiGateway, methodName, method) {
    apiGateway[methodName] = _getWrappedMethod(apiGateway, methodName, method);
}

function _getWrappedMethod(apiGateway, methodName, method) {
    return function (params, callback) {
        var invocationData = {
            apiGateway: apiGateway,
            methodName: methodName,
            method: method,
            retryCount: 0,
            params: params,
            originalCallback: callback
        };

        // Invoke original method repeatedly until no TooManyRequestsException or max retry limit hit.
        _invokeInnerMethod(invocationData);
    };
}

function _invokeInnerMethod(invocationData) {
    // Replace the original callback with our own to check for TooManyRequests exceptions.
    var retryCheck = function (error, data) { //eslint-disable-line func-style

        if (error && _isRetryableError(error)) {
            if (++invocationData.retryCount <= _maxRetries) {
                // Wait then retry.
                var retryIntervalMs = _getRetryInterval();
                logger.log(invocationData.methodName + ' failed with a retry-able error. Retrying in ' + retryIntervalMs, { error: error });

                setTimeout(function () {
                    logger.log('Retrying ' + invocationData.methodName);
                    _invokeInnerMethod(invocationData);
                }, retryIntervalMs);

                // Drop out so we don't invoke the original callback.
                return;
            }

            // Too many retries - abandon ship.
            logger.log(invocationData.methodName + ' failed with a retryable error and reached max retry count (' + _maxRetries + ')');
        }

        // If we reach here, the call either:
        //  - succeeded (yay);
        //  - failed with an error other than TooManyRequests;
        //  - reached the max retry count after numerous TooManyRequests errors.
        // Whichever, we still need to invoke the original callback.
        invocationData.originalCallback(error, data);
    };

    invocationData.method.call(invocationData.apiGateway, invocationData.params, retryCheck);
}

function _isRetryableErrorMessage(message) {
    return message && message.indexOf('Please try again later') > -1;
}

function _isRetryableError(error) {
    return error
        && (error.code === 'TooManyRequestsException'
            || _isRetryableErrorMessage(error.message))
        || error.retryable;
}

function _getRetryInterval() {
    return _minRetryIntervalMs
        + Math.random() * _retryWindow;
}

module.exports = getWrappedService;
<|endoftext|>


<commit_before>import formatValue from '../utils/formatValue';

describe('utils | formatValue', () => {
  it('should format array to object', () => {
    const initialValue = ['entry.create', 'entry.update', 'media.delete'];
    const expectedValue = {
      entry: ['entry.create', 'entry.update'],
      media: ['media.delete'],
    };

    const formattedValue = formatValue(initialValue);

    expect(expectedValue).toEqual(formattedValue);
  });
});
<commit_msg>invert values in EventInput formatValue unit test<commit_after>import formatValue from '../utils/formatValue';

describe('utils | formatValue', () => {
  it('should format array to object', () => {
    const initialValue = ['entry.create', 'entry.update', 'media.delete'];
    const expectedValue = {
      entry: ['entry.create', 'entry.update'],
      media: ['media.delete'],
    };

    const formattedValue = formatValue(initialValue);

    expect(formattedValue).toEqual(expectedValue);
  });
});
<|endoftext|>


<commit_before>/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; 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';
var fs = require('fs');
var Clipboard = require('clipboard');

var template = fs.readFileSync(__dirname + '/cam-widget-clipboard.html', 'utf8');

module.exports = ['$timeout', '$translate', function($timeout, $translate) {
  return {
    transclude: true,
    template: template,
    scope: {
      value: '=camWidgetClipboard'
    },

    link: function($scope, element, attrs) {
      var cb;

      $scope.noTooltip = typeof attrs.noTooltip !== 'undefined';
      $scope.copyStatus = null;
      $scope.icon = attrs.icon || 'glyphicon-copy';

      $scope.$watch('value', function() {
        $scope.tooltipText = attrs.tooltipText || $translate.instant('CAM_WIDGET_COPY', {value: $scope.value});
      });

      var _top;
      function restore() {
        $scope.$apply();
        _top = $timeout(function() {
          $scope.copyStatus = null;
        }, 1200, true);
      }

      function resize() {

        var content = element[0].querySelector('[ng-transclude]');
        var offset = element[0].parentElement.offsetWidth - element[0].offsetWidth;

        if(element[0].tagName.toLowerCase() !== 'span') {
          // element is the container
          offset = content.offsetWidth - element[0].offsetWidth;
        }

        // 2em at 12px
        if(offset < 24) {
          if(content.className.indexOf('resize') === -1)
            content.className += ' resize';
        } else {
          content.className = content.className.replace(' resize', '');
        }
      }

      // needed because otherwise the content of `element` is not rendered yet
      // and `querySelector` is then not available
      $timeout(function() {
        var link = element[0].querySelector('a.' + $scope.icon);
        if (!link) { return; }

        window.addEventListener('resize', resize);
        resize();

        cb = new Clipboard(link, {
          text: function() {
            return $scope.value;
          }
        });

        cb.on('success', function() {
          $scope.copyStatus = true;
          restore();
        });

        cb.on('error', function() {
          $scope.copyStatus = false;
          restore();
        });
      });

      $scope.$on('$destroy', function() {
        window.removeEventListener('resize', resize);
        if (cb && cb.destroy) {
          cb.destroy();
        }

        if (_top) {
          $timeout.cancel(_top);
        }
      });
    }
  };
}];
<commit_msg>chore(clipboard): rename resize to handleResize<commit_after>/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; 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';
var fs = require('fs');
var Clipboard = require('clipboard');

var template = fs.readFileSync(__dirname + '/cam-widget-clipboard.html', 'utf8');

module.exports = ['$timeout', '$translate', function($timeout, $translate) {
  return {
    transclude: true,
    template: template,
    scope: {
      value: '=camWidgetClipboard'
    },

    link: function($scope, element, attrs) {
      var cb;

      $scope.noTooltip = typeof attrs.noTooltip !== 'undefined';
      $scope.copyStatus = null;
      $scope.icon = attrs.icon || 'glyphicon-copy';

      $scope.$watch('value', function() {
        $scope.tooltipText = attrs.tooltipText || $translate.instant('CAM_WIDGET_COPY', {value: $scope.value});
      });

      var _top;
      function restore() {
        $scope.$apply();
        _top = $timeout(function() {
          $scope.copyStatus = null;
        }, 1200, true);
      }

      function handleResize() {

        var content = element[0].querySelector('[ng-transclude]');
        var offset = element[0].parentElement.offsetWidth - element[0].offsetWidth;

        if(element[0].tagName.toLowerCase() !== 'span') {
          // element is the container
          offset = content.offsetWidth - element[0].offsetWidth;
        }

        // 2em at 12px
        if(offset < 24) {
          if(content.className.indexOf('resize') === -1)
            content.className += ' resize';
        } else {
          content.className = content.className.replace(' resize', '');
        }
      }

      // needed because otherwise the content of `element` is not rendered yet
      // and `querySelector` is then not available
      $timeout(function() {
        var link = element[0].querySelector('a.' + $scope.icon);
        if (!link) { return; }

        window.addEventListener('resize', handleResize);
        handleResize();

        cb = new Clipboard(link, {
          text: function() {
            return $scope.value;
          }
        });

        cb.on('success', function() {
          $scope.copyStatus = true;
          restore();
        });

        cb.on('error', function() {
          $scope.copyStatus = false;
          restore();
        });
      });

      $scope.$on('$destroy', function() {
        window.removeEventListener('resize', handleResize);
        if (cb && cb.destroy) {
          cb.destroy();
        }

        if (_top) {
          $timeout.cancel(_top);
        }
      });
    }
  };
}];
<|endoftext|>


<commit_before>"use strict";

const EventEmitter = require("events").EventEmitter;
const util = require("util");
const EventSource = require("eventsource");

/**
 * Represents a Marathon Event Bus Client
 * @constructor
 * @param {object} options - The option map object.
 */
function MarathonEventBusClient (options) {

    if (!(this instanceof MarathonEventBusClient)) {
        return new MarathonEventBusClient(options);
    }

    // Inherit from EventEmitter
    EventEmitter.call(this);

    let self = this;

    // See https://github.com/mesosphere/marathon/blob/master/src/main/scala/mesosphere/marathon/core/event/Events.scala
    self.allowedEventTypes = [
      "pod_created_event","pod_updated_event", "pod_deleted_event","scheduler_registered_event", "scheduler_reregistered_event", "scheduler_disconnected_event", "subscribe_event", "unsubscribe_event", "event_stream_attached", "event_stream_detached", "add_health_check_event", "remove_health_check_event", "failed_health_check_event", "health_status_changed_event", "unhealthy_task_kill_event", "group_change_success", "group_change_failed", "deployment_info", "deployment_success", "deployment_failed", "deployment_step_success", "deployment_step_failure", "app_terminated_event", "status_update_event", "instance_changed_event", "unknown_instance_terminated_event", "instance_health_changed_event", "framework_message_event"
    ];

    self.allowedHeaeders = [
      'Content-Type', 'Authorization'
    ];

    self.options = {};

    // Marathon endpoint discovery
    self.options.marathonHost = options.marathonHost || "master.mesos";
    self.options.marathonPort = parseInt(options.marathonPort) || 8080;
    self.options.marathonProtocol = options.marathonProtocol || "http";
    self.options.marathonUri = options.marathonUri || "/v2/events";
    /*
     You can add additionals headers
     {'Authorization': 'token=MARATHON_AUTH_TOKEN', 'Content-Type': 'application/json'}
    */
    self.options.marathonHeaders = options.marathonHeaders || {};

    // Whether to emit a "connectionId" event
    self.options.enableConnectionEvent = options.enableConnectionEvent || false;

    // Set the used eventTypes
    if (options.eventTypes && options.eventTypes.length > 0) {
        self.options.eventTypes = [];
            options.eventTypes.forEach(function (eventType) {
            if (self.allowedEventTypes.indexOf(eventType) > -1) {
                self.options.eventTypes.push(eventType);
            }
        });
    } else {
        // Just use the deployment events by default, to avoid channel flooding
        self.options.eventTypes = ["deployment_info", "deployment_success", "deployment_failed"];
    }

    if (options.marathonHeaders && Object.keys(options.marathonHeaders).length > 0) {
      self.options.marathonHeaders = {};
        Object.keys(options.marathonHeaders).forEach(function (key) {
          if(self.allowedHeaeders.indexOf(key) > -1) {
            self.options.marathonHeaders[key] = options.marathonHeaders[key];
          }
        });
    }

    if (self.options.enableConnectionEvent) {
        self.options.eventTypes.push("connectionId");
    }

    function isFunction(obj) {
        return !!(obj && obj.constructor && obj.call && obj.apply);
    }

    // Event handlers
    self.options.eventHandlers = {};

    // Add custom event handlers if present
    if (options.handlers && Object.getOwnPropertyNames(options.handlers).length > 0) {
        Object.getOwnPropertyNames(options.handlers).forEach(function (handlerName) {
            const lcHandlerName = handlerName.toLowerCase();
            // Check if name is in defined event types, is a function
            if (self.options.eventTypes.indexOf(lcHandlerName) > -1 && isFunction(options.handlers[handlerName])) {
                self.options.eventHandlers[lcHandlerName] = function (name, data) {
                    // Emit according event
                    self.emit(name, data);
                    // Call custom event handler
                    options.handlers[handlerName](name, data);
                }
            }
        });
    }

    // Check if an event handlers has been defined for each event type
    self.options.eventTypes.forEach(function (eventType) {
        // If there's no event handler defined yet, set a default event handler which just prints the event name
        if (!self.options.eventHandlers.hasOwnProperty(eventType)) {
            self.options.eventHandlers[eventType] = function (name, data) {
                // Emit according event
                self.emit(name, data);
                // Log event name
                console.log("Default handler for " + name + ". Do nothing.");
            }
        }
    });

}

// Inherit from EventEmitter
util.inherits(MarathonEventBusClient, EventEmitter);

/**
 * Subscribes the MarathonEventBusClient to the Marathon Event Bus
 */
MarathonEventBusClient.prototype.subscribe = function () {

    let self = this,
        url = self.options.marathonProtocol + "://" + self.options.marathonHost + ":" + self.options.marathonPort+self.options.marathonUri;

    // Allow unauthorized HTTPS requests
    let eventSourceInitDict = self.options.marathonHeaders;

    eventSourceInitDict.rejectUnauthorized = false;

    // Create EventSource for Marathon /v2/events endpoint
    self.es = new EventSource(url, eventSourceInitDict);

    self.es.on("open", function () {
        self.emit("subscribed", { "timestamp": ((new Date().getTime())/1000) })
    });

    self.es.on("error", function (error) {
        self.emit("error", { "timestamp": ((new Date().getTime())/1000), error: error })
    });

    // Iterate over event types
    self.options.eventTypes.forEach(function (type) {
        // Add event listeners
        self.es.addEventListener(type, function (e) {
            self.options.eventHandlers[type](e.type, JSON.parse(e.data));
        });

    });

};

/**
 * Unsubscribes from the Marathon Event Bus
 */
MarathonEventBusClient.prototype.unsubscribe = function () {
    let self = this;
    self.emit("unsubscribed");
    setTimeout(function () {
        self.es.close();
    }, 100);
};

module.exports = MarathonEventBusClient;
<commit_msg>add headers comment<commit_after>"use strict";

const EventEmitter = require("events").EventEmitter;
const util = require("util");
const EventSource = require("eventsource");

/**
 * Represents a Marathon Event Bus Client
 * @constructor
 * @param {object} options - The option map object.
 */
function MarathonEventBusClient (options) {

    if (!(this instanceof MarathonEventBusClient)) {
        return new MarathonEventBusClient(options);
    }

    // Inherit from EventEmitter
    EventEmitter.call(this);

    let self = this;

    // See https://github.com/mesosphere/marathon/blob/master/src/main/scala/mesosphere/marathon/core/event/Events.scala
    self.allowedEventTypes = [
      "pod_created_event","pod_updated_event", "pod_deleted_event","scheduler_registered_event", "scheduler_reregistered_event", "scheduler_disconnected_event", "subscribe_event", "unsubscribe_event", "event_stream_attached", "event_stream_detached", "add_health_check_event", "remove_health_check_event", "failed_health_check_event", "health_status_changed_event", "unhealthy_task_kill_event", "group_change_success", "group_change_failed", "deployment_info", "deployment_success", "deployment_failed", "deployment_step_success", "deployment_step_failure", "app_terminated_event", "status_update_event", "instance_changed_event", "unknown_instance_terminated_event", "instance_health_changed_event", "framework_message_event"
    ];

    self.allowedHeaeders = [
      'Content-Type', 'Authorization'
    ];

    self.options = {};

    // Marathon endpoint discovery
    self.options.marathonHost = options.marathonHost || "master.mesos";
    self.options.marathonPort = parseInt(options.marathonPort) || 8080;
    self.options.marathonProtocol = options.marathonProtocol || "http";
    self.options.marathonUri = options.marathonUri || "/v2/events";
    /*
     You can add additionals headers
     {'Authorization': 'token=MARATHON_AUTH_TOKEN', 'Content-Type': 'application/json'}
    */
    self.options.marathonHeaders = options.marathonHeaders || {};

    // Whether to emit a "connectionId" event
    self.options.enableConnectionEvent = options.enableConnectionEvent || false;

    // Set the used eventTypes
    if (options.eventTypes && options.eventTypes.length > 0) {
        self.options.eventTypes = [];
            options.eventTypes.forEach(function (eventType) {
            if (self.allowedEventTypes.indexOf(eventType) > -1) {
                self.options.eventTypes.push(eventType);
            }
        });
    } else {
        // Just use the deployment events by default, to avoid channel flooding
        self.options.eventTypes = ["deployment_info", "deployment_success", "deployment_failed"];
    }
    // Set custom headers if present
    if (options.marathonHeaders && Object.keys(options.marathonHeaders).length > 0) {
      self.options.marathonHeaders = {};
        Object.keys(options.marathonHeaders).forEach(function (key) {
          if(self.allowedHeaeders.indexOf(key) > -1) {
            self.options.marathonHeaders[key] = options.marathonHeaders[key];
          }
        });
    }

    if (self.options.enableConnectionEvent) {
        self.options.eventTypes.push("connectionId");
    }

    function isFunction(obj) {
        return !!(obj && obj.constructor && obj.call && obj.apply);
    }

    // Event handlers
    self.options.eventHandlers = {};

    // Add custom event handlers if present
    if (options.handlers && Object.getOwnPropertyNames(options.handlers).length > 0) {
        Object.getOwnPropertyNames(options.handlers).forEach(function (handlerName) {
            const lcHandlerName = handlerName.toLowerCase();
            // Check if name is in defined event types, is a function
            if (self.options.eventTypes.indexOf(lcHandlerName) > -1 && isFunction(options.handlers[handlerName])) {
                self.options.eventHandlers[lcHandlerName] = function (name, data) {
                    // Emit according event
                    self.emit(name, data);
                    // Call custom event handler
                    options.handlers[handlerName](name, data);
                }
            }
        });
    }

    // Check if an event handlers has been defined for each event type
    self.options.eventTypes.forEach(function (eventType) {
        // If there's no event handler defined yet, set a default event handler which just prints the event name
        if (!self.options.eventHandlers.hasOwnProperty(eventType)) {
            self.options.eventHandlers[eventType] = function (name, data) {
                // Emit according event
                self.emit(name, data);
                // Log event name
                console.log("Default handler for " + name + ". Do nothing.");
            }
        }
    });

}

// Inherit from EventEmitter
util.inherits(MarathonEventBusClient, EventEmitter);

/**
 * Subscribes the MarathonEventBusClient to the Marathon Event Bus
 */
MarathonEventBusClient.prototype.subscribe = function () {

    let self = this,
        url = self.options.marathonProtocol + "://" + self.options.marathonHost + ":" + self.options.marathonPort+self.options.marathonUri;

    // Allow unauthorized HTTPS requests
    let eventSourceInitDict = self.options.marathonHeaders;

    eventSourceInitDict.rejectUnauthorized = false;

    // Create EventSource for Marathon /v2/events endpoint
    self.es = new EventSource(url, eventSourceInitDict);

    self.es.on("open", function () {
        self.emit("subscribed", { "timestamp": ((new Date().getTime())/1000) })
    });

    self.es.on("error", function (error) {
        self.emit("error", { "timestamp": ((new Date().getTime())/1000), error: error })
    });

    // Iterate over event types
    self.options.eventTypes.forEach(function (type) {
        // Add event listeners
        self.es.addEventListener(type, function (e) {
            self.options.eventHandlers[type](e.type, JSON.parse(e.data));
        });

    });

};

/**
 * Unsubscribes from the Marathon Event Bus
 */
MarathonEventBusClient.prototype.unsubscribe = function () {
    let self = this;
    self.emit("unsubscribed");
    setTimeout(function () {
        self.es.close();
    }, 100);
};

module.exports = MarathonEventBusClient;
<|endoftext|>


<commit_before>/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
 * text of the license. */

/**
 * @class
 *
 * @requires OpenLayers/Layer/Grid.js
 */
OpenLayers.Layer.KaMap = Class.create();
OpenLayers.Layer.KaMap.prototype =
  Object.extend( new OpenLayers.Layer.Grid(), {

    /** KaMap Layer is always a base layer
     *
     * @type Boolean
     */
    isBaseLayer: true,

    units: null,

    resolution: OpenLayers.DOTS_PER_INCH,

    DEFAULT_PARAMS: {
        i: 'jpeg',
        map: ''
    },

    initialize: function(name, url, params, options) {
        var newArguments = new Array();
        newArguments.push(name, url, params, options);
        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
        this.params = (params ? params : {});
        if (arguments.length > 0 && params) {
            OpenLayers.Util.applyDefaults(
                           this.params,
                           this.DEFAULT_PARAMS
                           );
        }
    },

    /**
     * @param {OpenLayers.Bounds} bounds
     *
     * @returns A string with the layer's url and parameters and also the
     *           passed-in bounds and appropriate tile size specified as
     *           parameters
     * @type String
     */
    getURL: function (bounds) {
        var zoom = this.map.getZoom();
        var scale = this.map.getScale();
        var cellSize = new OpenLayers.Size(mapRes*this.tileSize.w, mapRes*this.tileSize.h);
        var pX = Math.round(((bounds.left) / cellSize.w) * this.tileSize.w);
        var pY = -Math.round(((bounds.top) / cellSize.h) * this.tileSize.h);
        return this.getFullRequestString(
                      { t: pY,
                        l: pX,
                        s: scale
                      });
    },

    addTile:function(bounds,position) {
        var url = this.getURL(bounds);
        return new OpenLayers.Tile.Image(this, position, bounds,
                                             url, this.tileSize);
    },

    _initTiles:function() {

        var viewSize = this.map.getSize();
        var bounds = this.map.getExtent();
        var extent = this.map.getMaxExtent();
        var resolution = this.map.getResolution();
        var tilelon = resolution*this.tileSize.w;
        var tilelat = resolution*this.tileSize.h;

        var offsetlon = bounds.left;
        var tilecol = Math.floor(offsetlon/tilelon);
        var tilecolremain = offsetlon/tilelon - tilecol;
        var tileoffsetx = -tilecolremain * this.tileSize.w;
        var tileoffsetlon = tilecol * tilelon;

        var offsetlat = bounds.top;
        var tilerow = Math.ceil(offsetlat/tilelat);
        var tilerowremain = tilerow - offsetlat/tilelat;
        var tileoffsety = -(tilerowremain+1) * this.tileSize.h;
        var tileoffsetlat = tilerow * tilelat;

        tileoffsetx = Math.round(tileoffsetx); // heaven help us
        tileoffsety = Math.round(tileoffsety);

        this.origin = new OpenLayers.Pixel(tileoffsetx,tileoffsety);

        var startX = tileoffsetx;
        var startLon = tileoffsetlon;

        var rowidx = 0;

        do {
            var row;

            row = this.grid[rowidx++];
            if (!row) {
                row = new Array();
                this.grid.push(row);
            }

            tileoffsetlon = startLon;
            tileoffsetx = startX;

            var colidx = 0;

            do {
                var tileBounds = new OpenLayers.Bounds(tileoffsetlon,
                                                      tileoffsetlat,
                                                      tileoffsetlon + tilelon,
                                                      tileoffsetlat + tilelat);

                var x = tileoffsetx;
                x -= parseInt(this.map.layerContainerDiv.style.left);

                var y = tileoffsety;
                y -= parseInt(this.map.layerContainerDiv.style.top);

                var px = new OpenLayers.Pixel(x, y);
                var tile;

                tile = row[colidx++];
                if (!tile) {
                    tile = this.addTile(tileBounds, px);
                    row.push(tile);
                } else {
                    tile.moveTo(tileBounds, px, false);
                }

                tileoffsetlon += tilelon;
                tileoffsetx += this.tileSize.w;
            } while (tileoffsetlon <= bounds.right + tilelon * this.buffer)

            tileoffsetlat -= tilelat;
            tileoffsety += this.tileSize.h;
        } while(tileoffsetlat >= bounds.bottom - tilelat * this.buffer)

        this.spiralTileLoad();

    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Layer.KaMap"
});
<commit_msg>Fix missed change in KaMap. Tests now all pass.<commit_after>/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
 * text of the license. */

/**
 * @class
 *
 * @requires OpenLayers/Layer/Grid.js
 */
OpenLayers.Layer.KaMap = Class.create();
OpenLayers.Layer.KaMap.prototype =
  Object.extend( new OpenLayers.Layer.Grid(), {

    /** KaMap Layer is always a base layer
     *
     * @type Boolean
     */
    isBaseLayer: true,

    units: null,

    resolution: OpenLayers.DOTS_PER_INCH,

    DEFAULT_PARAMS: {
        i: 'jpeg',
        map: ''
    },

    initialize: function(name, url, params, options) {
        var newArguments = new Array();
        newArguments.push(name, url, params, options);
        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
        this.params = (params ? params : {});
        if (arguments.length > 0 && params) {
            OpenLayers.Util.applyDefaults(
                           this.params,
                           this.DEFAULT_PARAMS
                           );
        }
    },

    /**
     * @param {OpenLayers.Bounds} bounds
     *
     * @returns A string with the layer's url and parameters and also the
     *           passed-in bounds and appropriate tile size specified as
     *           parameters
     * @type String
     */
    getURL: function (bounds) {
        var mapRes = this.map.getResolution();
        var scale = this.map.getScale();
        var cellSize = new OpenLayers.Size(mapRes*this.tileSize.w, mapRes*this.tileSize.h);
        var pX = Math.round(((bounds.left) / cellSize.w) * this.tileSize.w);
        var pY = -Math.round(((bounds.top) / cellSize.h) * this.tileSize.h);
        return this.getFullRequestString(
                      { t: pY,
                        l: pX,
                        s: scale
                      });
    },

    addTile:function(bounds,position) {
        var url = this.getURL(bounds);
        return new OpenLayers.Tile.Image(this, position, bounds,
                                             url, this.tileSize);
    },

    _initTiles:function() {

        var viewSize = this.map.getSize();
        var bounds = this.map.getExtent();
        var extent = this.map.getMaxExtent();
        var resolution = this.map.getResolution();
        var tilelon = resolution*this.tileSize.w;
        var tilelat = resolution*this.tileSize.h;

        var offsetlon = bounds.left;
        var tilecol = Math.floor(offsetlon/tilelon);
        var tilecolremain = offsetlon/tilelon - tilecol;
        var tileoffsetx = -tilecolremain * this.tileSize.w;
        var tileoffsetlon = tilecol * tilelon;

        var offsetlat = bounds.top;
        var tilerow = Math.ceil(offsetlat/tilelat);
        var tilerowremain = tilerow - offsetlat/tilelat;
        var tileoffsety = -(tilerowremain+1) * this.tileSize.h;
        var tileoffsetlat = tilerow * tilelat;

        tileoffsetx = Math.round(tileoffsetx); // heaven help us
        tileoffsety = Math.round(tileoffsety);

        this.origin = new OpenLayers.Pixel(tileoffsetx,tileoffsety);

        var startX = tileoffsetx;
        var startLon = tileoffsetlon;

        var rowidx = 0;

        do {
            var row;

            row = this.grid[rowidx++];
            if (!row) {
                row = new Array();
                this.grid.push(row);
            }

            tileoffsetlon = startLon;
            tileoffsetx = startX;

            var colidx = 0;

            do {
                var tileBounds = new OpenLayers.Bounds(tileoffsetlon,
                                                      tileoffsetlat,
                                                      tileoffsetlon + tilelon,
                                                      tileoffsetlat + tilelat);

                var x = tileoffsetx;
                x -= parseInt(this.map.layerContainerDiv.style.left);

                var y = tileoffsety;
                y -= parseInt(this.map.layerContainerDiv.style.top);

                var px = new OpenLayers.Pixel(x, y);
                var tile;

                tile = row[colidx++];
                if (!tile) {
                    tile = this.addTile(tileBounds, px);
                    row.push(tile);
                } else {
                    tile.moveTo(tileBounds, px, false);
                }

                tileoffsetlon += tilelon;
                tileoffsetx += this.tileSize.w;
            } while (tileoffsetlon <= bounds.right + tilelon * this.buffer)

            tileoffsetlat -= tilelat;
            tileoffsety += this.tileSize.h;
        } while(tileoffsetlat >= bounds.bottom - tilelat * this.buffer)

        this.spiralTileLoad();

    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Layer.KaMap"
});
<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.
if ( process.argv<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.
if ( process.argv[<|endoftext|>


<commit_before>import { applyMiddleware, createStore } from 'redux'
import createSocketIoMiddleware from 'redux-socket.io'
import io from 'socket.io-client'
import R from 'ramda'

/* PROD */
let socket = io('https://buildmaster.cfapps.io')

/* NON-PROD */
// let socket = io('http://localhost:4000')

let socketIOMiddleware = createSocketIoMiddleware(socket, 'server/')

export default function configureStore () {
  function reducer (state = {}, action) {
    switch (action.type) {
      case 'message':
        return Object.assign({}, {
          builds:
            limitBuildCount(
              removeGreenLatest(
                combinedPayloadState(action.data.payload, state.builds)
              )
            )
        })
      default:
        return state
    }
  }

  function combinedPayloadState (payload, builds) {
    let isUniqueByRepoAndBranch = R.allPass([
      R.eqBy(R.prop('reponame')),
      R.eqBy(R.prop('branch'))
    ])

    return R.unionWith(isUniqueByRepoAndBranch, [payload], builds)
  }

  function limitBuildCount (builds) {
    return R.slice(0, 10, builds)
  }

  function removeGreenLatest (builds) {
    return R.reject(R.propEq('branch', 'green-latest'), builds)
  }

  const initialState = {builds: []}

  return applyMiddleware(socketIOMiddleware)(createStore)(reducer, initialState)
}
<commit_msg>SCHOMAY<commit_after>import { applyMiddleware, createStore } from 'redux'
import createSocketIoMiddleware from 'redux-socket.io'
import io from 'socket.io-client'
import R from 'ramda'

/* PROD */
let socket = io('https://buildmaster.cfapps.io')

/* NON-PROD */
// let socket = io('http://localhost:4000')

let socketIOMiddleware = createSocketIoMiddleware(socket, 'server/')

export default function configureStore () {
  function reducer (state = {}, action) {
    switch (action.type) {
      case 'message':
        let filterBuilds = R.compose(
          // toBuildObject
          limitBuildCount,
          removeGreenLatest,
          combinedPayloadState
        )
        return Object.assign({}, {
          builds: filterBuilds([action.data.payload], state.builds)
        })
      default:
        return state
    }
  }

  // TODO: const toBuildObject

  const limitBuildCount = R.slice(0, 10)

  const removeGreenLatest = R.reject(R.propEq('branch', 'green-latest'))

  function combinedPayloadState (payload, builds) {
    let isUniqueByRepoAndBranch = R.allPass([
      R.eqBy(R.prop('reponame')),
      R.eqBy(R.prop('branch'))
    ])

    return R.unionWith(isUniqueByRepoAndBranch, payload, builds)
  }

  const initialState = {builds: []}

  return applyMiddleware(socketIOMiddleware)(createStore)(reducer, initialState)
}
<|endoftext|>