<commit_before>var http = require("http");
var socketIo = require("socket.io");
var config = require("../config");
var listeners = require("./listeners");
var database = require("./database");
var domain = require("domain");
var utils = require("./utils");
var routing = require("./routing");

Object.defineProperty(Error.prototype, "toJSON", {
	value: function() {
		return this.message;
	},
	configurable: true
});

database.connect(function(err) {
	if(err)
		throw err;

	var app = http.createServer();
	app.listen(config.port, config.host);
	var io = socketIo.listen(app);

	io.sockets.on("connection", function(socket) {
		var d = domain.create();
		d.add(socket);

		var handlers = {
			error : function(err) {
				console.error("Error! Disconnecting client.");
				console.error(err.stack);
				socket.disconnect();
			},

			setPadId : function(padId) {
				if(typeof padId != "string" || socket.padId != null)
					return;

				socket.padId = true;

				database.getPadData(padId, function(err, data) {
					if(err)
						return _sendData(socket, "padData", err);

					socket.padId = data.id;
					socket.writable = data.writable;
					listeners.addPadListener(socket);

					_sendData(socket, "padData", null, data);
					_sendStreamData(socket, "view", database.getViews(socket.padId));
					_sendStreamData(socket, "type", database.getTypes(socket.padId));
					_sendStreamData(socket, "line", database.getPadLines(socket.padId));

					if(socket.bbox) { // In case bbox is set while fetching pad data
						_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, socket.bbox));
						_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, socket.bbox));
					}
				});
			},

			updateBbox : function(bbox) {
				if(!utils.stripObject(bbox, { top: "number", left: "number", bottom: "number", right: "number", zoom: "number" }))
					return;

				var bboxWithExcept = utils.extend({ }, bbox);
				if(socket.bbox && bbox.zoom == socket.bbox.zoom)
					bboxWithExcept.except = socket.bbox;

				socket.bbox = bbox;

				if(socket.padId && socket.padId !== true) {
					_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, bboxWithExcept));
					_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, bboxWithExcept));
				}
			},

			disconnect : function() {
				if(socket.padId)
					listeners.removePadListener(socket);
			},

			editPad : function(data, callback) {
				if(!utils.stripObject(data, { name: "string", defaultViewId: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updatePadData(socket.padId, data, callback);
			},

			addMarker : function(data, callback) {
				if(!utils.stripObject(data, { lat: "number", lon: "number", name: "string", colour: "string", typeId: "number", data: Object } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createMarker(socket.padId, data, callback);
			},

			editMarker : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", lat: "number", lon: "number", name: "string", colour: "string", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateMarker(data.id, data, callback);
			},

			deleteMarker : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteMarker(data.id, callback);
			},

			getLineTemplate : function(data, callback) {
				if(!utils.stripObject(data, { typeId: "number" }) || data.typeId == null)
					return callback("Invalid parameters.");

				database.getLineTemplate(data, callback);
			},

			addLine : function(data, callback) {
				if(!utils.stripObject(data, { points: [ { lat: "number", lon: "number" } ], mode: "string", colour: "string", width: "number", name: "string", typeId: "number", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createLine(socket.padId, data, callback);
			},

			editLine : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", points: [ { lat: "number", lon: "number" } ], mode: "string", colour: "string", width: "number", name: "string", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateLine(data.id, data, callback);
			},

			deleteLine : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteLine(data.id, callback);
			},

			addView : function(data, callback) {
				if(!utils.stripObject(data, { name: "string", baseLayer: "string", layers: [ "string" ], top: "number", left: "number", right: "number", bottom: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createView(socket.padId, data, callback);
			},

			editView : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", baseLayer: "string", layers: [ "string" ], top: "number", left: "number", right: "number", bottom: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateView(data.id, data, callback);
			},

			deleteView : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteView(data.id, callback);
			},

			addType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", name: "string", type: "string", fields: [ { name: "string", type: "string", default: "string", controlColour: "boolean", options: [ { key: "string", value: "string", colour: "string" } ] }] } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createType(socket.padId, data, callback);
			},

			editType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", name: "string", fields: [ { name: "string", type: "string", default: "string", controlColour: "boolean", controlWidth: "boolean", options: [ { key: "string", value: "string", colour: "string", width: "number" } ] }] } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateType(data.id, data, callback);
			},

			deleteType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteType(data.id, callback);
			}/*,

			copyPad : function(data, callback) {
				if(!utils.stripObject(data, { toId: "string" }))
					return callback("Invalid parameters.");

				database.copyPad(socket.padId, data.toId, callback);
			}*/
		};

		for(var i in handlers)
			socket.on(i, handlers[i]);
	});
});

function _sendData(socket, eventName, err, data) {
	if(err) {
		console.warn("_sendData", err, err.stack);
		return socket.emit("error", err);
	}

	socket.emit(eventName, data);
}

function _sendStreamData(socket, eventName, stream) {
	stream.on("data", function(data) {
		if(data != null)
			socket.emit(eventName, data);
	}).on("error", function(err) {
		console.warn("_sendStreamData", err, err.stack);
		socket.emit("error", err);
	})
}<commit_msg>Fixing loss of line width control in type field dropdown<commit_after>var http = require("http");
var socketIo = require("socket.io");
var config = require("../config");
var listeners = require("./listeners");
var database = require("./database");
var domain = require("domain");
var utils = require("./utils");
var routing = require("./routing");

Object.defineProperty(Error.prototype, "toJSON", {
	value: function() {
		return this.message;
	},
	configurable: true
});

database.connect(function(err) {
	if(err)
		throw err;

	var app = http.createServer();
	app.listen(config.port, config.host);
	var io = socketIo.listen(app);

	io.sockets.on("connection", function(socket) {
		var d = domain.create();
		d.add(socket);

		var handlers = {
			error : function(err) {
				console.error("Error! Disconnecting client.");
				console.error(err.stack);
				socket.disconnect();
			},

			setPadId : function(padId) {
				if(typeof padId != "string" || socket.padId != null)
					return;

				socket.padId = true;

				database.getPadData(padId, function(err, data) {
					if(err)
						return _sendData(socket, "padData", err);

					socket.padId = data.id;
					socket.writable = data.writable;
					listeners.addPadListener(socket);

					_sendData(socket, "padData", null, data);
					_sendStreamData(socket, "view", database.getViews(socket.padId));
					_sendStreamData(socket, "type", database.getTypes(socket.padId));
					_sendStreamData(socket, "line", database.getPadLines(socket.padId));

					if(socket.bbox) { // In case bbox is set while fetching pad data
						_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, socket.bbox));
						_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, socket.bbox));
					}
				});
			},

			updateBbox : function(bbox) {
				if(!utils.stripObject(bbox, { top: "number", left: "number", bottom: "number", right: "number", zoom: "number" }))
					return;

				var bboxWithExcept = utils.extend({ }, bbox);
				if(socket.bbox && bbox.zoom == socket.bbox.zoom)
					bboxWithExcept.except = socket.bbox;

				socket.bbox = bbox;

				if(socket.padId && socket.padId !== true) {
					_sendStreamData(socket, "marker", database.getPadMarkers(socket.padId, bboxWithExcept));
					_sendStreamData(socket, "linePoints", database.getLinePoints(socket.padId, bboxWithExcept));
				}
			},

			disconnect : function() {
				if(socket.padId)
					listeners.removePadListener(socket);
			},

			editPad : function(data, callback) {
				if(!utils.stripObject(data, { name: "string", defaultViewId: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updatePadData(socket.padId, data, callback);
			},

			addMarker : function(data, callback) {
				if(!utils.stripObject(data, { lat: "number", lon: "number", name: "string", colour: "string", typeId: "number", data: Object } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createMarker(socket.padId, data, callback);
			},

			editMarker : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", lat: "number", lon: "number", name: "string", colour: "string", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateMarker(data.id, data, callback);
			},

			deleteMarker : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteMarker(data.id, callback);
			},

			getLineTemplate : function(data, callback) {
				if(!utils.stripObject(data, { typeId: "number" }) || data.typeId == null)
					return callback("Invalid parameters.");

				database.getLineTemplate(data, callback);
			},

			addLine : function(data, callback) {
				if(!utils.stripObject(data, { points: [ { lat: "number", lon: "number" } ], mode: "string", colour: "string", width: "number", name: "string", typeId: "number", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createLine(socket.padId, data, callback);
			},

			editLine : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", points: [ { lat: "number", lon: "number" } ], mode: "string", colour: "string", width: "number", name: "string", data: Object }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateLine(data.id, data, callback);
			},

			deleteLine : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteLine(data.id, callback);
			},

			addView : function(data, callback) {
				if(!utils.stripObject(data, { name: "string", baseLayer: "string", layers: [ "string" ], top: "number", left: "number", right: "number", bottom: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createView(socket.padId, data, callback);
			},

			editView : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", baseLayer: "string", layers: [ "string" ], top: "number", left: "number", right: "number", bottom: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateView(data.id, data, callback);
			},

			deleteView : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteView(data.id, callback);
			},

			addType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", name: "string", type: "string", fields: [ { name: "string", type: "string", default: "string", controlColour: "boolean", controlWidth: "boolean", options: [ { key: "string", value: "string", colour: "string", width: "number" } ] }] } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.createType(socket.padId, data, callback);
			},

			editType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number", name: "string", fields: [ { name: "string", type: "string", default: "string", controlColour: "boolean", controlWidth: "boolean", options: [ { key: "string", value: "string", colour: "string", width: "number" } ] }] } ))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.updateType(data.id, data, callback);
			},

			deleteType : function(data, callback) {
				if(!utils.stripObject(data, { id: "number" }))
					return callback("Invalid parameters.");

				if(!socket.writable)
					return callback("In read-only mode.");

				database.deleteType(data.id, callback);
			}/*,

			copyPad : function(data, callback) {
				if(!utils.stripObject(data, { toId: "string" }))
					return callback("Invalid parameters.");

				database.copyPad(socket.padId, data.toId, callback);
			}*/
		};

		for(var i in handlers)
			socket.on(i, handlers[i]);
	});
});

function _sendData(socket, eventName, err, data) {
	if(err) {
		console.warn("_sendData", err, err.stack);
		return socket.emit("error", err);
	}

	socket.emit(eventName, data);
}

function _sendStreamData(socket, eventName, stream) {
	stream.on("data", function(data) {
		if(data != null)
			socket.emit(eventName, data);
	}).on("error", function(err) {
		console.warn("_sendStreamData", err, err.stack);
		socket.emit("error", err);
	})
}<|endoftext|>


<commit_before>/* jslint node: true */
"use strict";

var Promise = require('promise');
var get = Promise.denodeify(require('request').get);
var post = Promise.denodeify(require('request').post);
var xml2js = require('xml2js');
var iconv = require('iconv-lite');
var _ = require('lodash');
var global_config = require(process.cwd() + '/config');

var config = {
  lightstream_url: 'http://localhost:' + global_config.api.port + '/api/items/station?api_key=' + global_config.api.key,
  velomagg_url: global_config.crawler.velomagg_url
};

var parser = new xml2js.Parser();

var stations = {};
var fake = process.argv.reduce(function (exists, argument) {
  exists |= argument === '--fake';
  return exists;
}, false);

function fakeData(station) {
  if (fake && station.id === 18) {
    station.available_bikes = Math.round(Math.random() * station.total);
    station.free_slots = station.total - station.available_bikes;
    station.fake = true;
  }
}

function mapStation(si) {
  return {
    id: parseInt(si.$.id, 10),
    name: si.$.na.replace(/\d+ (.*)/g, '$1'),
    lat: parseFloat(si.$.la),
    lon: parseFloat(si.$.lg),
    available_bikes: parseInt(si.$.av, 10),
    free_slots: parseInt(si.$.fr, 10),
    total: parseInt(si.$.to, 10),
    credit_card: si.$.cb && si.$.cb === '1',
    date: new Date().toISOString()
  };
}

function filterStation(station) {
  fakeData(station);
  return !_.isEqual(stations[station.id], station, function (value, other) {
    if (/\d{4}-\d{2}-\d{2}/g.test(value)) {
      return true;
    }
  });
}

function sendToLightstream(station) {
  var body = {
    item: {
      geojson: {
        type: 'Point',
        coordinates: [station.lon, station.lat]
      },
      data: station
    }
  };
  post({
    url: config.lightstream_url,
    body: body,
    json: true
  }).then(function (response) {
    if (response.statusCode !== 200) {
      throw new Error(response.statusCode + ' : ' + (response.body.message || 'unknown error'))
    }
    stations[station.id] = station;
    console.log('station updated: ' + station.id);
  }).catch(function (error) {
    console.log(error);
  });
}

parser.addListener('end', function(result) {
  result.vcs.sl[0].si
    .map(mapStation)
    .filter(filterStation)
    .forEach(sendToLightstream);
});

setInterval(function () {
  console.log('loading...');
  get({
    url: config.velomagg_url,
    encoding: null
  }).then(function (response) {
    console.log('response loaded.');
    if (response.statusCode === 200) {
      parser.parseString(iconv.decode(response.body, 'win1252'));
    }
  });
}, 2000);
<commit_msg>comment verbose logs in crawler<commit_after>/* jslint node: true */
"use strict";

var Promise = require('promise');
var get = Promise.denodeify(require('request').get);
var post = Promise.denodeify(require('request').post);
var xml2js = require('xml2js');
var iconv = require('iconv-lite');
var _ = require('lodash');
var global_config = require(process.cwd() + '/config');

var config = {
  lightstream_url: 'http://localhost:' + global_config.api.port + '/api/items/station?api_key=' + global_config.api.key,
  velomagg_url: global_config.crawler.velomagg_url
};

var parser = new xml2js.Parser();

var stations = {};
var fake = process.argv.reduce(function (exists, argument) {
  exists |= argument === '--fake';
  return exists;
}, false);

function fakeData(station) {
  if (fake && station.id === 18) {
    station.available_bikes = Math.round(Math.random() * station.total);
    station.free_slots = station.total - station.available_bikes;
    station.fake = true;
  }
}

function mapStation(si) {
  return {
    id: parseInt(si.$.id, 10),
    name: si.$.na.replace(/\d+ (.*)/g, '$1'),
    lat: parseFloat(si.$.la),
    lon: parseFloat(si.$.lg),
    available_bikes: parseInt(si.$.av, 10),
    free_slots: parseInt(si.$.fr, 10),
    total: parseInt(si.$.to, 10),
    credit_card: si.$.cb && si.$.cb === '1',
    date: new Date().toISOString()
  };
}

function filterStation(station) {
  fakeData(station);
  return !_.isEqual(stations[station.id], station, function (value, other) {
    if (/\d{4}-\d{2}-\d{2}/g.test(value)) {
      return true;
    }
  });
}

function sendToLightstream(station) {
  var body = {
    item: {
      geojson: {
        type: 'Point',
        coordinates: [station.lon, station.lat]
      },
      data: station
    }
  };
  post({
    url: config.lightstream_url,
    body: body,
    json: true
  }).then(function (response) {
    if (response.statusCode !== 200) {
      throw new Error(response.statusCode + ' : ' + (response.body.message || 'unknown error'))
    }
    stations[station.id] = station;
    //console.log('station updated: ' + station.id);
  }).catch(function (error) {
    console.log(error);
  });
}

parser.addListener('end', function(result) {
  result.vcs.sl[0].si
    .map(mapStation)
    .filter(filterStation)
    .forEach(sendToLightstream);
});

setInterval(function () {
  //console.log('loading...');
  get({
    url: config.velomagg_url,
    encoding: null
  }).then(function (response) {
    //console.log('response loaded.');
    if (response.statusCode === 200) {
      parser.parseString(iconv.decode(response.body, 'win1252'));
    }
  });
}, 2000);
<|endoftext|>


<commit_before>var d2l = {

	jasmine: {

		_private: {

			compareStyle: function( node, property, expected ) {

				if ( !node ) {
					return { pass: false, message: 'The node value is not defined.' };
				}
				if ( !expected ) {
					return { pass: false, message: 'The expected value is not defined.' };
				}

				var val = window.getComputedStyle( node, null ).getPropertyValue( property );
				if ( val === expected ) {
					return { pass: true };
				} else {
					return { pass: false, message: 'Expected to find ' + expected + ' but found ' + val + '.' };
				}

			}

		},

		matchers: {

			toHaveCssSelector: function() {
				return {
					compare: function( doc, expected ) {

						if ( !doc ) {
							return { pass: false, message: 'The document value is not defined.' };
						}
						if ( !expected ) {
							return { pass: false, message: 'The expected value is not defined.' };
						}

						for ( var i=0; i<doc.styleSheets.length; ++i ) {
							for ( var j=0; j<doc.styleSheets[i].cssRules.length; ++j ) {
								var selectors = doc.styleSheets[i].cssRules[j].selectorText.split( ',' );
								for ( var k=0; k<selectors.length; k++ ) {
									if ( selectors[k].replace( /(^\s+|\s+$)/g,'' ) === expected ) {
										return { pass: true };
									}
								}
							}
						}

						return { pass: false, message: 'Expected to find ' + expected + ' css selector but did not.' };

					}
				};
			},

			toHaveFontWeight: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'font-weight', expected
							);
					}
				};
			},

			toHaveRgbColor: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'color', expected
							);
					}
				};
			},

			toHaveTextDecoration: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'text-decoration', expected
							);
					}
				};
			}

		}

	}

};<commit_msg>Rename matcher.<commit_after>var d2l = {

	jasmine: {

		_private: {

			compareStyle: function( node, property, expected ) {

				if ( !node ) {
					return { pass: false, message: 'The node value is not defined.' };
				}
				if ( !expected ) {
					return { pass: false, message: 'The expected value is not defined.' };
				}

				var val = window.getComputedStyle( node, null ).getPropertyValue( property );
				if ( val === expected ) {
					return { pass: true };
				} else {
					return { pass: false, message: 'Expected to find ' + expected + ' but found ' + val + '.' };
				}

			}

		},

		matchers: {

			toHaveCssSelector: function() {
				return {
					compare: function( doc, expected ) {

						if ( !doc ) {
							return { pass: false, message: 'The document value is not defined.' };
						}
						if ( !expected ) {
							return { pass: false, message: 'The expected value is not defined.' };
						}

						for ( var i=0; i<doc.styleSheets.length; ++i ) {
							for ( var j=0; j<doc.styleSheets[i].cssRules.length; ++j ) {
								var selectors = doc.styleSheets[i].cssRules[j].selectorText.split( ',' );
								for ( var k=0; k<selectors.length; k++ ) {
									if ( selectors[k].replace( /(^\s+|\s+$)/g,'' ) === expected ) {
										return { pass: true };
									}
								}
							}
						}

						return { pass: false, message: 'Expected to find ' + expected + ' css selector but did not.' };

					}
				};
			},

			toHaveColor: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'color', expected
							);
					}
				};
			},

			toHaveFontWeight: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'font-weight', expected
							);
					}
				};
			},

			toHaveTextDecoration: function() {
				return {
					compare: function( node, expected ) {
						return d2l.jasmine._private.compareStyle(
								node, 'text-decoration', expected
							);
					}
				};
			}

		}

	}

};<|endoftext|>


<commit_before>// ==UserScript==
// @name         Bancolombia password
// @namespace    http://federicojm.com/
// @version      0.1
// @description  Submit password filled by password manager.
// @author       Federico JM
// @match        https://sucursalpersonas.transaccionesbancolombia.com/mua/VALIDATEPASSWORD
// @grant        none
// @run-at       document-end
// ==/UserScript==

/* - jshint settings - */
/* globals collect, clearKeys, inspect, enviar */

(function ($) {
    'use strict';

    // jQuery is loaded by Bancolombia.
    if (typeof $ === "undefined") {
        return false;
    }

    // Password manager fills password field.
    // Bancolombia uses an onscreen keyboard that fails with password managers.
    // Simulate clicking each number and submit.
    $('#password').change(function() {
        var password = $(this).val();

        // Bancolombia sets a timeout for collect().
        // Run it if necessary.
        if (typeof dom_data_collection === "undefined") {
            collect();
        }

        if (password.length === 4) {
            clearKeys();
            for (var i = 0, len = password.length; i < len; i++) {
                $('#keyboard_ div:contains("' + password[i] + '")').parent().click();
            }
            inspect();
            enviar();
        }
    });
})(window.jQuery);
<commit_msg>Enable 2nd password autosubmit<commit_after>// ==UserScript==
// @name         Bancolombia password
// @namespace    http://federicojm.com/
// @version      0.2
// @description  Submit password filled by password manager.
// @author       Federico JM
// @match        https://sucursalpersonas.transaccionesbancolombia.com/mua/VALIDATEPASSWORD
// @match        https://sucursalpersonas.transaccionesbancolombia.com/cb/pages/jsp/home/index.jsp
// @grant        none
// @run-at       document-end
// ==/UserScript==

/* - jshint settings - */
/* globals collect, clearKeys, inspect, enviar */

(function ($) {
    'use strict';

    // jQuery is loaded by Bancolombia.
    if (typeof $ === "undefined") {
        return false;
    }

    // Password manager fills password field.
    // Bancolombia uses an onscreen keyboard that fails with password managers.
    // Simulate clicking each number and submit.
    $(document).on('change', "#password", function() {
        var password = $(this).val();

        // Bancolombia sets a timeout for collect().
        // Run it if necessary.
        // Only available on first password.
        if (window.collect !== undefined && typeof dom_data_collection === "undefined") {
            collect();
        }

        if (password.length === 4) {
            clearKeys();
            for (var i = 0, len = password.length; i < len; i++) {
                $('#keyboard_ div:contains("' + password[i] + '")').parent().click();
            }
            // Only available on first password.
            if (window.inspect !== undefined) {
                inspect();
            }
            enviar();
        }
    });
})(window.jQuery);
<|endoftext|>


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

var Moment = require('moment'),
    Crypto = require('crypto'),
    helpers = require('./helpers.js'),
    signV4 = (request, dataShaSum256, accessKey, secretKey) => {
      if (!accessKey || !secretKey) {
        return
      }
      var requestDate = Moment().utc()
      if (!dataShaSum256) {
        dataShaSum256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
      }

      if (!request.headers) {
        request.headers = {}
      }

      var region = helpers.getRegion(request.host),
          host = request.host

      if ((request.scheme === 'http' && request.port !== 80) || (request.scheme === 'https' && request.port !== 443)) {
        host = `${host}:${request.port}`
      }

      request.headers.host = host
      request.headers['x-amz-date'] = requestDate.format('YYYYMMDDTHHmmss') + 'Z'
      request.headers['x-amz-content-sha256'] = dataShaSum256

      var canonicalRequestAndSignedHeaders = getCanonicalRequest(request, dataShaSum256),
          canonicalRequest = canonicalRequestAndSignedHeaders[0],
          signedHeaders = canonicalRequestAndSignedHeaders[1],
          hash = Crypto.createHash('sha256')

      hash.update(canonicalRequest)

      var canonicalRequestHash = hash.digest('hex'),
          stringToSign = getStringToSign(canonicalRequestHash, requestDate, region),
          signingKey = getSigningKey(requestDate, region, secretKey),
          hmac = Crypto.createHmac('sha256', signingKey)

      hmac.update(stringToSign)

      var signedRequest = hmac.digest('hex').toLowerCase().trim(),
          credentials = `${accessKey}/${requestDate.format('YYYYMMDD')}/${region}/s3/aws4_request`,
          authorization = `Credential=${credentials}, SignedHeaders=${signedHeaders}, Signature=${signedRequest}`

      request.headers.authorization = 'AWS4-HMAC-SHA256' + authorization

      function getSigningKey(date, region, secretKey) {
        var key = 'AWS4' + secretKey,
            dateLine = date.format('YYYYMMDD'),
            hmac1 = Crypto.createHmac('sha256', key).update(dateLine).digest('binary'),
            hmac2 = Crypto.createHmac('sha256', hmac1).update(region).digest('binary'),
            hmac3 = Crypto.createHmac('sha256', hmac2).update('s3').digest('binary')
        return Crypto.createHmac('sha256', hmac3).update('aws4_request').digest('binary')
      }

      function getCanonicalRequest(request, dataShaSum1) {
        var headerKeys = [],
            headers = [],
            ignoredHeaders = ['Authorization', 'Content-Length', 'Content-Type', 'User-Agent']

        // Excerpts from @lsegal - https://github.com/aws/aws-sdk-js/issues/659#issuecomment-120477258
        //
        //  User-Agent:
        //
        //      This is ignored from signing because signing this causes problems with generating pre-signed URLs
        //      (that are executed by other agents) or when customers pass requests through proxies, which may
        //      modify the user-agent.
        //
        //  Content-Length:
        //
        //      This is ignored from signing because generating a pre-signed URL should not provide a content-length
        //      constraint, specifically when vending a S3 pre-signed PUT URL. The corollary to this is that when
        //      sending regular requests (non-pre-signed), the signature contains a checksum of the body, which
        //      implicitly validates the payload length (since changing the number of bytes would change the checksum)
        //      and therefore this header is not valuable in the signature.
        //
        //  Content-Type:
        //
        //      Signing this header causes quite a number of problems in browser environments, where browsers
        //      like to modify and normalize the content-type header in different ways. There is more information
        //      on this in https://github.com/aws/aws-sdk-js/issues/244. Avoiding this field simplifies logic
        //      and reduces the possibility of future bugs
        //
        //  Authorization:
        //
        //      Is skipped for obvious reasons

        for (var key in request.headers) {
          if (request.headers.hasOwnProperty(key) && ignoredHeaders.indexOf(key) === -1) {
            var value = request.headers[key]
            headers.push(`${key.toLowerCase()}:${value}`)
            headerKeys.push(key.toLowerCase())
          }
        }

        headers.sort()
        headerKeys.sort()

        var signedHeaders = ''
        headerKeys.forEach(element => {
          if (signedHeaders) {
            signedHeaders += ';'
          }
          signedHeaders += element
        })

        var splitPath = request.path.split('?'),
            requestResource = splitPath[0],
            requestQuery = ''

        if (splitPath.length === 2) {
          requestQuery = splitPath[1]
            .split('&')
            .sort()
            .map(element => {
              if (element.indexOf('=') === -1) {
                element = element + '='
              }
              return element
            })
            .join('&')
        }

        var canonicalString = ''
        canonicalString += canonicalString + request.method.toUpperCase() + '\n'
        canonicalString += requestResource + '\n'
        canonicalString += requestQuery + '\n'
        headers.forEach(element => {
          canonicalString += element + '\n'
        })
        canonicalString += '\n'
        canonicalString += signedHeaders + '\n'
        canonicalString += dataShaSum1
        return [canonicalString, signedHeaders]
      }
    }, getStringToSign = function(canonicalRequestHash, requestDate, region) {
      var stringToSign = 'AWS4-HMAC-SHA256\n'
      stringToSign += requestDate.format('YYYYMMDDTHHmmss') + 'Z\n'
      stringToSign += `${requestDate.format('YYYYMMDD')}/${region}/s3/aws4_request\n`
      stringToSign += canonicalRequestHash
      return stringToSign
    }

module.exports = signV4
<commit_msg>There should be space after AWS4-HMAC-SHA256 in the authorization header. Having no space caused auth failure.<commit_after>/*
 * Minio Javascript Library for Amazon S3 compatible cloud storage, (C) 2016 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Moment = require('moment'),
    Crypto = require('crypto'),
    helpers = require('./helpers.js'),
    signV4 = (request, dataShaSum256, accessKey, secretKey) => {
      if (!accessKey || !secretKey) {
        return
      }
      var requestDate = Moment().utc()
      if (!dataShaSum256) {
        dataShaSum256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
      }

      if (!request.headers) {
        request.headers = {}
      }

      var region = helpers.getRegion(request.host),
          host = request.host

      if ((request.scheme === 'http' && request.port !== 80) || (request.scheme === 'https' && request.port !== 443)) {
        host = `${host}:${request.port}`
      }

      request.headers.host = host
      request.headers['x-amz-date'] = requestDate.format('YYYYMMDDTHHmmss') + 'Z'
      request.headers['x-amz-content-sha256'] = dataShaSum256

      var canonicalRequestAndSignedHeaders = getCanonicalRequest(request, dataShaSum256),
          canonicalRequest = canonicalRequestAndSignedHeaders[0],
          signedHeaders = canonicalRequestAndSignedHeaders[1],
          hash = Crypto.createHash('sha256')

      hash.update(canonicalRequest)

      var canonicalRequestHash = hash.digest('hex'),
          stringToSign = getStringToSign(canonicalRequestHash, requestDate, region),
          signingKey = getSigningKey(requestDate, region, secretKey),
          hmac = Crypto.createHmac('sha256', signingKey)

      hmac.update(stringToSign)

      var signedRequest = hmac.digest('hex').toLowerCase().trim(),
          credentials = `${accessKey}/${requestDate.format('YYYYMMDD')}/${region}/s3/aws4_request`,
          authorization = `Credential=${credentials}, SignedHeaders=${signedHeaders}, Signature=${signedRequest}`

      request.headers.authorization = 'AWS4-HMAC-SHA256 ' + authorization

      function getSigningKey(date, region, secretKey) {
        var key = 'AWS4' + secretKey,
            dateLine = date.format('YYYYMMDD'),
            hmac1 = Crypto.createHmac('sha256', key).update(dateLine).digest('binary'),
            hmac2 = Crypto.createHmac('sha256', hmac1).update(region).digest('binary'),
            hmac3 = Crypto.createHmac('sha256', hmac2).update('s3').digest('binary')
        return Crypto.createHmac('sha256', hmac3).update('aws4_request').digest('binary')
      }

      function getCanonicalRequest(request, dataShaSum1) {
        var headerKeys = [],
            headers = [],
            ignoredHeaders = ['Authorization', 'Content-Length', 'Content-Type', 'User-Agent']

        // Excerpts from @lsegal - https://github.com/aws/aws-sdk-js/issues/659#issuecomment-120477258
        //
        //  User-Agent:
        //
        //      This is ignored from signing because signing this causes problems with generating pre-signed URLs
        //      (that are executed by other agents) or when customers pass requests through proxies, which may
        //      modify the user-agent.
        //
        //  Content-Length:
        //
        //      This is ignored from signing because generating a pre-signed URL should not provide a content-length
        //      constraint, specifically when vending a S3 pre-signed PUT URL. The corollary to this is that when
        //      sending regular requests (non-pre-signed), the signature contains a checksum of the body, which
        //      implicitly validates the payload length (since changing the number of bytes would change the checksum)
        //      and therefore this header is not valuable in the signature.
        //
        //  Content-Type:
        //
        //      Signing this header causes quite a number of problems in browser environments, where browsers
        //      like to modify and normalize the content-type header in different ways. There is more information
        //      on this in https://github.com/aws/aws-sdk-js/issues/244. Avoiding this field simplifies logic
        //      and reduces the possibility of future bugs
        //
        //  Authorization:
        //
        //      Is skipped for obvious reasons

        for (var key in request.headers) {
          if (request.headers.hasOwnProperty(key) && ignoredHeaders.indexOf(key) === -1) {
            var value = request.headers[key]
            headers.push(`${key.toLowerCase()}:${value}`)
            headerKeys.push(key.toLowerCase())
          }
        }

        headers.sort()
        headerKeys.sort()

        var signedHeaders = ''
        headerKeys.forEach(element => {
          if (signedHeaders) {
            signedHeaders += ';'
          }
          signedHeaders += element
        })

        var splitPath = request.path.split('?'),
            requestResource = splitPath[0],
            requestQuery = ''

        if (splitPath.length === 2) {
          requestQuery = splitPath[1]
            .split('&')
            .sort()
            .map(element => {
              if (element.indexOf('=') === -1) {
                element = element + '='
              }
              return element
            })
            .join('&')
        }

        var canonicalString = ''
        canonicalString += canonicalString + request.method.toUpperCase() + '\n'
        canonicalString += requestResource + '\n'
        canonicalString += requestQuery + '\n'
        headers.forEach(element => {
          canonicalString += element + '\n'
        })
        canonicalString += '\n'
        canonicalString += signedHeaders + '\n'
        canonicalString += dataShaSum1
        return [canonicalString, signedHeaders]
      }
    }, getStringToSign = function(canonicalRequestHash, requestDate, region) {
      var stringToSign = 'AWS4-HMAC-SHA256\n'
      stringToSign += requestDate.format('YYYYMMDDTHHmmss') + 'Z\n'
      stringToSign += `${requestDate.format('YYYYMMDD')}/${region}/s3/aws4_request\n`
      stringToSign += canonicalRequestHash
      return stringToSign
    }

module.exports = signV4
<|endoftext|>


<commit_before>define(function(require, exports, module) {
    "use strict";

    main.consumes = [
        "Plugin", "tabManager", "menus", "commands", "settings",
        "tree", "save", "ui", "c9", "panels"
    ];
    main.provides = ["openfiles"];
    return main;

    function main(options, imports, register) {
        var Plugin   = imports.Plugin;
        var tabs     = imports.tabManager;
        var menus    = imports.menus;
        var commands = imports.commands;
        var settings = imports.settings;
        var panels   = imports.panels;
        var tree     = imports.tree;
        var save     = imports.save;
        var ui       = imports.ui;

        var Tree     = require("ace_tree/tree");
        var TreeData = require("./openfilesdp");
        var basename = require("path").basename;

        /***** Initialization *****/

        var plugin        = new Plugin("Ajax.org", main.consumes);
        var emit          = plugin.getEmitter();
        var staticPrefix  = options.staticPrefix;

        // tree maximum height
        var showOpenFiles = false;
        var defaultShow   = options.defaultShow;
        var dragged       = false;

        // UI Elements
        var ofDataProvider, ofTree, treeParent, winFileTree;
        var ctxItem, ctxDiv, preventUpdate, mnuFilesSettings, ctxItem2;

        var loaded = false;
        function load(){
            if (loaded) return false;
            loaded = true;

            // Hook events to get the focussed tab
            tabs.on("focusSync", delayedUpdate);
            // tabs.on("tabDestroy", delayedUpdate);
            tabs.on("tabAfterClose", update);
            tabs.on("tabReparent", delayedUpdate);
            tabs.on("tabOrder", delayedUpdate);

            save.on("tabSavingState", refresh);

            commands.addCommand({
                name: "toggleOpenfiles",
                exec: function() {
                    toggleOpenfiles();
                }
            }, plugin);

            menus.addItemByPath("View/Open Files", new ui.item({
                type    : "check",
                checked : "user/openfiles/@show"
                // command : "toggleOpenfiles"
            }), 200, plugin);

            settings.on("read", function(e){
                // Defaults
                settings.setDefaults("user/openfiles", [
                    ["show", defaultShow],
                    ["hidetree", "false"]
                ]);
                showOpenFiles = settings.getBool("user/openfiles/@show");
                updateVisibility(showOpenFiles);
            }, plugin);

            settings.on("user/openfiles/@show", function(value){
                showOpenFiles = value;
                updateVisibility(showOpenFiles);
            });

            panels.on("showPanelTree", function(){ update(); });
        }

        var drawn = false;
        function draw(){
            if (drawn) return;
            drawn = true;

            // ace_tree customization '.openfiles'
            ui.insertCss(require("text!./openfiles.css"), staticPrefix, plugin);

            tree.getElement("winOpenfiles", function(winOpenfiles) {
                treeParent = winOpenfiles;

                tree.getElement("winFileTree", function(winFileTreeL) {
                    winFileTree = winFileTreeL;
                });

                var div = document.createElement("div");
                treeParent.$int.appendChild(div);

                // Create the Ace Tree
                ofTree = new Tree(div);
                ofDataProvider = new TreeData();
                // ofTree.renderer.setScrollMargin(0, 10);
                ofTree.renderer.setTheme({cssClass: "filetree"});
                // Assign the dataprovider
                ofTree.setDataProvider(ofDataProvider);
                // Some global render metadata
                ofDataProvider.staticPrefix = staticPrefix;

                ofTree.on("userSelect", function(){
                    setTimeout(onSelect, 40);
                });

                // make sure scrollbar on windows is in the padding area
                ofTree.renderer.on("scrollbarVisibilityChanged", updateScrollBarSize);
                ofTree.renderer.on("resize", updateScrollBarSize);
                function updateScrollBarSize() {
                    var w = ofTree.renderer.scrollBarV.getWidth();
                    ofTree.renderer.scroller.style.right = Math.max(w, 10) + "px";
                }

                // APF + DOM HACK: close tab with confirmation
                ofTree.on("mousedown", function(e){
                    var domTarget = e.domEvent.target;
                    var pos = e.getDocumentPosition();
                    var node = ofDataProvider.findItemAtOffset(pos.y);

                    if (node.children && !~domTarget.className.indexOf("toggler")) {
                        e.preventDefault();
                        return;
                    }

                    if (! (node && node.path && domTarget && ~domTarget.className.indexOf("close")))
                        return;

                    var amlTab = node.tab.aml;
                    amlTab.parentNode.remove(amlTab, {});
                });

                ofTree.focus = function() {};

                ofTree.renderer.on("autoresize", function() {
                    updateHeight();
                });

                ofTree.setOption("maxLines", 100);
                ofTree.renderer.getMaxHeight = function () {
                    return Math.floor(treeParent.parentNode.$int.offsetHeight * 0.5 - 23);
                };

                mnuFilesSettings = tree.getElement("mnuFilesSettings");
                ctxItem = ui.insertByIndex(mnuFilesSettings, new ui.item({
                    caption : "Hide Workspace Files",
                    type    : "check",
                    visible : treeParent.visible,
                    checked : "state/openfiles/@hidetree",
                    onclick : function(e){
                        hideTree(this.checked)
                    }
                }), 195, plugin);
                ctxItem2 = ui.insertByIndex(mnuFilesSettings, new ui.item({
                    caption : "Show Open Files",
                    type    : "check",
                    checked : "user/openfiles/@show",
                    command : "toggleOpenfiles"
                }), 190, plugin);
                ctxDiv = ui.insertByIndex(mnuFilesSettings,
                    new ui.divider(), 185, plugin);

                if (showOpenFiles) {
                    tabs.on("ready", function(){ show(); });

                    if (settings.getBool("state/openfiles/@hidetree"))
                        hideTree(true);
                }
                else
                    hideOpenFiles();

                emit("draw");
            });
        }

        /***** Methods *****/

        function hideTree(state){
            settings.set("state/openfiles/@hidetree", state);

            if (treeParent) {
                if (state)
                    ui.setStyleClass(treeParent.parentNode.$int, "hidetree");
                else
                    ui.setStyleClass(treeParent.parentNode.$int, "", ["hidetree"]);
            }

            if (mnuFilesSettings) {
                mnuFilesSettings.childNodes.forEach(function(node){
                    if (node.$position >= 200) {
                        node.setAttribute("visible", !state);
                    }
                });
            }

            if (ofTree) {
                ofTree.resize();
                tree.resize();
            }
        }

        var updateTimer;
        function delayedUpdate() {
            if (updateTimer)
                return;
            updateTimer = setTimeout(function() {
                updateTimer = null;
                update();
            }, 10);
        }

        function update() {
            if (!showOpenFiles)
                return;

            if (!panels.isActive("tree"))
                return;

            draw();

            if (!ofTree)
                return;

            preventUpdate = true;

            var activePanes = tabs.getPanes(tabs.container);
            var focussedTab = tabs.focussedTab;
            // focussedTab can be the terminal or output views
            if (focussedTab && activePanes.indexOf(focussedTab.pane) === -1
              && activePanes.length)
                focussedTab = activePanes[0].getTab();

            // unhook document change update listeners
            tabs.getTabs().forEach(function (tab) {
                tab.document && tab.document.off("changed", refresh);
            });

            var selected;
            var root = { groups: [] };
            var actualRoot = {
                children : [
                    {
                        label     : "open files",
                        path      : "!openfiles",
                        isOpen    : true,
                        className : "heading",
                        isRoot    : true,
                        isFolder  : true,
                        status    : "loaded",
                        map       : {},
                        children  : root.groups,
                        noSelect  : true
                    }
                ]
            };

            var oldRoot = ofDataProvider && ofDataProvider.root;
            var existing = oldRoot && oldRoot.groups || {};
            root.children = activePanes.map(function(pane, i) {
                var group = existing[i] || { isOpen: true, className: "group" };
                if (group.isOpen == "forced")
                    group.isOpen = false;
                root.groups[i] = group;
                group.children = null;
                // name: pane.name (tab0 ...)
                group.children =  pane.getTabs()
                    .filter(function(tab){
                        return tab.path && tab.loaded && !tab.meta.$closing;
                    })
                    .map(function(tab) {
                        var node = {
                            name : basename(tab.path),
                            path : tab.path,
                            tab  : tab
                        };
                        if (tab == focussedTab) {
                            selected = node;
                            group.isOpen = "forced";
                        }

                        tab.document.on("changed", refresh);
                        return node;
                    });
                return group;
            }).filter(function(pane){
                return pane.children.length;
            }).map(function (node, i) {
                node.name = "GROUP " + (i+1);
                return node;
            });

            // Hide the openfiles
            if (!root.children.length) {
                preventUpdate = false;
                return hideOpenFiles();
            }

            ui.setStyleClass(treeParent.parentNode.$int, "hasopenfiles");

            treeParent.show();

            if (root.children.length === 1)
                actualRoot.children[0].children = root.children[0].children;

            ofDataProvider.setRoot(actualRoot);
            ofDataProvider.selection.selectNode(selected);

            updateHeight();
        }

        function updateHeight(selected){
            preventUpdate = true;

            var maxHeight = treeParent.parentNode.$int.offsetHeight * 0.5;
            var treeHeight = ofTree.renderer.desiredHeight + 23;

            treeParent.$int.style.height = dragged
                ? Math.min(treeParent.getHeight(), treeHeight) + "px"
                : Math.min(treeHeight, maxHeight) + "px";

            // ofTree.resize(true);
            tree.resize();

            if (!selected)
                selected = ofTree.selectedNode;

            ofTree.renderer.scrollCaretIntoView(selected, 0.5);

            preventUpdate = false;
        }

        function refresh() {
            if (!showOpenFiles || !ofDataProvider)
                return;
            ofDataProvider._signal("change");
        }

        function onSelect() {
            var node = ofTree.selection.getCursor();
            if (node && tabs.focussedTab && tabs.focussedTab.path != node.path)
                tabs.focusTab(node.path);
        }

        function hideOpenFiles() {
            var htmlNode = treeParent && treeParent.parentNode.$int;
            htmlNode && ui.setStyleClass(htmlNode, "", ["hasopenfiles"]);
            treeParent && treeParent.hide();
            tree.resize();
        }

        function toggleOpenfiles() {
            showOpenFiles = !showOpenFiles;
            settings.set("user/openfiles/@show", showOpenFiles);
            updateVisibility(showOpenFiles);
        }

        function updateVisibility(show) {
            if (show) {
                draw();
                update();
                ctxItem && ctxItem.show();

                if (settings.getBool("state/openfiles/@hidetree"))
                    hideTree(true);

                if (!panels.isActive("tree")) {
                    panels.once("showPanelTree", function(){
                        ofTree.resize(true);
                        tree.resize(true);
                    });

                    panels.activate("tree");
                }
            }
            else {
                hideOpenFiles();
                ctxItem && ctxItem.hide();

                if (treeParent)
                    hideTree(false);
            }

            emit("visible", { value: show });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
            loaded = false;
            drawn  = false;
        });

        function show() {
            updateVisibility(true);
        }

        function hide() {
            updateVisibility(false);
        }

        /***** Register and define API *****/

        /**
         * Displays the open files above the tree.
         *
         * @singleton
         */
        plugin.freezePublicAPI({
            /**
             * Show the openfiles panel
             */
            show: show,

            /**
             * Hide the openfiles panel
             */
            hide: hide,

            /**
             * Trigger a complete update of the openfiles view, only when the
             * openfiles panel is visible.
             */
            update: update,

            /**
             * Rerender the viewed part of the tree without having to recreate
             * the tree data.
             * Example usage: when the saving state or document content changed
             * Only applies when openfiles is visible
             */
            refresh: refresh,

            /**
             *
             */
            showTree: hideTree.bind(null, false),

            /**
             *
             */
            hideTree: hideTree.bind(null, true)
        });

        register(null, {
            openfiles: plugin
        });
    }
});
<commit_msg>Prevent recursion in the other open files menu as well<commit_after>define(function(require, exports, module) {
    "use strict";

    main.consumes = [
        "Plugin", "tabManager", "menus", "commands", "settings",
        "tree", "save", "ui", "c9", "panels"
    ];
    main.provides = ["openfiles"];
    return main;

    function main(options, imports, register) {
        var Plugin   = imports.Plugin;
        var tabs     = imports.tabManager;
        var menus    = imports.menus;
        var commands = imports.commands;
        var settings = imports.settings;
        var panels   = imports.panels;
        var tree     = imports.tree;
        var save     = imports.save;
        var ui       = imports.ui;

        var Tree     = require("ace_tree/tree");
        var TreeData = require("./openfilesdp");
        var basename = require("path").basename;

        /***** Initialization *****/

        var plugin        = new Plugin("Ajax.org", main.consumes);
        var emit          = plugin.getEmitter();
        var staticPrefix  = options.staticPrefix;

        // tree maximum height
        var showOpenFiles = false;
        var defaultShow   = options.defaultShow;
        var dragged       = false;

        // UI Elements
        var ofDataProvider, ofTree, treeParent, winFileTree;
        var ctxItem, ctxDiv, preventUpdate, mnuFilesSettings, ctxItem2;

        var loaded = false;
        function load(){
            if (loaded) return false;
            loaded = true;

            // Hook events to get the focussed tab
            tabs.on("focusSync", delayedUpdate);
            // tabs.on("tabDestroy", delayedUpdate);
            tabs.on("tabAfterClose", update);
            tabs.on("tabReparent", delayedUpdate);
            tabs.on("tabOrder", delayedUpdate);

            save.on("tabSavingState", refresh);

            commands.addCommand({
                name: "toggleOpenfiles",
                exec: function() {
                    toggleOpenfiles();
                }
            }, plugin);

            menus.addItemByPath("View/Open Files", new ui.item({
                type    : "check",
                checked : "user/openfiles/@show"
                // command : "toggleOpenfiles"
            }), 200, plugin);

            settings.on("read", function(e){
                // Defaults
                settings.setDefaults("user/openfiles", [
                    ["show", defaultShow],
                    ["hidetree", "false"]
                ]);
                showOpenFiles = settings.getBool("user/openfiles/@show");
                updateVisibility(showOpenFiles);
            }, plugin);

            settings.on("user/openfiles/@show", function(value){
                showOpenFiles = value;
                updateVisibility(showOpenFiles);
            });

            panels.on("showPanelTree", function(){ update(); });
        }

        var drawn = false;
        function draw(){
            if (drawn) return;
            drawn = true;

            // ace_tree customization '.openfiles'
            ui.insertCss(require("text!./openfiles.css"), staticPrefix, plugin);

            tree.getElement("winOpenfiles", function(winOpenfiles) {
                treeParent = winOpenfiles;

                tree.getElement("winFileTree", function(winFileTreeL) {
                    winFileTree = winFileTreeL;
                });

                var div = document.createElement("div");
                treeParent.$int.appendChild(div);

                // Create the Ace Tree
                ofTree = new Tree(div);
                ofDataProvider = new TreeData();
                // ofTree.renderer.setScrollMargin(0, 10);
                ofTree.renderer.setTheme({cssClass: "filetree"});
                // Assign the dataprovider
                ofTree.setDataProvider(ofDataProvider);
                // Some global render metadata
                ofDataProvider.staticPrefix = staticPrefix;

                ofTree.on("userSelect", function(){
                    setTimeout(onSelect, 40);
                });

                // make sure scrollbar on windows is in the padding area
                ofTree.renderer.on("scrollbarVisibilityChanged", updateScrollBarSize);
                ofTree.renderer.on("resize", updateScrollBarSize);
                function updateScrollBarSize() {
                    var w = ofTree.renderer.scrollBarV.getWidth();
                    ofTree.renderer.scroller.style.right = Math.max(w, 10) + "px";
                }

                // APF + DOM HACK: close tab with confirmation
                ofTree.on("mousedown", function(e){
                    var domTarget = e.domEvent.target;
                    var pos = e.getDocumentPosition();
                    var node = ofDataProvider.findItemAtOffset(pos.y);

                    if (node.children && !~domTarget.className.indexOf("toggler")) {
                        e.preventDefault();
                        return;
                    }

                    if (! (node && node.path && domTarget && ~domTarget.className.indexOf("close")))
                        return;

                    var amlTab = node.tab.aml;
                    amlTab.parentNode.remove(amlTab, {});
                });

                ofTree.focus = function() {};

                ofTree.renderer.on("autoresize", function() {
                    updateHeight();
                });

                ofTree.setOption("maxLines", 100);
                ofTree.renderer.getMaxHeight = function () {
                    return Math.floor(treeParent.parentNode.$int.offsetHeight * 0.5 - 23);
                };

                mnuFilesSettings = tree.getElement("mnuFilesSettings");
                ctxItem = ui.insertByIndex(mnuFilesSettings, new ui.item({
                    caption : "Hide Workspace Files",
                    type    : "check",
                    visible : treeParent.visible,
                    checked : "state/openfiles/@hidetree",
                    onclick : function(e){
                        hideTree(this.checked)
                    }
                }), 195, plugin);
                ctxItem2 = ui.insertByIndex(mnuFilesSettings, new ui.item({
                    caption : "Show Open Files",
                    type    : "check",
                    checked : "user/openfiles/@show",
                }), 190, plugin);
                ctxDiv = ui.insertByIndex(mnuFilesSettings,
                    new ui.divider(), 185, plugin);

                if (showOpenFiles) {
                    tabs.on("ready", function(){ show(); });

                    if (settings.getBool("state/openfiles/@hidetree"))
                        hideTree(true);
                }
                else
                    hideOpenFiles();

                emit("draw");
            });
        }

        /***** Methods *****/

        function hideTree(state){
            settings.set("state/openfiles/@hidetree", state);

            if (treeParent) {
                if (state)
                    ui.setStyleClass(treeParent.parentNode.$int, "hidetree");
                else
                    ui.setStyleClass(treeParent.parentNode.$int, "", ["hidetree"]);
            }

            if (mnuFilesSettings) {
                mnuFilesSettings.childNodes.forEach(function(node){
                    if (node.$position >= 200) {
                        node.setAttribute("visible", !state);
                    }
                });
            }

            if (ofTree) {
                ofTree.resize();
                tree.resize();
            }
        }

        var updateTimer;
        function delayedUpdate() {
            if (updateTimer)
                return;
            updateTimer = setTimeout(function() {
                updateTimer = null;
                update();
            }, 10);
        }

        function update() {
            if (!showOpenFiles)
                return;

            if (!panels.isActive("tree"))
                return;

            draw();

            if (!ofTree)
                return;

            preventUpdate = true;

            var activePanes = tabs.getPanes(tabs.container);
            var focussedTab = tabs.focussedTab;
            // focussedTab can be the terminal or output views
            if (focussedTab && activePanes.indexOf(focussedTab.pane) === -1
              && activePanes.length)
                focussedTab = activePanes[0].getTab();

            // unhook document change update listeners
            tabs.getTabs().forEach(function (tab) {
                tab.document && tab.document.off("changed", refresh);
            });

            var selected;
            var root = { groups: [] };
            var actualRoot = {
                children : [
                    {
                        label     : "open files",
                        path      : "!openfiles",
                        isOpen    : true,
                        className : "heading",
                        isRoot    : true,
                        isFolder  : true,
                        status    : "loaded",
                        map       : {},
                        children  : root.groups,
                        noSelect  : true
                    }
                ]
            };

            var oldRoot = ofDataProvider && ofDataProvider.root;
            var existing = oldRoot && oldRoot.groups || {};
            root.children = activePanes.map(function(pane, i) {
                var group = existing[i] || { isOpen: true, className: "group" };
                if (group.isOpen == "forced")
                    group.isOpen = false;
                root.groups[i] = group;
                group.children = null;
                // name: pane.name (tab0 ...)
                group.children =  pane.getTabs()
                    .filter(function(tab){
                        return tab.path && tab.loaded && !tab.meta.$closing;
                    })
                    .map(function(tab) {
                        var node = {
                            name : basename(tab.path),
                            path : tab.path,
                            tab  : tab
                        };
                        if (tab == focussedTab) {
                            selected = node;
                            group.isOpen = "forced";
                        }

                        tab.document.on("changed", refresh);
                        return node;
                    });
                return group;
            }).filter(function(pane){
                return pane.children.length;
            }).map(function (node, i) {
                node.name = "GROUP " + (i+1);
                return node;
            });

            // Hide the openfiles
            if (!root.children.length) {
                preventUpdate = false;
                return hideOpenFiles();
            }

            ui.setStyleClass(treeParent.parentNode.$int, "hasopenfiles");

            treeParent.show();

            if (root.children.length === 1)
                actualRoot.children[0].children = root.children[0].children;

            ofDataProvider.setRoot(actualRoot);
            ofDataProvider.selection.selectNode(selected);

            updateHeight();
        }

        function updateHeight(selected){
            preventUpdate = true;

            var maxHeight = treeParent.parentNode.$int.offsetHeight * 0.5;
            var treeHeight = ofTree.renderer.desiredHeight + 23;

            treeParent.$int.style.height = dragged
                ? Math.min(treeParent.getHeight(), treeHeight) + "px"
                : Math.min(treeHeight, maxHeight) + "px";

            // ofTree.resize(true);
            tree.resize();

            if (!selected)
                selected = ofTree.selectedNode;

            ofTree.renderer.scrollCaretIntoView(selected, 0.5);

            preventUpdate = false;
        }

        function refresh() {
            if (!showOpenFiles || !ofDataProvider)
                return;
            ofDataProvider._signal("change");
        }

        function onSelect() {
            var node = ofTree.selection.getCursor();
            if (node && tabs.focussedTab && tabs.focussedTab.path != node.path)
                tabs.focusTab(node.path);
        }

        function hideOpenFiles() {
            var htmlNode = treeParent && treeParent.parentNode.$int;
            htmlNode && ui.setStyleClass(htmlNode, "", ["hasopenfiles"]);
            treeParent && treeParent.hide();
            tree.resize();
        }

        function toggleOpenfiles() {
            showOpenFiles = !showOpenFiles;
            settings.set("user/openfiles/@show", showOpenFiles);
            updateVisibility(showOpenFiles);
        }

        function updateVisibility(show) {
            if (show) {
                draw();
                update();
                ctxItem && ctxItem.show();

                if (settings.getBool("state/openfiles/@hidetree"))
                    hideTree(true);

                if (!panels.isActive("tree")) {
                    panels.once("showPanelTree", function(){
                        ofTree.resize(true);
                        tree.resize(true);
                    });

                    panels.activate("tree");
                }
            }
            else {
                hideOpenFiles();
                ctxItem && ctxItem.hide();

                if (treeParent)
                    hideTree(false);
            }

            emit("visible", { value: show });
        }

        /***** Lifecycle *****/

        plugin.on("load", function(){
            load();
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
            loaded = false;
            drawn  = false;
        });

        function show() {
            updateVisibility(true);
        }

        function hide() {
            updateVisibility(false);
        }

        /***** Register and define API *****/

        /**
         * Displays the open files above the tree.
         *
         * @singleton
         */
        plugin.freezePublicAPI({
            /**
             * Show the openfiles panel
             */
            show: show,

            /**
             * Hide the openfiles panel
             */
            hide: hide,

            /**
             * Trigger a complete update of the openfiles view, only when the
             * openfiles panel is visible.
             */
            update: update,

            /**
             * Rerender the viewed part of the tree without having to recreate
             * the tree data.
             * Example usage: when the saving state or document content changed
             * Only applies when openfiles is visible
             */
            refresh: refresh,

            /**
             *
             */
            showTree: hideTree.bind(null, false),

            /**
             *
             */
            hideTree: hideTree.bind(null, true)
        });

        register(null, {
            openfiles: plugin
        });
    }
});
<|endoftext|>


<commit_before>'use strict';

module.exports = function(app) {
	// Routing logic
	var categories = require('../../app/controllers/categories.server.controller');

	app.route('/categories')
		.get(categories.list)
		.post(categories.create);

	app.route('/categories/:categoryId')
		.get(categories.read)
		.put(categories.update)
		.delete(categories.delete);

	app.param('categoryId', categories.categoryById);
};<commit_msg>Add authentication<commit_after>'use strict';

module.exports = function(app) {
	// Routing logic
	var categories = require('../../app/controllers/categories.server.controller');
	var users = require('../../app/controllers/users.server.controller');

	app.route('/categories')
		.get(categories.list)
		.post(users.requiresLogin, categories.create);

	app.route('/categories/:categoryId')
		.get(categories.read)
		.put(users.requiresLogin, categories.update)
		.delete(users.requiresLogin, categories.delete);

	app.param('categoryId', categories.categoryById);
};<|endoftext|>


<commit_before>/*************************************************************
 * ************************ SERVER ***************************
 ************************** UPDATE ***************************
 *************************************************************
 */
const request = require('request');
const csv = require('csvtojson');
var http = require('http');

var urlET = 'http://academic.uprm.edu/hdc/GOES-PRWEB_RESULTS/reference_ET_PenmanMonteith/reference_ET_PenmanMonteith';
var urlRainfall = 'http://academic.uprm.edu/hdc/GOES-PRWEB_RESULTS/rainfall/rainfall'
var referenceET = [];
var rainfall = [];

Date.prototype.yyyymmdd = function() {
  var mm = this.getMonth() + 1; // getMonth() is zero-based
  var dd = this.getDate();

  return [this.getFullYear(),
          (mm>9 ? '' : '0') + mm,
          (dd>9 ? '' : '0') + dd
         ].join('');
};

function downloadFile(urlOfFile,day,callback){
	var matrix = [];

	return csv({noheader:true})
	.fromStream(request.get(urlOfFile + day + '.csv'))
	.on('csv',(csvRow, rowIndex)=>{
		// csvRow is an array
		matrix.push(csvRow);
	})
	.on('end',(error)=>{
		if(matrix.length < 101){
			console.log(day +'\'s file is not ready.');
			matrix = [];
			day--;
			downloadFile(urlOfFile,day,callback);
		}
		else{
			callback(matrix,day);
		}

	});
}

function getTodaysFiles(){
	var date = new Date();
	var today = date.yyyymmdd();
	today = parseInt(today);

	// Get Reference ET data
	downloadFile(urlET,today,function(matrix,day){
		referenceET = matrix;
		console.log(day+': ReferenceET downloaded into matrix.');

		// Get Rainfall data
		downloadFile(urlRainfall,day,function(matrix,day){
			rainfall = matrix;
			console.log(day+': Rainfall downloaded into matrix.');

			// Read All Crops
			readAllCrops();
		});
	});

	return;
}

function accessDatabase(restfulAPI,callback){
	return http.get({
        host: 'h2ocrop.herokuapp.com',
        path: restfulAPI
    }, function(response) {
    	response.setEncoding('utf8');
        // Continuously update stream with data
        var body = '';
        response.on('data', function(d) {
            body += d;
        });
        response.on('end', function() {
            // Data reception is done, do whatever with it!
            var parsed;
            try{
                parsed = JSON.parse(body);
            }catch(error){
            	parsed = body;
            }
            callback(parsed);
        });
    });
}

function readAllCrops() {
    accessDatabase('/db/get/allcrops',function(result) {
    	var allcrops = result;
        for(var i=0;i<allcrops.length;i++){
        	updateNewData(allcrops[i]);
        }
    });

}

function clearSpaces(data){
	for(d in data){
		if(typeof data[d] === "string") {

			data[d] = data[d].split(' ').join('%20');
			console.log(data[d]);
		}
	}
}

function updateNewData(crop){
	var calculated, irrigationDepth, Kc, adjusted,ETcadj,RAW;

	console.log('Updating data for crop '+crop.cropid+' ...');
	calculated = getIrrigationDepth(crop);
	irrigationDepth = calculated.irrigationDepth;
	Kc = calculated.Kc;
	crop.currentet = irrigationDepth;
	crop.currentkc = Kc;

	adjusted = adjustIrrigationDepth(crop);
	ETcadj = adjusted.ETcadj;
	RAW = adjusted.RAW;
	crop.cumulativeET += ETcadj;

	//clear for URL Launch
	clearSpaces(crop);
	console.log(JSON.stringify(crop));

	//update crop in database
	accessDatabase('/db/update/crop/'+JSON.stringify(crop), function(result){
			console.log('Updated crop '+crop.cropid+': day '+crop.currentday,crop.currentet,crop.currentkc,crop.cumulativeet);
	});

	// if(crop.cumulativeet >= RAW){
	// 	//alert user to irrigate
	// 	accessDatabase('/sendAlert/'+JSON.stringify(crop),function(result){
	// 		console.log('Alerted user '+crop.username+' at '+crop.email);
	// 	});
	// }
	if(true){
		//alert user to irrigate
		crop.email = 'armando.ortiz1@upr.edu';
		accessDatabase('/sendAlert/'+JSON.stringify(crop),function(r){});
	}

}

function getIrrigationDepth(crop){
	var latIndex, lonIndex, ETo, Kc, ETc, irrigationDepth;

	latIndex = crop.latindex-1;
	lonIndex = crop.lonindex-1;
	ETo = referenceET[latIndex][lonIndex];
	crop.currentday++;

	if(crop.currentday <= crop.lini){
		Kc = crop.kcini;
	}
	else if(crop.currentday <= (crop.lini + crop.ldev)){
		Kc = crop.kcini + ((crop.currentday - crop.lini) / crop.ldev) * (crop.kcmid - crop.kcini);
	}
	else if(crop.currentday <= (crop.lini+crop.ldev+crop.lmid)){
		Kc = crop.kcmid;
	}
	else if(crop.currentday <= (crop.lini+crop.ldev+crop.lmid+crop.llate)){
		Kc = crop.kcmid + ((crop.currentday - crop.lini+crop.ldev+crop.lmid) / crop.llate) * (crop.kcend - crop.kcmid);
	}
	else{
		Kc = crop.kcend;
		crop.cropstatus = 'Finished';
	}

	ETc = Kc * ETo;
	irrigationDepth = ETc - rainfall[latIndex][lonIndex];

	if(irrigationDepth < 0){
		irrigationDepth = 0;
	}
	return {irrigationDepth: irrigationDepth, Kc: Kc};
}

function adjustIrrigationDepth(crop){
	var TAW, p, RAW, ETcadj, Ks;
	crop.p = parseFloat(crop.p);
	crop.qfc = parseFloat(crop.qfc);
	crop.qwp = parseFloat(crop.qwp);
	crop.zr = parseFloat(crop.zr);

	TAW = 1000 * (crop.qfc - crop.qwp) * crop.zr;
	p = (crop.p) + (0.04 * (5 - crop.currentet));

	if(p < 0.1){
		p = 0.1;
	}
	else if(p > 0.8){
		p = 0.8;
	}

	RAW = p * TAW;

	if(crop.cumulativeet < RAW){
		Ks = 1;
	}
	else{
		Ks = (TAW - crop.cumulativeet) / (TAW - RAW);
	}

	ETcadj = Ks * crop.currentkc * crop.currentet;

	return {ETcadj: ETcadj, RAW: RAW};
}

//to be called once at ~2am everyday
function serverUpdate(){
	getTodaysFiles();
}

serverUpdate();
<commit_msg>Update Server bug fixed<commit_after>/*************************************************************
 * ************************ SERVER ***************************
 ************************** UPDATE ***************************
 *************************************************************
 */
const request = require('request');
const csv = require('csvtojson');
var http = require('http');

var urlET = 'http://academic.uprm.edu/hdc/GOES-PRWEB_RESULTS/reference_ET_PenmanMonteith/reference_ET_PenmanMonteith';
var urlRainfall = 'http://academic.uprm.edu/hdc/GOES-PRWEB_RESULTS/rainfall/rainfall'
var referenceET = [];
var rainfall = [];

Date.prototype.yyyymmdd = function() {
  var mm = this.getMonth() + 1; // getMonth() is zero-based
  var dd = this.getDate();

  return [this.getFullYear(),
          (mm>9 ? '' : '0') + mm,
          (dd>9 ? '' : '0') + dd
         ].join('');
};

function downloadFile(urlOfFile,day,callback){
	var matrix = [];

	return csv({noheader:true})
	.fromStream(request.get(urlOfFile + day + '.csv'))
	.on('csv',(csvRow, rowIndex)=>{
		// csvRow is an array
		matrix.push(csvRow);
	})
	.on('end',(error)=>{
		if(matrix.length < 101){
			console.log(day +'\'s file is not ready.');
			matrix = [];
			day--;
			downloadFile(urlOfFile,day,callback);
		}
		else{
			callback(matrix,day);
		}

	});
}

function getTodaysFiles(){
	var date = new Date();
	var today = date.yyyymmdd();
	today = parseInt(today);

	// Get Reference ET data
	downloadFile(urlET,today,function(matrix,day){
		referenceET = matrix;
		console.log(day+': ReferenceET downloaded into matrix.');

		// Get Rainfall data
		downloadFile(urlRainfall,day,function(matrix,day){
			rainfall = matrix;
			console.log(day+': Rainfall downloaded into matrix.');

			// Read All Crops
			readAllCrops();
		});
	});

	return;
}

function accessDatabase(restfulAPI,callback){
	return http.get({
        host: 'h2ocrop.herokuapp.com',
        path: restfulAPI
    }, function(response) {
    	response.setEncoding('utf8');
        // Continuously update stream with data
        var body = '';
        response.on('data', function(d) {
            body += d;
        });
        response.on('end', function() {
            // Data reception is done, do whatever with it!
            var parsed;
            try{
                parsed = JSON.parse(body);
            }catch(error){
            	parsed = body;
            }
            callback(parsed);
        });
    });
}

function readAllCrops() {
    accessDatabase('/db/get/allcrops',function(result) {
    	var allcrops = result;
        for(var i=0;i<allcrops.length;i++){
        	updateNewData(allcrops[i]);
        }
    });

}

function clearSpaces(data){
	for(d in data){
		if(typeof data[d] === "string") {
			data[d] = data[d].split(' ').join('%20');
		}
	}
}

function updateNewData(crop){
	var calculated, irrigationDepth, Kc, adjusted,ETcadj,RAW;

	console.log('Updating data for crop '+crop.cropid+' ...');
	calculated = getIrrigationDepth(crop);
	irrigationDepth = calculated.irrigationDepth;
	Kc = calculated.Kc;
	crop.currentet = irrigationDepth;
	crop.currentkc = Kc;

	adjusted = adjustIrrigationDepth(crop);
	ETcadj = adjusted.ETcadj;
	RAW = adjusted.RAW;
	crop.cumulativeet += ETcadj;

	//clear for URL Launch
	clearSpaces(crop);

	//update crop in database
	accessDatabase('/db/update/crop/'+JSON.stringify(crop), function(result){
			console.log('Updated crop '+crop.cropid+': day '+crop.currentday+
				' ETc '+crop.currentet+' Kc '+crop.currentkc+' Cumu '+crop.cumulativeet);
	});

	if(crop.cumulativeet >= RAW){
		//alert user to irrigate
		accessDatabase('/sendAlert/'+JSON.stringify(crop),function(result){
			console.log('Alerted user '+crop.username+' at '+crop.email);
		});
	}
	// if(true){
	// 	//alert user to irrigate
	// 	crop.email = 'armando.ortiz1@upr.edu';
	// 	accessDatabase('/sendAlert/'+JSON.stringify(crop),function(r){});
	// }

}

function getIrrigationDepth(crop){
	var latIndex, lonIndex, ETo, Kc, ETc, irrigationDepth;
	crop.kcini = parseFloat(crop.kcini);
	crop.kcmid = parseFloat(crop.kcmid);
	crop.kcend = parseFloat(crop.kcend);
	crop.lini = parseFloat(crop.lini);
	crop.ldev = parseFloat(crop.ldev);
	crop.lmid = parseFloat(crop.lmid);
	crop.llate = parseFloat(crop.llate);

	latIndex = crop.latindex-1;
	lonIndex = crop.lonindex-1;
	ETo = referenceET[latIndex][lonIndex];
	crop.currentday++;

	if(crop.currentday <= crop.lini){
		Kc = crop.kcini;
	}
	else if(crop.currentday <= (crop.lini + crop.ldev)){
		Kc = crop.kcini + ((crop.currentday - crop.lini) / crop.ldev) * (crop.kcmid - crop.kcini);
	}
	else if(crop.currentday <= (crop.lini+crop.ldev+crop.lmid)){
		Kc = crop.kcmid;
	}
	else if(crop.currentday <= (crop.lini+crop.ldev+crop.lmid+crop.llate)){
		Kc = crop.kcmid + ((crop.currentday - crop.lini+crop.ldev+crop.lmid) / crop.llate) * (crop.kcend - crop.kcmid);
	}
	else{
		Kc = crop.kcend;
		crop.cropstatus = 'Finished';
	}

	ETc = Kc * ETo;
	irrigationDepth = ETc - rainfall[latIndex][lonIndex];

	if(irrigationDepth < 0){
		irrigationDepth = 0;
	}
	return {irrigationDepth: irrigationDepth, Kc: Kc};
}

function adjustIrrigationDepth(crop){
	var TAW, p, RAW, ETcadj, Ks;
	crop.p = parseFloat(crop.p);
	crop.qfc = parseFloat(crop.qfc);
	crop.qwp = parseFloat(crop.qwp);
	crop.zr = parseFloat(crop.zr);

	TAW = 1000 * (crop.qfc - crop.qwp) * crop.zr;
	p = (crop.p) + (0.04 * (5 - crop.currentet));

	if(p < 0.1){
		p = 0.1;
	}
	else if(p > 0.8){
		p = 0.8;
	}

	RAW = p * TAW;

	if(crop.cumulativeet < RAW){
		Ks = 1;
	}
	else{
		Ks = (TAW - crop.cumulativeet) / (TAW - RAW);
	}

	ETcadj = Ks * crop.currentet;

	return {ETcadj: ETcadj, RAW: RAW};
}

//to be called once at ~2am everyday
function serverUpdate(){
	getTodaysFiles();
}

serverUpdate();
<|endoftext|>


<commit_before>/*global config*/
import React from 'react';
import { render } from 'react-dom';
import { createHistory } from 'history';
import { Router, useRouterHistory } from 'react-router';
import routes from './routes';
import Cookies from 'js-cookie';

if (!config.apiRoot) {
  console.warn('You need to set your apiRoot via localStorage');
  console.warn('e.g. localStorage["apiRootOverride"] = "https://path.to-api.com/v1/api"');
}

if (config.fullstoryToken && config.usernameCookie && Cookies.get(config.usernameCookie)) {
  FS.identify(Cookies.get(config.usernameCookie), {
    app_str: 'blazar'
  });
}

const browserHistory = useRouterHistory(createHistory) ({
  basename: config.appRoot
});

render(
  <Router history={browserHistory}>
    {routes}
  </Router>,
  document.getElementById('app')
);
<commit_msg>specify display name too<commit_after>/*global config*/
import React from 'react';
import { render } from 'react-dom';
import { createHistory } from 'history';
import { Router, useRouterHistory } from 'react-router';
import routes from './routes';
import Cookies from 'js-cookie';

if (!config.apiRoot) {
  console.warn('You need to set your apiRoot via localStorage');
  console.warn('e.g. localStorage["apiRootOverride"] = "https://path.to-api.com/v1/api"');
}

if (config.fullstoryToken && config.usernameCookie && Cookies.get(config.usernameCookie)) {
  FS.identify(Cookies.get(config.usernameCookie), {
    displayName: Cookies.get(config.usernameCookie),
    app_str: 'blazar'
  });
}

const browserHistory = useRouterHistory(createHistory) ({
  basename: config.appRoot
});

render(
  <Router history={browserHistory}>
    {routes}
  </Router>,
  document.getElementById('app')
);
<|endoftext|>