<commit_before>var KEY_AUTH = 'overlay_networks_group1';

new Vue({
	el: '#app',
	data: {
		isLoading: true,
		websockets: {
			stompClient: null,
			connected: false,
			initialized: false
		},
		auth: {
			authenticated: false,
			username: ''
		},
		chat: {
			contacts: [],
			selectedContact: '',
		},
		input: {
			loginUsername: '',
			loginUsernameDisabled: false,
			addContactInput: '',
			addContactInputDisabled: false,
			messageInput: '',
			messageInputDisabled: false
		}
	},
	computed: {
		currentChatMessages: function() {
			var App = this;
			var contact = App.chat.contacts.filter(function(item) {
				return item.name === App.chat.selectedContact;
			});
			if(contact.length === 1) {
				return contact[0].messages;
			} else {
				return [];
			}
		},
		currentChatContact: function() {
			var App = this;

			var contact = App.chat.contacts.filter(function(item) {
				return item.name === App.chat.selectedContact;
			});
			if(contact.length === 1) {
				return contact[0];
			}
		}
	},
	methods: {
		connectToWebsockets: function () {
			var App = this;
			var socket = new SockJS('/websocket');
			App.websockets.stompClient = Stomp.over(socket);
			App.websockets.stompClient.connect({}, function connect(frame) {
				App.websockets.connected = true;
				App.websockets.initialized = true;

				App.websockets.stompClient.subscribe('/topic/receive-message', function (response) {
					response = JSON.parse(response.body);

					var filteredContact = App.chat.contacts.filter(function(item) {
						return item.name === response.sender.name;
					});
					if(filteredContact.length === 1) {
						filteredContact[0].messages.push({
							messageId: response.messageId,
							content: response.message,
							isOwnMessage: false,
							approved: false
						});
						setToStorage(App);

					} else {
						console.log("Could not find a contact to that message.", message);
					}
				});

				App.websockets.stompClient.subscribe('/topic/receive-notary', function (response) {
					response = JSON.parse(response.body);
					var messageFound = false;

					for(var i = 0; i < App.chat.contacts.length; i++) {
						var contact = App.chat.contacts[i];
						var messageArray = contact.messages.filter(function (item) {
							return item.messageId === response.messageId;
						});

						if(messageArray.length === 1) {
							messageArray[0].approved = true;
							messageFound = true;
							setToStorage(App);
							break;
						}
					}

					if(!messageFound) {
						console.log("Could not find a message to approve (notary)", response);
					}
				});
				App.websockets.stompClient.subscribe('/topic/update-contacts', function (response) {
					response = JSON.parse(response.body);

					for(var i = 0; i < response.length; i++) {
						var responseItem = response[i];

						var contactArray = App.chat.contacts.filter(function (item) {
							return item.name === responseItem.contact.name;
						});
						if(contactArray.length === 1) {
							contactArray[0].online = responseItem.status;

						} else {
							console.log("Contact not found in local list", responseItem);
						}
					}
				});
			}, function disconnect() {
				App.websockets.connected = false;
			});
		},
		submitLogin: function() {
			var App = this;

			App.input.loginUsernameDisabled = true;
			return App.$http.post('/rest/login', { name: App.input.loginUsername }).then(function() {
				App.auth = {
					authenticated: true,
					username: App.input.loginUsername
				};
				setToStorage(App);

				App.input.loginUsername = '';
				App.connectToWebsockets();

			}, function() {
				alert("You cannot use this username.");
				App.input.loginUsername = '';
			}).then(function() {
				App.input.loginUsernameDisabled = false;
			});
		},
		autoLogin: function(storageObject) {
			var App = this;

			if(storageObject && storageObject.auth && storageObject.chat) {
				return App.$http.post('/rest/login', { name: storageObject.auth.username }).then(function() {
					var contactSet = getSubmittableContactList(storageObject);
					return App.$http.post('/rest/new-contact-list', contactSet).then(function() {
						App.auth = storageObject.auth;
						App.chat = storageObject.chat;
						App.connectToWebsockets();

					}, function() {
						App.logout();
					});

				}, function() {
					removeFromStorage();
				});

			} else {
				removeFromStorage();
				return Promise.resolve();
			}
		},
		addContact: function() {
			var App = this;

			var usernameNotEmpty = App.input.addContactInput.trim() !== '';
			var usernameDifferentToOwnUsername = App.input.addContactInput !== App.auth.username;
			var userDoesNotExistAlready = App.chat.contacts.filter(function(item) {
				return item.name === App.input.addContactInput;
			}).length === 0;

			if(usernameNotEmpty && usernameDifferentToOwnUsername && userDoesNotExistAlready) {
				App.input.addContactInputDisabled = true;
				App.$http.post('/rest/new-contact', { name: App.input.addContactInput }).then(function() {

					App.chat.contacts.push({
						name: App.input.addContactInput,
						messages: [],
						online: false
					});
					setToStorage(App);

					App.input.addContactInput = '';
					App.input.addContactInputDisabled = false;

					// set focus back to input field
					window.setTimeout(function() {
						App.$refs.addContactInput.focus();
					});
				}, function() {
					App.input.addContactInputDisabled = false;
				});
			}

		},
		submitMessage: function() {
			var App = this;
			var selectedContact = App.chat.selectedContact;
			var messageInput =  App.input.messageInput

			App.input.messageInputDisabled = true;
			App.$http.post('/rest/send-message', { message: messageInput, receiver: { name: selectedContact }}).then(function(response) {
				var messageId = response.body.messageId;

				App.chat.contacts.filter(function(item) {
					return item.name === selectedContact;
				})[0].messages.push({
					messageId: messageId,
					content: messageInput,
					isOwnMessage: true,
					approved: false
				});

				App.input.messageInput = '';
				App.input.messageInputDisabled = false;

				// set focus back to input field
				window.setTimeout(function() {
					App.$refs.messageInput.focus();
				});

			}, function() {
				App.messageInputDisabled = false;
			});
		},
		logout: function() {
			var App = this;
			App.$http.post('/rest/logout').then(function() {
				removeFromStorage();
				window.location.reload();
			}, function() {
				window.location.reload();
			});
		},
		reload: function() {
			window.location.reload();
		}
	},
	mounted: function() {
		var App = this;

		App.isLoading = true;
		var storageObject = getFromStorage();
		App.autoLogin(storageObject).then(function() {
			App.isLoading = false;
		}, function() {
			App.isLoading = false;
		});
	}
});

function getFromStorage() {
	var storageObject = window.localStorage.getItem(KEY_AUTH);
	if (storageObject) {
		var result = null;
		try { result = JSON.parse(storageObject); } catch (error) { result = null; }

		// adapt online status & selectedFriend
		if(result.chat && result.auth) {
			result.chat.selectedContact = '';
			for(var i=0; i<result.chat.contacts.length; i++) {
				result.chat.contacts[i].online = false;
			}
			return result;
		} else {
			return null;
		}
	} else {
		return null;
	}
}
function setToStorage(App) {
	var storageObject = { auth: App.auth, chat: App.chat };
	window.localStorage.setItem(KEY_AUTH, JSON.stringify(storageObject));
}
function removeFromStorage() {
	window.localStorage.removeItem(KEY_AUTH);
}

function getSubmittableContactList(App) {
	var contactArray = App.chat.contacts;
	var contactSubmitSet = [];

	for(var i=0; i < contactArray.length; i++) {
		contactSubmitSet.push({
			name: contactArray[i].name
		});
	}
	return contactSubmitSet;
}

/* Sockets:
 *
 *
var stompClient = null;

function setConnected(connected) {
	$("#connect").prop("disabled", connected);
	$("#disconnect").prop("disabled", !connected);
	if (connected) {
		$("#conversation").show();
	}
	else {
		$("#conversation").hide();
	}
	$("#greetings").html("");
}

function connect() {
	var socket = new SockJS('/websocket-connection');
	stompClient = Stomp.over(socket);
	stompClient.connect({}, function (frame) {
		setConnected(true);
		console.log('Connected: ' + frame);
		stompClient.subscribe('/topic/greetings', function (greeting) {
			showGreeting(JSON.parse(greeting.body).content);
		});
	});
}

function disconnect() {
	if (stompClient != null) {
		stompClient.disconnect();
	}
	setConnected(false);
	console.log("Disconnected");
}

function sendName() {
	stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}

function showGreeting(message) {
	$("#greetings").append("
" + message + "
");
}

$(function () {
	$("form").on('submit', function (e) {
		e.preventDefault();
	});
	$( "#connect" ).click(function() { connect(); });
	$( "#disconnect" ).click(function() { disconnect(); });
	$( "#send" ).click(function() { sendName(); });
});

*/<commit_msg>disable verbose stompclient console output<commit_after>var KEY_AUTH = 'overlay_networks_group1';

new Vue({
	el: '#app',
	data: {
		isLoading: true,
		websockets: {
			stompClient: null,
			connected: false,
			initialized: false
		},
		auth: {
			authenticated: false,
			username: ''
		},
		chat: {
			contacts: [],
			selectedContact: '',
		},
		input: {
			loginUsername: '',
			loginUsernameDisabled: false,
			addContactInput: '',
			addContactInputDisabled: false,
			messageInput: '',
			messageInputDisabled: false
		}
	},
	computed: {
		currentChatMessages: function() {
			var App = this;
			var contact = App.chat.contacts.filter(function(item) {
				return item.name === App.chat.selectedContact;
			});
			if(contact.length === 1) {
				return contact[0].messages;
			} else {
				return [];
			}
		},
		currentChatContact: function() {
			var App = this;

			var contact = App.chat.contacts.filter(function(item) {
				return item.name === App.chat.selectedContact;
			});
			if(contact.length === 1) {
				return contact[0];
			}
		}
	},
	methods: {
		connectToWebsockets: function () {
			var App = this;
			var socket = new SockJS('/websocket');
			App.websockets.stompClient = Stomp.over(socket);
			App.websockets.stompClient.debug = null;
			App.websockets.stompClient.connect({}, function connect(frame) {
				App.websockets.connected = true;
				App.websockets.initialized = true;

				App.websockets.stompClient.subscribe('/topic/receive-message', function (response) {
					response = JSON.parse(response.body);

					var filteredContact = App.chat.contacts.filter(function(item) {
						return item.name === response.sender.name;
					});
					if(filteredContact.length === 1) {
						filteredContact[0].messages.push({
							messageId: response.messageId,
							content: response.message,
							isOwnMessage: false,
							approved: false
						});
						setToStorage(App);

					} else {
						console.log("Could not find a contact to that message.", message);
					}
				});

				App.websockets.stompClient.subscribe('/topic/receive-notary', function (response) {
					response = JSON.parse(response.body);
					var messageFound = false;

					for(var i = 0; i < App.chat.contacts.length; i++) {
						var contact = App.chat.contacts[i];
						var messageArray = contact.messages.filter(function (item) {
							return item.messageId === response.messageId;
						});

						if(messageArray.length === 1) {
							messageArray[0].approved = true;
							messageFound = true;
							setToStorage(App);
							break;
						}
					}

					if(!messageFound) {
						console.log("Could not find a message to approve (notary)", response);
					}
				});
				App.websockets.stompClient.subscribe('/topic/update-contacts', function (response) {
					response = JSON.parse(response.body);

					for(var i = 0; i < response.length; i++) {
						var responseItem = response[i];

						var contactArray = App.chat.contacts.filter(function (item) {
							return item.name === responseItem.contact.name;
						});
						if(contactArray.length === 1) {
							contactArray[0].online = responseItem.status;

						} else {
							console.log("Contact not found in local list", responseItem);
						}
					}
				});
			}, function disconnect() {
				App.websockets.connected = false;
			});
		},
		submitLogin: function() {
			var App = this;

			App.input.loginUsernameDisabled = true;
			return App.$http.post('/rest/login', { name: App.input.loginUsername }).then(function() {
				App.auth = {
					authenticated: true,
					username: App.input.loginUsername
				};
				setToStorage(App);

				App.input.loginUsername = '';
				App.connectToWebsockets();

			}, function() {
				alert("You cannot use this username.");
				App.input.loginUsername = '';
			}).then(function() {
				App.input.loginUsernameDisabled = false;
			});
		},
		autoLogin: function(storageObject) {
			var App = this;

			if(storageObject && storageObject.auth && storageObject.chat) {
				return App.$http.post('/rest/login', { name: storageObject.auth.username }).then(function() {
					var contactSet = getSubmittableContactList(storageObject);
					return App.$http.post('/rest/new-contact-list', contactSet).then(function() {
						App.auth = storageObject.auth;
						App.chat = storageObject.chat;
						App.connectToWebsockets();

					}, function() {
						App.logout();
					});

				}, function() {
					removeFromStorage();
				});

			} else {
				removeFromStorage();
				return Promise.resolve();
			}
		},
		addContact: function() {
			var App = this;

			var usernameNotEmpty = App.input.addContactInput.trim() !== '';
			var usernameDifferentToOwnUsername = App.input.addContactInput !== App.auth.username;
			var userDoesNotExistAlready = App.chat.contacts.filter(function(item) {
				return item.name === App.input.addContactInput;
			}).length === 0;

			if(usernameNotEmpty && usernameDifferentToOwnUsername && userDoesNotExistAlready) {
				App.input.addContactInputDisabled = true;
				App.$http.post('/rest/new-contact', { name: App.input.addContactInput }).then(function() {

					App.chat.contacts.push({
						name: App.input.addContactInput,
						messages: [],
						online: false
					});
					setToStorage(App);

					App.input.addContactInput = '';
					App.input.addContactInputDisabled = false;

					// set focus back to input field
					window.setTimeout(function() {
						App.$refs.addContactInput.focus();
					});
				}, function() {
					App.input.addContactInputDisabled = false;
				});
			}

		},
		submitMessage: function() {
			var App = this;
			var selectedContact = App.chat.selectedContact;
			var messageInput =  App.input.messageInput

			App.input.messageInputDisabled = true;
			App.$http.post('/rest/send-message', { message: messageInput, receiver: { name: selectedContact }}).then(function(response) {
				var messageId = response.body.messageId;

				App.chat.contacts.filter(function(item) {
					return item.name === selectedContact;
				})[0].messages.push({
					messageId: messageId,
					content: messageInput,
					isOwnMessage: true,
					approved: false
				});

				App.input.messageInput = '';
				App.input.messageInputDisabled = false;

				// set focus back to input field
				window.setTimeout(function() {
					App.$refs.messageInput.focus();
				});

			}, function() {
				App.messageInputDisabled = false;
			});
		},
		logout: function() {
			var App = this;
			App.$http.post('/rest/logout').then(function() {
				removeFromStorage();
				window.location.reload();
			}, function() {
				window.location.reload();
			});
		},
		reload: function() {
			window.location.reload();
		}
	},
	mounted: function() {
		var App = this;

		App.isLoading = true;
		var storageObject = getFromStorage();
		App.autoLogin(storageObject).then(function() {
			App.isLoading = false;
		}, function() {
			App.isLoading = false;
		});
	}
});

function getFromStorage() {
	var storageObject = window.localStorage.getItem(KEY_AUTH);
	if (storageObject) {
		var result = null;
		try { result = JSON.parse(storageObject); } catch (error) { result = null; }

		// adapt online status & selectedFriend
		if(result.chat && result.auth) {
			result.chat.selectedContact = '';
			for(var i=0; i<result.chat.contacts.length; i++) {
				result.chat.contacts[i].online = false;
			}
			return result;
		} else {
			return null;
		}
	} else {
		return null;
	}
}
function setToStorage(App) {
	var storageObject = { auth: App.auth, chat: App.chat };
	window.localStorage.setItem(KEY_AUTH, JSON.stringify(storageObject));
}
function removeFromStorage() {
	window.localStorage.removeItem(KEY_AUTH);
}

function getSubmittableContactList(App) {
	var contactArray = App.chat.contacts;
	var contactSubmitSet = [];

	for(var i=0; i < contactArray.length; i++) {
		contactSubmitSet.push({
			name: contactArray[i].name
		});
	}
	return contactSubmitSet;
}

/* Sockets:
 *
 *
var stompClient = null;

function setConnected(connected) {
	$("#connect").prop("disabled", connected);
	$("#disconnect").prop("disabled", !connected);
	if (connected) {
		$("#conversation").show();
	}
	else {
		$("#conversation").hide();
	}
	$("#greetings").html("");
}

function connect() {
	var socket = new SockJS('/websocket-connection');
	stompClient = Stomp.over(socket);
	stompClient.connect({}, function (frame) {
		setConnected(true);
		console.log('Connected: ' + frame);
		stompClient.subscribe('/topic/greetings', function (greeting) {
			showGreeting(JSON.parse(greeting.body).content);
		});
	});
}

function disconnect() {
	if (stompClient != null) {
		stompClient.disconnect();
	}
	setConnected(false);
	console.log("Disconnected");
}

function sendName() {
	stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}

function showGreeting(message) {
	$("#greetings").append("
" + message + "
");
}

$(function () {
	$("form").on('submit', function (e) {
		e.preventDefault();
	});
	$( "#connect" ).click(function() { connect(); });
	$( "#disconnect" ).click(function() { disconnect(); });
	$( "#send" ).click(function() { sendName(); });
});

*/<|endoftext|>


<commit_before>/**
 * Manages loading of the main menu for the application.
 */
Rexster.modules.mainMenu = function(api) {

	function slideGraphPanel(newState) {
		var options = { direction:"right" },
		    different = isPanelDifferent("mainGraph");

		// hide the current panel as a new one has been selected
		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null && different) {
			Rexster.currentPanel.hide("slide", options);
		}

		Rexster("graph", "history", function(innerApi) {

			if (newState != undefined) {
				innerApi.historyPush(newState);
			}

			// show the graph panel
			innerApi.initGraphList(function(){
				if (different) {
					Rexster.currentPanel = $("#mainGraph");
					$("#slideHolder").prepend(Rexster.currentPanel);
					Rexster.currentPanel.show("slide");
				}

				Elastic.refresh();
			});
		});
	}

	function slideGremlinPanel(newState) {
		var options = { direction:"right" };

		// hide the current panel as a new one has been selected
		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null) {
			Rexster.currentPanel.hide("slide", options);
		}

		Rexster.currentPanel = $("#mainGremlin");
		$("#slideHolder").prepend(Rexster.currentPanel);
		Rexster.currentPanel.show("slide");
		Elastic.refresh();

		Rexster("terminal", "history", function(innerApi) {
			if (newState != undefined) {
				innerApi.historyPush(newState);
			}

			innerApi.initTerminal();
		});
	}

	function isPanelDifferent(newPanel) {
		var diff = true;

		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null) {
			diff = Rexster.currentPanel.attr("id") != newPanel;
		}

		return diff;
	}

	api.initMainMenu = function(){

		var menuItems = [
		                  {"id":"Dashboard", "menuName":"Dashboard", "disabled":true},
		                  {"id":"Graph", "menuName":"Graphs", "checked":true},
		                  {"id":"Gremlin", "menuName":"Gremlin"},
		                  {"id":"Pacer", "menuName":"Pacer", "disabled":true}
		                ],
		     state = {};

		Rexster("history", function(innerApi) {
			state = innerApi.getApplicationState();
		});

		$("#radiosetMainMenu").empty();

		if (state != undefined && state.menu != undefined) {
			if (state.menu == "graph") {
				menuItems[1].checked = true;
				menuItems[2].checked = false;
			} else if (state.menu == "gremlin") {
				menuItems[1].checked = false;
				menuItems[2].checked = true;
			}
		}

		Rexster("template", function(innerApi) {
			innerApi.applyMainMenuTemplate(menuItems, "#radiosetMainMenu")
		});

		$("#radiosetMainMenu").buttonset();

		$("#radioMenuGraph").unbind("click");
		$("#radioMenuGraph").click(function() {
			slideGraphPanel("/main/graph");
			return false;
		});

		$("#radioMenuGremlin").unbind("click");
		$("#radioMenuGremlin").click(function() {
			slideGremlinPanel("/main/gremlin");
            return false;
		});

		if (state.menu === "graph") {
			if (state.hasOwnProperty("graph")) {
				// the state is defined for the graph so no need to initialize
				slideGraphPanel();
			} else {
				// no graph is set so let it default the first one
				$("#radioMenuGraph").click();
			}
		} else if (state.menu === "gremlin") {
			if (state.hasOwnProperty("graph")) {
				slideGremlinPanel();
			} else {
				$("#radioMenuGremlin").click();
			}
		}
	};
};<commit_msg>tightened up the animation a bit so that the panels would slide in a single direction on menu change.<commit_after>/**
 * Manages loading of the main menu for the application.
 */
Rexster.modules.mainMenu = function(api) {

	function slideGraphPanel(newState) {
		var options = { direction:"right" },
		    different = isPanelDifferent("mainGraph");

		// hide the current panel as a new one has been selected
		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null && different) {
			Rexster.currentPanel.hide("slide", options, 500);
		}

		Rexster("graph", "history", function(innerApi) {

			if (newState != undefined) {
				innerApi.historyPush(newState);
			}

			// show the graph panel
			innerApi.initGraphList(function(){
				if (different) {
					Rexster.currentPanel = $("#mainGraph");
					$("#slideHolder").prepend(Rexster.currentPanel);
					Rexster.currentPanel.delay(500).show("slide", null, function() { Elastic.refresh(); });
				}
			});
		});
	}

	function slideGremlinPanel(newState) {
		var options = { direction:"right" },
	    different = isPanelDifferent("mainGremlin");;

		// hide the current panel as a new one has been selected
		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null && different) {
			Rexster.currentPanel.hide("slide", options);
		}

		Rexster("terminal", "history", function(innerApi) {
			if (newState != undefined) {
				innerApi.historyPush(newState);
			}

			innerApi.initTerminal(function(){
				if (different) {
					Rexster.currentPanel = $("#mainGremlin");
					$("#slideHolder").prepend(Rexster.currentPanel);
					Rexster.currentPanel.delay(500).show("slide", null, function() { Elastic.refresh(); });
				}
			});
		});
	}

	function isPanelDifferent(newPanel) {
		var diff = true;

		if (Rexster.currentPanel != undefined && Rexster.currentPanel != null) {
			diff = Rexster.currentPanel.attr("id") != newPanel;
		}

		return diff;
	}

	api.initMainMenu = function(){

		var menuItems = [
		                  {"id":"Dashboard", "menuName":"Dashboard", "disabled":true},
		                  {"id":"Graph", "menuName":"Graphs", "checked":true},
		                  {"id":"Gremlin", "menuName":"Gremlin"},
		                  {"id":"Pacer", "menuName":"Pacer", "disabled":true}
		                ],
		     state = {};

		Rexster("history", function(innerApi) {
			state = innerApi.getApplicationState();
		});

		$("#radiosetMainMenu").empty();

		if (state != undefined && state.menu != undefined) {
			if (state.menu == "graph") {
				menuItems[1].checked = true;
				menuItems[2].checked = false;
			} else if (state.menu == "gremlin") {
				menuItems[1].checked = false;
				menuItems[2].checked = true;
			}
		}

		Rexster("template", function(innerApi) {
			innerApi.applyMainMenuTemplate(menuItems, "#radiosetMainMenu")
		});

		$("#radiosetMainMenu").buttonset();

		$("#radioMenuGraph").unbind("click");
		$("#radioMenuGraph").click(function() {
			slideGraphPanel("/main/graph");
			return false;
		});

		$("#radioMenuGremlin").unbind("click");
		$("#radioMenuGremlin").click(function() {
			slideGremlinPanel("/main/gremlin");
            return false;
		});

		if (state.menu === "graph") {
			if (state.hasOwnProperty("graph")) {
				// the state is defined for the graph so no need to initialize
				slideGraphPanel();
			} else {
				// no graph is set so let it default the first one
				$("#radioMenuGraph").click();
			}
		} else if (state.menu === "gremlin") {
			if (state.hasOwnProperty("graph")) {
				slideGremlinPanel();
			} else {
				$("#radioMenuGremlin").click();
			}
		}
	};
};<|endoftext|>


<commit_before>function print (m, cr) { process.stdio.writeError(m+(cr===false?"":"\n")); return print };

require("./npm").install("http://github.com/isaacs/npm/tarball/rewrite", "npm")
  .addCallback(function () { print("It worked!") })
  .addErrback(function () {
    print
      ("Failure!\n")
      ([].slice.call(arguments,0).join("\n"))
      ("")
      (new Error().stack);
  });
<commit_msg>Using the wrong tarball for npm installation.<commit_after>function print (m, cr) { process.stdio.writeError(m+(cr===false?"":"\n")); return print };

require("./npm").install("http://github.com/isaacs/npm/tarball/master", "npm")
  .addCallback(function () { print("It worked!") })
  .addErrback(function () {
    print
      ("Failure!\n")
      ([].slice.call(arguments,0).join("\n"))
      ("")
      (new Error().stack);
  });
<|endoftext|>


<commit_before>/**

 @author: Tom Clement (tjclement)
 @license NPOSL-3.0
 @copyright Bizboard, 2015

 */

import Timer                            from 'famous/utilities/Timer.js';
import {ObjectHelper}                   from './ObjectHelper.js';

export class Throttler {
    /**
     *
     * @param {Number} throttleDelay Minimum amount of time in between each action executed by the Throttler, in milliseconds or ticks.
     * @param {Boolean} shouldQueue Enable if each added action should be executed consecutively, or disable if a newly
     * added action should replace a previous one.
     * @param {Object} actionContext Context to which the actions executed by the Throttler will be bound.
     * @param {Boolean} useTicks whether ticks should be used instead of milliseconds
     * @returns {Throttler} Throttler instance.
     */
    constructor(throttleDelay = 0, shouldQueue = true, actionContext = this, useTicks = false) {
        this.delay = throttleDelay;
        this._useTicks = useTicks;
        this._timerFunction = useTicks ? Timer.every : Timer.setInterval;
        this.timer = null;
        this.shouldQueue = shouldQueue;
        this.actionContext = actionContext;

        this.queue = [];
        this.executionTimer = null;

        ObjectHelper.bindAllMethods(this, this);
    }

    /**
     * Adds an executable action to the queue that will be executed consecutively by the Throttler.
     * If Throttler was constructed with shouldQueue = false, adding a new action will remove the old one.
     * @param {Function} action Function to execute.
     * @returns {void}
     */
    add(action) {
        /* If we're not queueing, clear the previous action if present. The new action will replace the old one. */
        if (!this.shouldQueue) {
            this.queue.pop();
        }

        this.queue.push(action);
        if (!this.timer) {
            this.timer = this._timerFunction(this._executeTopAction, this.delay);
        }
    }

    /**
     * Clears the Throttler's timer if it is set.
     * @returns {void}
     * @private
     */
    _clearTimer() {
        Timer.clear(this.timer);
        this.timer = null;
    }

    /**
     * Removes the top action from the Throttler's queue if any is present, and executes it with the correct binding context.
     * @returns {void}
     * @private
     */
    _executeTopAction() {
        let action = this.queue.shift();
        if (action && typeof action === 'function') {
            action.call(this.actionContext);
        }
        if (!this.queue.length) {
            this._clearTimer();
        }
    }
}<commit_msg>Fixed so that the throttler executes synchronously when set to 0 delay<commit_after>/**

 @author: Tom Clement (tjclement)
 @license NPOSL-3.0
 @copyright Bizboard, 2015

 */

import Timer                            from 'famous/utilities/Timer.js';
import {ObjectHelper}                   from './ObjectHelper.js';

export class Throttler {
    /**
     *
     * @param {Number} throttleDelay Minimum amount of time in between each action executed by the Throttler, in milliseconds or ticks.
     * @param {Boolean} shouldQueue Enable if each added action should be executed consecutively, or disable if a newly
     * added action should replace a previous one.
     * @param {Object} actionContext Context to which the actions executed by the Throttler will be bound.
     * @param {Boolean} useTicks whether ticks should be used instead of milliseconds
     * @returns {Throttler} Throttler instance.
     */
    constructor(throttleDelay = 0, shouldQueue = true, actionContext = this, useTicks = false) {
        this.delay = throttleDelay;
        this._useTicks = useTicks;
        this._timerFunction = useTicks ? Timer.every : Timer.setInterval;
        this.timer = null;
        this.shouldQueue = shouldQueue;
        this.actionContext = actionContext;

        this.queue = [];
        this.executionTimer = null;

        ObjectHelper.bindAllMethods(this, this);
    }

    /**
     * Adds an executable action to the queue that will be executed consecutively by the Throttler.
     * If Throttler was constructed with shouldQueue = false, adding a new action will remove the old one.
     * @param {Function} action Function to execute.
     * @returns {void}
     */
    add(action) {
        if(this.delay === 0){
            action.call(this.actionContext);
        } else {
            /* If we're not queueing, clear the previous action if present. The new action will replace the old one. */
            if (!this.shouldQueue) {
                this.queue.pop();
            }

            this.queue.push(action);
            if (!this.timer) {
                this.timer = this._timerFunction(this._executeTopAction, this.delay);
            }
        }

    }

    /**
     * Clears the Throttler's timer if it is set.
     * @returns {void}
     * @private
     */
    _clearTimer() {
        Timer.clear(this.timer);
        this.timer = null;
    }

    /**
     * Removes the top action from the Throttler's queue if any is present, and executes it with the correct binding context.
     * @returns {void}
     * @private
     */
    _executeTopAction() {
        let action = this.queue.shift();
        if (action && typeof action === 'function') {
            action.call(this.actionContext);
        }
        if (!this.queue.length) {
            this._clearTimer();
        }
    }
}<|endoftext|>


<commit_before>const Promise = require('promise');

// Constants
const possibleResponses = require('../../config/options');
module.exports = function(slackClient, slackWebClient) {
  return {
    channelMessageToSlackbot(message) {
      const firstWord = message.text.split(' ')[0];
      return (firstWord === process.env.SLACK_BOT_NAME) ||
        (firstWord === `<@${process.env.SLACK_BOT_SLACK_ID}>:`) ||
        (firstWord === `<@${process.env.SLACK_BOT_SLACK_ID}>`);
    },

    privateMessageToSlackbot(message) {
    },

    startGame(message) {
    },
};
<commit_msg>engine of slack bot - initial release<commit_after>const Promise = require('promise');

// Constants
const possibleResponses = require('../../config/options');

// Models
const Game = require('../models/game');
const GameResponse = require('../models/game-response');

module.exports = function(slackClient, slackWebClient) {
  const dataHelpers = require('../data/helpers')(slackWebClient);
  const messanger = require('./messanger')(slackClient);
  const startGameValidator = require('../validators/start-game');
  const responseValidator = require('../validators/response');
  const gameRules = require('./game-rules');

  return {
    channelMessageToSlackbot(message) {
      const firstWord = message.text.split(' ')[0];
      return (firstWord === process.env.SLACK_BOT_NAME) ||
        (firstWord === `<@${process.env.SLACK_BOT_SLACK_ID}>:`) ||
        (firstWord === `<@${process.env.SLACK_BOT_SLACK_ID}>`);
    },

    privateMessageToSlackbot(message) {
      dataHelpers.fetchUserDirectMessageId(message).then((directMessageId) => {
        if (message.channel === directMessageId) this._acceptResponse(message);
      });
    },

    startGame(message) {
      const users = startGameValidator(message, messanger);
      if (!users.length) return;

      const game = new Game({ playerIds: users, channelId: message.channel });
      game.save(() => {
        messanger.respondWith(message, `Starting game ${game._id}...`);
      });
    },

    _acceptResponse(message) {
      this._extractPossibleGameObject(message).then((game) => {
        if (responseValidator(message)) return this._createResponse(message, game);
      }).then((game) => {
        this._checkGameStatus(game);
      }).catch((err) => {
        if (err !== 'Flow escape') console.log('error');
      });
    },

    _extractPossibleGameObject(message) {
      const gameId = message.text.split(' ')[0];

      return new Promise((resolve, reject) => {
        Game.findOne({ '_id': gameId }, (error, game) => {
          if (game) {
            resolve(game);
          } else {
            messanger.respondWith(message, 'No such game in database :(');
            reject();
          }
        });
      });
    },

    _createResponse(message, game) {
      return new Promise((resolve, reject) => {
        GameResponse.findOne({ 'gameId': game._id, 'userId': message.user }, (error, gameResponse) => {
          if (gameResponse) {
            messanger.respondWith(message, 'You already responded to this game!');
            reject();
          } else {
            resolve();
          }
        });
      }).then(() => {
        return new Promise((resolve, reject) => {
          const gameResponseObject = new GameResponse({
            gameId: game._id,
            userId: message.user,
            response: message.text.split(' ')[1],
          });
          gameResponseObject.save(() => {
            messanger.respondWith(message, 'Acknowledgement!');
            resolve(game);
          });
        });
      });
    },

    _checkGameStatus(game) {
      GameResponse.find({ 'gameId': game._id }).lean().exec((err, results) => {
        if (game.playerIds.length !== results.length) return;

        const gameCounter = gameRules.processToGameCounter(results);
        if (gameRules.drawByAllPossibilites(gameCounter)) {
          messanger.notifyAboutDraw(game);
        } else if (gameRules.drawByOnlyOnePossibility(gameCounter)) {
          messanger.notifyAboutDraw(game);
        } else {
          messanger.notifyAboutWinners(game, gameRules.giveWinners(gameCounter, results));
        }
      });
    },
  };
};
<|endoftext|>


<commit_before>
import EventEmitter from 'events';
import httpProxy from 'http-proxy';
import { isFunction, isString, isNumber, isObject } from 'lodash';
import url from 'url';
import qs from 'qs';
import getBody from 'raw-body';
import config from '../config';
import getCertOption from './getCertOption';
import koaContextCallbackify from '../utils/koaContextCallbackify';
import { appLogger } from '../utils/logger';

const ensureSSL = (ssl) => {
	if (ssl && ssl.cert && ssl.key) {
		const { root } = config;
		return {
			...ssl,
			...getCertOption(root, ssl.key, ssl.cert),
		};
	}
	return ssl;
};

const MayHasBodyMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];

export default (options = {}, handleProxyContext) => {
	if (isString(options)) { options = { target: options }; }

	const {
		enable = true,
		query: queryModifier,
		contentType,
		...opts,
	} = options;

	if (!enable) { return; }

	const { ssl, target, forward } = opts;

	const isFormContent = contentType === 'application/x-www-form-urlencoded';
	const isJsonContent = contentType === 'application/json';

	ensureSSL(ssl);

	const requests = new WeakMap();
	const proxy = httpProxy.createProxyServer({ ssl });
	const dest = target || forward;

	let host;
	if (isString(dest)) { host = url.parse(dest).host; }
	else { host = dest.host; }

	const done = (proxyContext, res) => {
		if (!res.headersSent && res._getResponseTime) {
			const { key, value } = res._getResponseTime();
			res.setHeader(key, value);
		}

		if (proxyContext.done) { proxyContext.done(); }
		requests.delete(res);
	};

	proxy.on('proxyReqWs', (proxyReq, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyReqWs', proxyReq, req, res);
		}
	});

	proxy.on('proxyReq', (proxyReq, req, res) => {
		if (!res.headersSent) {
			proxyReq.setHeader('host', host);

			if (isJsonContent || isFormContent) {
				proxyReq.setHeader('Content-Type', contentType);
			}

			if (req._transformedBody) {
				const body = req._transformedBody;
				proxyReq.setHeader('Content-Length', Buffer.byteLength(body));
				proxyReq.write(body);
			}
		}

		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyReq', proxyReq, req, res);
		}
	});

	proxy.on('proxyRes', (proxyRes, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyRes', proxyRes, req, res);
			done(proxyContext, res);
		}
	});

	proxy.on('error', (err, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);

			appLogger.debug('[ProxyError]', err);

			if (!res.headersSent) {
				if (isFunction(proxyContext.errorHandler)) {
					proxyContext.errorHandler(err, req, res);
				}
				else {
					res.setHeader('Content-Type', 'application/json');
					res.statusCode = isNumber(err.status) ? err.status : 500;
					res.statusMessage = 'ECONNREFUSED';
					res.end(JSON.stringify({ message: 'ECONNREFUSED' }));
				}
			}

			done(proxyContext, res);
		}
	});

	const modifyQuery = (ctx) => {
		if (!queryModifier) { return; }

		const urlObject = url.parse(ctx.req.url);
		let query = qs.parse(urlObject.query);
		let queryAlt = queryModifier;

		if (isFunction(queryAlt)) {
			query = queryAlt(query, ctx);
		}
		else {
			if (isString(queryAlt)) {
				queryAlt = qs.parse(queryAlt);
			}

			if (isObject(queryAlt)) {
				Object.assign(query, queryAlt);
			}
		}

		if (isObject(query)) { query = qs.stringify(query); }

		Reflect.deleteProperty(urlObject, 'search');
		Reflect.deleteProperty(urlObject, 'query');
		urlObject.query = query;
		if (query) { urlObject.search = `?${query}`; }

		ctx.req.url = url.format(urlObject);
	};

	const maybeTransformBody = async (ctx) => {
		if (!isFormContent && !isJsonContent) { return; }

		const originContentType = ctx.get('Content-Type');
		if (contentType === originContentType) { return; }

		if (!MayHasBodyMethods.includes(ctx.method.toUpperCase())) { return; }

		let body = await getBody(ctx.req);

		if (isFormContent) {
			body = qs.stringify(JSON.parse(body.toString()));
		}
		else if (isJsonContent) {
			body = JSON.stringify(qs.parse(body.toString()));
		}

		ctx.req._transformedBody = body;
	};

	const proxyMiddleware = async (ctx) => {

		await maybeTransformBody(ctx);

		modifyQuery(ctx);
		koaContextCallbackify(ctx);

		proxy.web(ctx.req, ctx.res, opts);

		await new Promise((resolve) => {
			var proxyContext = new EventEmitter();
			proxyContext.done = resolve;
			if (isFunction(handleProxyContext)) {
				handleProxyContext(proxyContext);
			}
			requests.set(ctx.res, proxyContext);
		});
	};

	return proxyMiddleware;
};
<commit_msg>use querystring insteadof qs<commit_after>
import EventEmitter from 'events';
import httpProxy from 'http-proxy';
import { isFunction, isString, isNumber, isObject } from 'lodash';
import url from 'url';
import qs from 'querystring';
import getBody from 'raw-body';
import config from '../config';
import getCertOption from './getCertOption';
import koaContextCallbackify from '../utils/koaContextCallbackify';
import { appLogger } from '../utils/logger';

const ensureSSL = (ssl) => {
	if (ssl && ssl.cert && ssl.key) {
		const { root } = config;
		return {
			...ssl,
			...getCertOption(root, ssl.key, ssl.cert),
		};
	}
	return ssl;
};

const MayHasBodyMethods = ['POST', 'PUT', 'PATCH', 'DELETE'];

export default (options = {}, handleProxyContext) => {
	if (isString(options)) { options = { target: options }; }

	const {
		enable = true,
		query: queryModifier,
		contentType,
		...opts,
	} = options;

	if (!enable) { return; }

	const { ssl, target, forward } = opts;

	const isFormContent = contentType === 'application/x-www-form-urlencoded';
	const isJsonContent = contentType === 'application/json';

	ensureSSL(ssl);

	const requests = new WeakMap();
	const proxy = httpProxy.createProxyServer({ ssl });
	const dest = target || forward;

	let host;
	if (isString(dest)) { host = url.parse(dest).host; }
	else { host = dest.host; }

	const done = (proxyContext, res) => {
		if (!res.headersSent && res._getResponseTime) {
			const { key, value } = res._getResponseTime();
			res.setHeader(key, value);
		}

		if (proxyContext.done) { proxyContext.done(); }
		requests.delete(res);
	};

	proxy.on('proxyReqWs', (proxyReq, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyReqWs', proxyReq, req, res);
		}
	});

	proxy.on('proxyReq', (proxyReq, req, res) => {
		if (!res.headersSent) {
			proxyReq.setHeader('host', host);

			if (isJsonContent || isFormContent) {
				proxyReq.setHeader('Content-Type', contentType);
			}

			if (req._transformedBody) {
				const body = req._transformedBody;
				proxyReq.setHeader('Content-Length', Buffer.byteLength(body));
				proxyReq.write(body);
			}
		}

		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyReq', proxyReq, req, res);
		}
	});

	proxy.on('proxyRes', (proxyRes, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);
			proxyContext.emit('proxyRes', proxyRes, req, res);
			done(proxyContext, res);
		}
	});

	proxy.on('error', (err, req, res) => {
		if (requests.has(res)) {
			const proxyContext = requests.get(res);

			appLogger.debug('[ProxyError]', err);

			if (!res.headersSent) {
				if (isFunction(proxyContext.errorHandler)) {
					proxyContext.errorHandler(err, req, res);
				}
				else {
					res.setHeader('Content-Type', 'application/json');
					res.statusCode = isNumber(err.status) ? err.status : 500;
					res.statusMessage = 'ECONNREFUSED';
					res.end(JSON.stringify({ message: 'ECONNREFUSED' }));
				}
			}

			done(proxyContext, res);
		}
	});

	const modifyQuery = (ctx) => {
		if (!queryModifier) { return; }

		const urlObject = url.parse(ctx.req.url);
		let query = qs.parse(urlObject.query);
		let queryAlt = queryModifier;

		if (isFunction(queryAlt)) {
			query = queryAlt(query, ctx);
		}
		else {
			if (isString(queryAlt)) {
				queryAlt = qs.parse(queryAlt);
			}

			if (isObject(queryAlt)) {
				Object.assign(query, queryAlt);
			}
		}

		if (isObject(query)) { query = qs.stringify(query); }

		Reflect.deleteProperty(urlObject, 'search');
		Reflect.deleteProperty(urlObject, 'query');
		urlObject.query = query;
		if (query) { urlObject.search = `?${query}`; }

		ctx.req.url = url.format(urlObject);
	};

	const maybeTransformBody = async (ctx) => {
		if (!isFormContent && !isJsonContent) { return; }

		const originContentType = ctx.get('Content-Type');
		if (contentType === originContentType) { return; }

		if (!MayHasBodyMethods.includes(ctx.method.toUpperCase())) { return; }

		let body = await getBody(ctx.req);

		if (isFormContent) {
			body = qs.stringify(JSON.parse(body.toString()));
		}
		else if (isJsonContent) {
			body = JSON.stringify(qs.parse(body.toString()));
		}

		ctx.req._transformedBody = body;
	};

	const proxyMiddleware = async (ctx) => {

		await maybeTransformBody(ctx);

		modifyQuery(ctx);
		koaContextCallbackify(ctx);

		proxy.web(ctx.req, ctx.res, opts);

		await new Promise((resolve) => {
			var proxyContext = new EventEmitter();
			proxyContext.done = resolve;
			if (isFunction(handleProxyContext)) {
				handleProxyContext(proxyContext);
			}
			requests.set(ctx.res, proxyContext);
		});
	};

	return proxyMiddleware;
};
<|endoftext|>


<commit_before>const { remote } = require('electron');
const path = require('path');
const Config = require('electron-config');

const DEFAULT_BASE_DESTINATION = path.join(remote.app.getPath('videos'), 'YouTube');

const KEYS = {
  BASE_DESTINATION: 'base_destination',
};

let config;
export var init = function () {
  config = new Config();

  if (! config.has(KEYS.BASE_DESTINATION)) {
    config.set(KEYS.BASE_DESTINATION, DEFAULT_BASE_DESTINATION);
  }
};

export var clear = function () {
  config.clear();
}

export var save = function (key, value) {
  config.set(key, value);
};

export var get = function (key) {
  config.get(key);
};

export var getBaseDestination = function () {
  return config.get(KEYS.BASE_DESTINATION);
}

export var setBaseDestination = function (baseDestination) {
  config.set(KEYS.BASE_DESTINATION, baseDestination);
}
<commit_msg>Add downloads storage methods<commit_after>const { remote } = require('electron');
const path = require('path');
const Config = require('electron-config');

const DEFAULT_BASE_DESTINATION = path.join(remote.app.getPath('videos'), 'YouTube');

const KEYS = {
  BASE_DESTINATION: 'base_destination',
  DOWNLOADS: 'downloads',
};

let config;
export var init = function () {
  config = new Config();

  if (! config.has(KEYS.BASE_DESTINATION)) {
    config.set(KEYS.BASE_DESTINATION, DEFAULT_BASE_DESTINATION);
  }

  if (! config.has(KEYS.DOWNLOADS)) {
    config.set(KEYS.DOWNLOADS, {});
  }
};

export var clear = function () {
  config.clear();
}

export var save = function (key, value) {
  config.set(key, value);
};

export var get = function (key) {
  config.get(key);
};

export var getBaseDestination = function () {
  return config.get(KEYS.BASE_DESTINATION);
}

export var setBaseDestination = function (baseDestination) {
  config.set(KEYS.BASE_DESTINATION, baseDestination);
}

// Downloads
export var getDownloads = function () {
  return config.get(KEYS.DOWNLOADS);
}

export var hasVideoInDownloads = function (id) {
  return Object.keys(getDownloads()).indexOf(id) > -1;
}

export var addVideoInDownloads = function (id, info) {
  const downloads = config.get(KEYS.DOWNLOADS);
  if (hasVideoInDownloads(id)) {
    throw new Error('Already in list');
  }

  downloads[id] = info;

  config.set(KEYS.DOWNLOADS, downloads);
}

export var removeVideoFromDownloads = function (id) {
  config.delete(KEYS.DOWNLOADS + '.' + id);
}
<|endoftext|>


<commit_before>/* eslint-disable */
import axios from 'axios';
import { login } from './auth';
import config from './config';
import history from '../configuration/history';
import { parseJwt } from '../../helpers';

const headers = {
    Accept: 'application/vnd.janus.v1+json',
};

const client = axios.create({
    baseURL: process.env.NODE_ENV !== 'production' ? config.gateway.uri : process.env.REACT_APP_BASE_URL,
    headers,
});

export const setAccessToken = (token) => {
    localStorage.setItem('access_token', token);
    client.defaults.headers.common.Authorization = `Bearer ${token}`;
};

export const getAccessToken = () => {
    const token = localStorage.getItem('access_token');

    if (!token) return;

    const expirationTime = parseJwt(token).exp * 1000;
    const dateNow = new Date();

    if (expirationTime > dateNow.getTime()) {
        return token;
    }
};

export const setRefreshToken = token => localStorage.setItem('refresh_token', token);

export const getRefreshToken = () => localStorage.getItem('refresh_token');

if (getAccessToken()) {
    setAccessToken(getAccessToken());
}

client.interceptors.response.use(undefined, (error) => {
    if (error.response.status === 401) {
        // history.push('/login');
    }
    // if (error.response.status === 401 && error.config && !error.config.isRetryRequest) {
    //     return login(config.gateway.username, config.gateway.password).then((response) => {
    //         error.config.isRetryRequest = true;
    //         error.config.headers.Authorization = `Bearer ${response.data.token}`;
    //         setAccessToken(response.data.token);
    //         return client(error.config);
    //     });
    // }
});

export default client;
<commit_msg>uncomment<commit_after>/* eslint-disable */
import axios from 'axios';
import { login } from './auth';
import config from './config';
import history from '../configuration/history';
import { parseJwt } from '../../helpers';

const headers = {
    Accept: 'application/vnd.janus.v1+json',
};

const client = axios.create({
    baseURL: process.env.NODE_ENV !== 'production' ? config.gateway.uri : process.env.REACT_APP_BASE_URL,
    headers,
});

export const setAccessToken = (token) => {
    localStorage.setItem('access_token', token);
    client.defaults.headers.common.Authorization = `Bearer ${token}`;
};

export const getAccessToken = () => {
    const token = localStorage.getItem('access_token');

    if (!token) return;

    const expirationTime = parseJwt(token).exp * 1000;
    const dateNow = new Date();

    if (expirationTime > dateNow.getTime()) {
        return token;
    }
};

export const setRefreshToken = token => localStorage.setItem('refresh_token', token);

export const getRefreshToken = () => localStorage.getItem('refresh_token');

if (getAccessToken()) {
    setAccessToken(getAccessToken());
}

client.interceptors.response.use(undefined, (error) => {
    if (error.response.status === 401) {
        history.push('/login');
    }
    // if (error.response.status === 401 && error.config && !error.config.isRetryRequest) {
    //     return login(config.gateway.username, config.gateway.password).then((response) => {
    //         error.config.isRetryRequest = true;
    //         error.config.headers.Authorization = `Bearer ${response.data.token}`;
    //         setAccessToken(response.data.token);
    //         return client(error.config);
    //     });
    // }
});

export default client;
<|endoftext|>


<commit_before>import React from "react";
import { lifecycle, compose, branch } from "recompose";
import { withRouter, Link } from "react-router-dom";
import {
  MenuItem,
  MenuDivider,
  Tooltip,
  KeyCombo,
  ContextMenu,
  Menu,
  Classes,
  Icon
} from "@blueprintjs/core";
import { startCase, omit } from "lodash";

const noop = () => {};

// https://github.com/palantir/blueprint/issues/2820
function MenuItemLink({ text, onClick, icon, navTo }) {
  const handleLinkClick = e => {
    e.target.closest(`.${Classes.POPOVER_DISMISS}`).click();
  };

  return (

      <Link onClick={handleLinkClick} to={navTo} className="bp3-menu-item">
        {icon && <Icon icon={icon} />}

{text}

      </Link>

  );
}

// Enhanced MenuItem that supports history-based navigation when passed a
// `navTo` prop
export const EnhancedMenuItem = compose(
  lifecycle({
    componentDidMount: function() {
      const { didMount = noop, className } = this.props;
      didMount({ className });
    },
    componentWillUnmount: function() {
      const { willUnmount = noop, className } = this.props;
      willUnmount({ className });
    }
  }),
  branch(({ navTo }) => navTo, withRouter)
)(function({ navTo, context, staticContext, didMount, willUnmount, ...props }) {
  let MenuItemComp = MenuItem;
  if (navTo) {
    MenuItemComp = MenuItemLink;
  }

  return (
    <MenuItemComp
      popoverProps={{
        autoFocus: false
      }}
      navTo={navTo}
      {...props}
    />
  );
});

// First Non-Undefined
function fnu(...args) {
  return args.find(v => v !== undefined);
}

// Sets a tick icon if items has a `checked` prop
export const tickMenuEnhancer = def => {
  const out = { ...def };
  if (out.checked !== undefined) {
    out.icon = out.checked ? "small-tick" : "blank";
  }
  return out;
};

// Derives various menu item props based on command objects matched via the `cmd`
// prop. Derived props include `text`, `icon`, `hotkey`, `onClick` and `disabled`.
export const commandMenuEnhancer = (commands, config = {}) => (
  def,
  context
) => {
  const cmdId = typeof def === "string" ? def : def.cmd;
  let item = typeof def === "string" ? { cmd: def } : { ...def };

  const useTicks = fnu(item.useTicks, config.useTicks);
  delete item.useTicks;

  if (cmdId && commands[cmdId] && def.divider === undefined) {
    const command = commands[cmdId];

    const { isActive, isDisabled, isHidden } = command;
    const toggles = isActive !== undefined;

    item.hidden = fnu(item.hidden, isHidden);
    item.disabled = fnu(item.disabled, isDisabled);

    item.key = item.key || cmdId;
    item.submenu = item.submenu || command.submenu;

    if (toggles) {
      if (useTicks) {
        item.text = item.text || command.shortName || command.name;
        item.checked = item.checked || isActive;
      } else {
        item.text =
          item.text ||
          (isActive ? command.name : command.inactiveName || command.name);
        item.icon =
          item.icon ||
          (isActive ? command.icon : command.inactiveIcon || command.icon);
      }
    } else {
      item.text = item.text || command.name;
      item.icon = item.icon || command.icon;
    }

    item.hotkey = item.hotkey || command.hotkey;
    if (!item.onClick) {
      item.onClick = event =>
        command.execute({
          event,
          context,
          menuItem: item,
          viaMenu: true
        });
    }
  } else if (cmdId && !commands[cmdId]) {
    item.text = item.text || startCase(cmdId);
    item.disabled = true;
  }

  if (config.omitIcons) {
    item.icon = undefined;
  }

  if (config.forceIconAlignment !== false) {
    item.icon = item.icon || "blank";
  }

  if (useTicks) {
    item = tickMenuEnhancer(item);
  }

  return item;
};

const ident = x => x;

const dividerShorthandEnhancer = def =>
  typeof def === "string" && def.startsWith("--")
    ? { divider: def.substr(2) }
    : def;

// filter out unwanted attributes here! we won't want these to show up on the dom element or react will give nasty warnings
const unwantedAttrs = [
  "submenu",
  "hotkey",
  "showInSearchMenu",
  "hideFromMenuSearch"
];

/** A menu item component that adds many features over the standard MenuItem,
 * and allows for dynamic menu structures that are computed efficiently (only
 * visible sections are computed and rendered).
 * TODO: document and add examples
 */
export const DynamicMenuItem = ({
  def,
  enhancers = [ident],
  context,
  doNotEnhanceTopLevelItem
}) => {
  // If passed an element instead of a menu item definition, return it.
  // This allows mixing menu item elements and menu item defs, and makes it
  // safe to call menu creation utils with their own output.
  if (React.isValidElement(def)) return def;

  const item = [
    dividerShorthandEnhancer,
    ...(doNotEnhanceTopLevelItem ? [ident] : enhancers)
  ].reduce((v, f) => f(v, context), def);
  let out;

  if (item.divider !== undefined) {
    out = <MenuDivider {...(item.divider ? { title: item.divider } : {})} />;
  } else {
    const ItemComponent = item.component || EnhancedMenuItem;
    out = (
      <ItemComponent
        // filter out unwanted attributes here!
        {...omit(item, unwantedAttrs)}
        context={context}
        icon={item.icon || item.iconName}
        labelElement={item.hotkey && <KeyCombo minimal combo={item.hotkey} />}
        text={item.text}
      >
        {item.submenu
          ? item.submenu
              .filter(ident)
              .map((def, index) => (
                <DynamicMenuItem {...{ def, enhancers, context }} key={index} />
              ))
          : undefined}
      </ItemComponent>
    );
  }
  // if (item.disabled && item.disabledTooltip) {
  //   item.tooltip = def.disabledTooltip
  // }
  if (item.disabled && typeof item.disabled === "string") {
    item.tooltip = item.disabled;
  }

  if (item.tooltip) {
    out = <Tooltip content={item.tooltip}>{out}</Tooltip>;
  }

  return item.hidden ? null : out;
};

// Map the passed item definition(s) to DynamicMenuItem elements
export const createDynamicMenu = (menuDef, enhancers, context) => {
  if (menuDef instanceof Array) {
    return menuDef.map((def, index) => (
      <DynamicMenuItem {...{ def, enhancers, context }} key={index} />
    ));
  } else {
    return <DynamicMenuItem {...{ def: menuDef, enhancers, context }} />;
  }
};

// Create a "bar" menu, keeping the top level array unchanged, and only
// map their submenus to DynamicMenuItem elements
export const createDynamicBarMenu = (topMenuDef, enhancers, context) => {
  return topMenuDef.map(topLevelItem => {
    const def = { ...topLevelItem };
    if (def.submenu) {
      def.submenu = def.submenu.map((subdef, index) => (
        <DynamicMenuItem def={subdef} {...{ enhancers, context }} key={index} />
      ));
    }
    return def;
  });
};

// Shorthand for command-based menus
export const createCommandMenu = (menuDef, commands, config, context) => {
  return createDynamicMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context
  );
};

// Shorthand for command-based bar menus
export const createCommandBarMenu = (menuDef, commands, config, context) => {
  return createDynamicBarMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context
  );
};

export function showCommandContextMenu(
  menuDef,
  commands,
  config,
  event,
  onClose,
  context
) {
  return showContextMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context,
    event,
    onClose
  );
}

/**
 * TODO: update documentation. This is now an alias of createDynamicMenu
 *
 * Creates the contents of a Blueprint menu based on a given menu structure.
 *
 * The input can be an array of item objects, where each may contain:
 * text: text to show
 * key: React key to use (optional)
 * divider: indicates it's a divider instead of an item. Use an empty string
 *   for a normal divider, or some label text for a labeled one
 * icon: name of icon to show (optional)
 * label: right-aligned label, used mostly for shortcuts (optional)
 * hotkey: right-aligned label formatted with <KeyCombo> (optional)
 * tooltip: tooltip text to use (optional)
 * submenu: nested menu structure describing submenu (i.e. array of item objects),
 *   or array of MenuItem elements
 * onClick: click handler
 * navTo: a url to navigate to (assumes react-router)
 * href: a url to link to
 * target: link target
 *
 * Since this function is recursive (to handle nested submenus), and React
 * elements passed as input are returned unchanged, it is possible to freely mix
 * item objects and MenuItem elements. That also makes it safe to call the function
 * with its own output.
 *
 * A customize function may also be provided, and allows customization or
 * replacement of the created MenuItems, allowing for custom props or behavior.
 * That function receives the original created element and the item object, and
 * must return an element.
 *
 * Usage example:
 *
 * const menu = createMenu([
 *   { text: 'Item One', icon: 'add', onClick: () => console.info('Clicked 1') },
 *   { text: 'Item One', onClick: () => console.info('Clicked 2') },
 *   { divider: '' },
 *   { text: 'Item Three', icon: 'numerical', onClick: () => console.info('Clicked 3') },
 *   { divider: '' },
 *   { text: 'Submenus', submenu: [
 *     { text: 'Sub One' },
 *     { text: 'Sub Two' },
 *   ]},
 * ]);
 *
 */
export const createMenu = createDynamicMenu;

export function showContextMenu(
  menuDef,
  enhancers,
  event,
  onClose,
  context,
  menuComp = Menu
) {
  menuDef = filterMenuForCorrectness(menuDef);
  if (!menuDef) return;

  const MenuComponent = menuComp;
  event.persist();
  // Render a context menu at the passed event's position
  ContextMenu.show(
    <MenuComponent>
      {createDynamicMenu(menuDef, enhancers, context)}
    </MenuComponent>,
    { left: event.clientX, top: event.clientY },
    onClose
  );
  event.stopPropagation && event.stopPropagation();
  event.preventDefault && event.preventDefault();
}

function filterMenuForCorrectness(menuDef) {
  return menuDef && menuDef.length && menuDef.filter(ident);
}
<commit_msg>conditionally spread navTo prop to get rid of react unrecognized dom element prop warning<commit_after>import React from "react";
import { lifecycle, compose, branch } from "recompose";
import { withRouter, Link } from "react-router-dom";
import {
  MenuItem,
  MenuDivider,
  Tooltip,
  KeyCombo,
  ContextMenu,
  Menu,
  Classes,
  Icon
} from "@blueprintjs/core";
import { startCase, omit } from "lodash";

const noop = () => {};

// https://github.com/palantir/blueprint/issues/2820
function MenuItemLink({ text, onClick, icon, navTo }) {
  const handleLinkClick = e => {
    e.target.closest(`.${Classes.POPOVER_DISMISS}`).click();
  };

  return (

      <Link onClick={handleLinkClick} to={navTo} className="bp3-menu-item">
        {icon && <Icon icon={icon} />}

{text}

      </Link>

  );
}

// Enhanced MenuItem that supports history-based navigation when passed a
// `navTo` prop
export const EnhancedMenuItem = compose(
  lifecycle({
    componentDidMount: function() {
      const { didMount = noop, className } = this.props;
      didMount({ className });
    },
    componentWillUnmount: function() {
      const { willUnmount = noop, className } = this.props;
      willUnmount({ className });
    }
  }),
  branch(({ navTo }) => navTo, withRouter)
)(function({ navTo, context, staticContext, didMount, willUnmount, ...props }) {
  let MenuItemComp = MenuItem;
  if (navTo) {
    MenuItemComp = MenuItemLink;
  }

  return (
    <MenuItemComp
      popoverProps={{
        autoFocus: false
      }}
      {...(navTo && { navTo })}
      {...props}
    />
  );
});

// First Non-Undefined
function fnu(...args) {
  return args.find(v => v !== undefined);
}

// Sets a tick icon if items has a `checked` prop
export const tickMenuEnhancer = def => {
  const out = { ...def };
  if (out.checked !== undefined) {
    out.icon = out.checked ? "small-tick" : "blank";
  }
  return out;
};

// Derives various menu item props based on command objects matched via the `cmd`
// prop. Derived props include `text`, `icon`, `hotkey`, `onClick` and `disabled`.
export const commandMenuEnhancer = (commands, config = {}) => (
  def,
  context
) => {
  const cmdId = typeof def === "string" ? def : def.cmd;
  let item = typeof def === "string" ? { cmd: def } : { ...def };

  const useTicks = fnu(item.useTicks, config.useTicks);
  delete item.useTicks;

  if (cmdId && commands[cmdId] && def.divider === undefined) {
    const command = commands[cmdId];

    const { isActive, isDisabled, isHidden } = command;
    const toggles = isActive !== undefined;

    item.hidden = fnu(item.hidden, isHidden);
    item.disabled = fnu(item.disabled, isDisabled);

    item.key = item.key || cmdId;
    item.submenu = item.submenu || command.submenu;

    if (toggles) {
      if (useTicks) {
        item.text = item.text || command.shortName || command.name;
        item.checked = item.checked || isActive;
      } else {
        item.text =
          item.text ||
          (isActive ? command.name : command.inactiveName || command.name);
        item.icon =
          item.icon ||
          (isActive ? command.icon : command.inactiveIcon || command.icon);
      }
    } else {
      item.text = item.text || command.name;
      item.icon = item.icon || command.icon;
    }

    item.hotkey = item.hotkey || command.hotkey;
    if (!item.onClick) {
      item.onClick = event =>
        command.execute({
          event,
          context,
          menuItem: item,
          viaMenu: true
        });
    }
  } else if (cmdId && !commands[cmdId]) {
    item.text = item.text || startCase(cmdId);
    item.disabled = true;
  }

  if (config.omitIcons) {
    item.icon = undefined;
  }

  if (config.forceIconAlignment !== false) {
    item.icon = item.icon || "blank";
  }

  if (useTicks) {
    item = tickMenuEnhancer(item);
  }

  return item;
};

const ident = x => x;

const dividerShorthandEnhancer = def =>
  typeof def === "string" && def.startsWith("--")
    ? { divider: def.substr(2) }
    : def;

// filter out unwanted attributes here! we won't want these to show up on the dom element or react will give nasty warnings
const unwantedAttrs = [
  "submenu",
  "hotkey",
  "showInSearchMenu",
  "hideFromMenuSearch"
];

/** A menu item component that adds many features over the standard MenuItem,
 * and allows for dynamic menu structures that are computed efficiently (only
 * visible sections are computed and rendered).
 * TODO: document and add examples
 */
export const DynamicMenuItem = ({
  def,
  enhancers = [ident],
  context,
  doNotEnhanceTopLevelItem
}) => {
  // If passed an element instead of a menu item definition, return it.
  // This allows mixing menu item elements and menu item defs, and makes it
  // safe to call menu creation utils with their own output.
  if (React.isValidElement(def)) return def;

  const item = [
    dividerShorthandEnhancer,
    ...(doNotEnhanceTopLevelItem ? [ident] : enhancers)
  ].reduce((v, f) => f(v, context), def);
  let out;

  if (item.divider !== undefined) {
    out = <MenuDivider {...(item.divider ? { title: item.divider } : {})} />;
  } else {
    const ItemComponent = item.component || EnhancedMenuItem;
    out = (
      <ItemComponent
        // filter out unwanted attributes here!
        {...omit(item, unwantedAttrs)}
        context={context}
        icon={item.icon || item.iconName}
        labelElement={item.hotkey && <KeyCombo minimal combo={item.hotkey} />}
        text={item.text}
      >
        {item.submenu
          ? item.submenu
              .filter(ident)
              .map((def, index) => (
                <DynamicMenuItem {...{ def, enhancers, context }} key={index} />
              ))
          : undefined}
      </ItemComponent>
    );
  }
  // if (item.disabled && item.disabledTooltip) {
  //   item.tooltip = def.disabledTooltip
  // }
  if (item.disabled && typeof item.disabled === "string") {
    item.tooltip = item.disabled;
  }

  if (item.tooltip) {
    out = <Tooltip content={item.tooltip}>{out}</Tooltip>;
  }

  return item.hidden ? null : out;
};

// Map the passed item definition(s) to DynamicMenuItem elements
export const createDynamicMenu = (menuDef, enhancers, context) => {
  if (menuDef instanceof Array) {
    return menuDef.map((def, index) => (
      <DynamicMenuItem {...{ def, enhancers, context }} key={index} />
    ));
  } else {
    return <DynamicMenuItem {...{ def: menuDef, enhancers, context }} />;
  }
};

// Create a "bar" menu, keeping the top level array unchanged, and only
// map their submenus to DynamicMenuItem elements
export const createDynamicBarMenu = (topMenuDef, enhancers, context) => {
  return topMenuDef.map(topLevelItem => {
    const def = { ...topLevelItem };
    if (def.submenu) {
      def.submenu = def.submenu.map((subdef, index) => (
        <DynamicMenuItem def={subdef} {...{ enhancers, context }} key={index} />
      ));
    }
    return def;
  });
};

// Shorthand for command-based menus
export const createCommandMenu = (menuDef, commands, config, context) => {
  return createDynamicMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context
  );
};

// Shorthand for command-based bar menus
export const createCommandBarMenu = (menuDef, commands, config, context) => {
  return createDynamicBarMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context
  );
};

export function showCommandContextMenu(
  menuDef,
  commands,
  config,
  event,
  onClose,
  context
) {
  return showContextMenu(
    menuDef,
    [commandMenuEnhancer(commands, config)],
    context,
    event,
    onClose
  );
}

/**
 * TODO: update documentation. This is now an alias of createDynamicMenu
 *
 * Creates the contents of a Blueprint menu based on a given menu structure.
 *
 * The input can be an array of item objects, where each may contain:
 * text: text to show
 * key: React key to use (optional)
 * divider: indicates it's a divider instead of an item. Use an empty string
 *   for a normal divider, or some label text for a labeled one
 * icon: name of icon to show (optional)
 * label: right-aligned label, used mostly for shortcuts (optional)
 * hotkey: right-aligned label formatted with <KeyCombo> (optional)
 * tooltip: tooltip text to use (optional)
 * submenu: nested menu structure describing submenu (i.e. array of item objects),
 *   or array of MenuItem elements
 * onClick: click handler
 * navTo: a url to navigate to (assumes react-router)
 * href: a url to link to
 * target: link target
 *
 * Since this function is recursive (to handle nested submenus), and React
 * elements passed as input are returned unchanged, it is possible to freely mix
 * item objects and MenuItem elements. That also makes it safe to call the function
 * with its own output.
 *
 * A customize function may also be provided, and allows customization or
 * replacement of the created MenuItems, allowing for custom props or behavior.
 * That function receives the original created element and the item object, and
 * must return an element.
 *
 * Usage example:
 *
 * const menu = createMenu([
 *   { text: 'Item One', icon: 'add', onClick: () => console.info('Clicked 1') },
 *   { text: 'Item One', onClick: () => console.info('Clicked 2') },
 *   { divider: '' },
 *   { text: 'Item Three', icon: 'numerical', onClick: () => console.info('Clicked 3') },
 *   { divider: '' },
 *   { text: 'Submenus', submenu: [
 *     { text: 'Sub One' },
 *     { text: 'Sub Two' },
 *   ]},
 * ]);
 *
 */
export const createMenu = createDynamicMenu;

export function showContextMenu(
  menuDef,
  enhancers,
  event,
  onClose,
  context,
  menuComp = Menu
) {
  menuDef = filterMenuForCorrectness(menuDef);
  if (!menuDef) return;

  const MenuComponent = menuComp;
  event.persist();
  // Render a context menu at the passed event's position
  ContextMenu.show(
    <MenuComponent>
      {createDynamicMenu(menuDef, enhancers, context)}
    </MenuComponent>,
    { left: event.clientX, top: event.clientY },
    onClose
  );
  event.stopPropagation && event.stopPropagation();
  event.preventDefault && event.preventDefault();
}

function filterMenuForCorrectness(menuDef) {
  return menuDef && menuDef.length && menuDef.filter(ident);
}
<|endoftext|>


<commit_before>var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();

exports.handler = function(event, context) {
    console.log(JSON.stringify(event, null, '  '));

    var bname = event.name.replace(/\W/g, '');
    bname = bname.charAt(0).toUpperCase() + bname.slice(1);

    var n = dynamodb.getItem({
        "TableName": "baby-names",
        "Key" : {
            name : bname
        }
    });

    if (n.votes >= 0){
        dynamodb.updateItem({
            "TableName": "baby-names",
            "Key" : {
                name : bname
            },
            "UpdateExpression" : "SET votes = votes + :a",
            "ExpressionAttributeValues" : {
                ":a" : 1
            }
        }, function(err, data) {
            if (err) {
                context.done('error putting item into dynamodb failed: '+err);
            } else {
                console.log('success: '+JSON.stringify(data, null, '  '));
                context.done();
            }
        });
    } else {
        console.log('blocking upvote on blacklisted name: '+bname);
    }
};<commit_msg>Removed blacklisting. Doesn't seem to be working<commit_after>var doc = require('dynamodb-doc');
var dynamodb = new doc.DynamoDB();

exports.handler = function(event, context) {
    console.log(JSON.stringify(event, null, '  '));

    var bname = event.name.replace(/\W/g, '');
    bname = bname.charAt(0).toUpperCase() + bname.slice(1);

    dynamodb.updateItem({
        "TableName": "baby-names",
		"Key" : {
			name : bname
		},
		"UpdateExpression" : "SET votes = votes + :a",
		"ExpressionAttributeValues" : {
			":a" : 1
		}
	}, function(err, data) {
		if (err) {
			context.done('error putting item into dynamodb failed: '+err);
		} else {
			console.log('success: '+JSON.stringify(data, null, '  '));
			context.done();
		}
	});
};<|endoftext|>


<commit_before>'use strict'

module.exports = function () {
  var init = function (scope, elem, attrs, formField) {
    // add watchers for any logical functions which need to be executed based on a form variable
    if (formField.skipLogic.func && formField.skipLogic.func.watchingVars) {
      formField.skipLogic.func.watchingVars.forEach(function (watchingVar, key) {
        var varToWatch = 'form.' + watchingVar + '.$viewValue'
        scope.$watch(varToWatch, function (value, oldValue) {
          var params = formField.skipLogic.func.params
          var paramsObj = {}
          for (var p = 0; p < params.length; p++) {
            if (scope.form[params[p]]) {
              paramsObj[params[p]] = scope.form[params[p]].$modelValue
            } else {
              if (typeof params[p] === 'object') {
                for (var key in params[p]) {
                  if (params[p].hasOwnProperty(key)) {
                    paramsObj[key] = params[p][key]
                  }
                }
              } else {
                paramsObj[params[p]] = params[p]
              }
            }
          }

          if (typeof formField.skipLogic.func.execute === 'function') {
            var funcVal = formField.skipLogic.func.execute(paramsObj)
            scope.form[scope.field.name].$setViewValue(funcVal)
            scope.form[scope.field.name].$setUntouched()
            scope.form[scope.field.name].$setPristine()
            scope.form[scope.field.name].$render()
          }
        })
      })
    }

    // add watchers for any logic checks (show/hide)
    if (formField.skipLogic.checks.length > 0) {
      for (var i = 0; i < formField.skipLogic.checks.length; i++) {
        var check = formField.skipLogic.checks[i]
        if (check && check.group) {
          for (var j = 0; j < check.group.length; j++) {
            scope.$watch(check.group[j].variable, function (value, oldValue) {
              skipLogicGroupCheck(scope, check)
            }, true)
          }
        } else {
          scope.$watch(check.variable, function (value, oldValue) {
            skipLogicOperandCheck(scope, value, check)
          }, true)
        }
      }
    }
  }

  var operators = {
    '=': function (a, b) { return a === b },
    '!=': function (a, b) { return a !== b },
    '<': function (a, b) { return a < b },
    '<=': function (a, b) { return a <= b },
    '>': function (a, b) { return a > b },
    '>=': function (a, b) { return a >= b },

    'in': function (a, b) {
      if (b.indexOf(a) >= 0) {
        return true
      }
      return false
    },
    '!in': function (a, b) {
      if (b.indexOf(a) === -1) {
        return true
      }
      return false
    },

    'contains': function (a, b) {
      if (!a) {
        return false
      }
      return (a.indexOf(b) >= 0)
    },
    '!contains': function (a, b) {
      if (!a) {
        return true
      }
      return (a.indexOf(b) === -1)
    }
  }

  var skipLogicOperandCheck = function (scope, value, check) {
    skipLogicCheck(check.action, operators[check.operand](value, check.value), scope)
  }

  var skipLogicCheck = function (action, check, scope) {
    switch (action) {
      case 'checkPhoneNumber':
        if (check) {
          scope.field.settings.checkPhoneNumber = true
        } else {
          scope.field.settings.checkPhoneNumber = false
        }
        break
      case 'checkIdNumber':
        if (check) {
          scope.field.settings.checkIdNumber = true
        } else {
          scope.field.settings.checkIdNumber = false
        }
        break

      case 'disabled':
        if (check) {
          scope.field.settings.disabled = true
        } else {
          scope.field.settings.disabled = false
        }
        break
      case 'required':
        if (check) {
          scope.field.settings.required = true
        } else {
          scope.field.settings.required = false
        }
        break
      case 'showhide':
      default:
        if (check) {
          scope.field.show = true
        } else {
          scope.field.show = false
        }
    }
  }

  // TODO do a complex (more than one depth) groups, probably xor xnor would handle this
  var skipLogicGroupCheck = function (scope, check) {
    var logicGate = check.logicGate
    var checkEval = null
    for (var i = 0; i < check.group.length; i++) {
      var c = check.group[i]
      var fieldVariableSplit = c.variable.split('.')
      var value
      switch (fieldVariableSplit[0]) {
        case 'form':
          value = scope.form[fieldVariableSplit[1]][fieldVariableSplit[2]]
          break
        case 'globals':
          var property = c.variable.replace('globals.', '')
          var propertyArry = property.split('.')
          var newValObj = JSON.parse(JSON.stringify(scope.globals))
          propertyArry.forEach(function (prop) {
            newValObj = newValObj[prop]
          })
          value = newValObj
          break
        default:
          break
      }

      // console.log(value)
      if (checkEval !== null) {
        if (logicGate === 'and') {
          checkEval = checkEval && operators[c.operand](value, c.value)
        } else if (logicGate === 'or') {
          checkEval = checkEval || operators[c.operand](value, c.value)
        }
      } else {
        checkEval = operators[c.operand](value, c.value)
      }
    }
    skipLogicCheck(check.action, checkEval, scope)
  }

  return {
    init: init,

    operators: operators,
    skipLogicOperandCheck: skipLogicOperandCheck,
    skipLogicGroupCheck: skipLogicGroupCheck
  }
}
<commit_msg>Removed commeneted out code<commit_after>'use strict'

module.exports = function () {
  var init = function (scope, elem, attrs, formField) {
    // add watchers for any logical functions which need to be executed based on a form variable
    if (formField.skipLogic.func && formField.skipLogic.func.watchingVars) {
      formField.skipLogic.func.watchingVars.forEach(function (watchingVar, key) {
        var varToWatch = 'form.' + watchingVar + '.$viewValue'
        scope.$watch(varToWatch, function (value, oldValue) {
          var params = formField.skipLogic.func.params
          var paramsObj = {}
          for (var p = 0; p < params.length; p++) {
            if (scope.form[params[p]]) {
              paramsObj[params[p]] = scope.form[params[p]].$modelValue
            } else {
              if (typeof params[p] === 'object') {
                for (var key in params[p]) {
                  if (params[p].hasOwnProperty(key)) {
                    paramsObj[key] = params[p][key]
                  }
                }
              } else {
                paramsObj[params[p]] = params[p]
              }
            }
          }

          if (typeof formField.skipLogic.func.execute === 'function') {
            var funcVal = formField.skipLogic.func.execute(paramsObj)
            scope.form[scope.field.name].$setViewValue(funcVal)
            scope.form[scope.field.name].$setUntouched()
            scope.form[scope.field.name].$setPristine()
            scope.form[scope.field.name].$render()
          }
        })
      })
    }

    // add watchers for any logic checks (show/hide)
    if (formField.skipLogic.checks.length > 0) {
      for (var i = 0; i < formField.skipLogic.checks.length; i++) {
        var check = formField.skipLogic.checks[i]
        if (check && check.group) {
          for (var j = 0; j < check.group.length; j++) {
            scope.$watch(check.group[j].variable, function (value, oldValue) {
              skipLogicGroupCheck(scope, check)
            }, true)
          }
        } else {
          scope.$watch(check.variable, function (value, oldValue) {
            skipLogicOperandCheck(scope, value, check)
          }, true)
        }
      }
    }
  }

  var operators = {
    '=': function (a, b) { return a === b },
    '!=': function (a, b) { return a !== b },
    '<': function (a, b) { return a < b },
    '<=': function (a, b) { return a <= b },
    '>': function (a, b) { return a > b },
    '>=': function (a, b) { return a >= b },

    'in': function (a, b) {
      if (b.indexOf(a) >= 0) {
        return true
      }
      return false
    },
    '!in': function (a, b) {
      if (b.indexOf(a) === -1) {
        return true
      }
      return false
    },

    'contains': function (a, b) {
      if (!a) {
        return false
      }
      return (a.indexOf(b) >= 0)
    },
    '!contains': function (a, b) {
      if (!a) {
        return true
      }
      return (a.indexOf(b) === -1)
    }
  }

  var skipLogicOperandCheck = function (scope, value, check) {
    skipLogicCheck(check.action, operators[check.operand](value, check.value), scope)
  }

  var skipLogicCheck = function (action, check, scope) {
    switch (action) {
      case 'checkPhoneNumber':
        if (check) {
          scope.field.settings.checkPhoneNumber = true
        } else {
          scope.field.settings.checkPhoneNumber = false
        }
        break
      case 'checkIdNumber':
        if (check) {
          scope.field.settings.checkIdNumber = true
        } else {
          scope.field.settings.checkIdNumber = false
        }
        break

      case 'disabled':
        if (check) {
          scope.field.settings.disabled = true
        } else {
          scope.field.settings.disabled = false
        }
        break
      case 'required':
        if (check) {
          scope.field.settings.required = true
        } else {
          scope.field.settings.required = false
        }
        break
      case 'showhide':
      default:
        if (check) {
          scope.field.show = true
        } else {
          scope.field.show = false
        }
    }
  }

  // TODO do a complex (more than one depth) groups, probably xor xnor would handle this
  var skipLogicGroupCheck = function (scope, check) {
    var logicGate = check.logicGate
    var checkEval = null
    for (var i = 0; i < check.group.length; i++) {
      var c = check.group[i]
      var fieldVariableSplit = c.variable.split('.')
      var value
      switch (fieldVariableSplit[0]) {
        case 'form':
          value = scope.form[fieldVariableSplit[1]][fieldVariableSplit[2]]
          break
        case 'globals':
          var property = c.variable.replace('globals.', '')
          var propertyArry = property.split('.')
          var newValObj = JSON.parse(JSON.stringify(scope.globals))
          propertyArry.forEach(function (prop) {
            newValObj = newValObj[prop]
          })
          value = newValObj
          break
        default:
          break
      }

      if (checkEval !== null) {
        if (logicGate === 'and') {
          checkEval = checkEval && operators[c.operand](value, c.value)
        } else if (logicGate === 'or') {
          checkEval = checkEval || operators[c.operand](value, c.value)
        }
      } else {
        checkEval = operators[c.operand](value, c.value)
      }
    }
    skipLogicCheck(check.action, checkEval, scope)
  }

  return {
    init: init,

    operators: operators,
    skipLogicOperandCheck: skipLogicOperandCheck,
    skipLogicGroupCheck: skipLogicGroupCheck
  }
}
<|endoftext|>


<commit_before>/**!
 * AngularJS file upload/drop directive with http post and progress
 * @author  Danial  <danial.farid@gmail.com>
 * @version 1.0.2
 */
(function() {

var angularFileUpload = angular.module('angularFileUpload', []);

angularFileUpload.html5 = !!window.FormData;

if (!angularFileUpload.html5) {
	(function () {
		//load FileAPI
		if (!window.FileAPI || !FileAPI.upload) {
			var base = '', script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index;
			if (window.FileAPI && window.FileAPI.jsPath) {
				base = window.FileAPI.jsPath;
			} else {
				for (i = 0; i < allScripts.length; i++) {
					index = allScripts[i].src.indexOf('angular-file-upload.js')
					if (index == -1) {
						index = allScripts[i].src.indexOf('angular-file-upload.min.js');
					}
					if (index > -1) {
						base = allScripts[i].src.substring(0, index);
						break;
					}
				}
			}

			if (!window.FileAPI || FileAPI.staticPath == null) {
				FileAPI = {
					staticPath: base
				}
			}

			script.setAttribute('src', base + 'FileAPI.min.js');
			document.getElementsByTagName('head')[0].appendChild(script);
		}
	})();
}

angularFileUpload.XMLHttpRequest = function() {
	if (!angularFileUpload.html5) {
		window.FormData = FormData = function() {
			return {
				append: function(key, val) {
					this[key] = val;
				}
			};
		};
		var xhr = {
			onreadystatechange: function(){},
			headers: {},
			responseHeaders: {},
			config: {
				complete: function(err, x) {
					xhr.status = x.status;
					xhr.readyState = 4;
					xhr.responseHeaders = x.getAllResponseHeaders();
					xhr.responseText = x.responseText;
					xhr.onreadystatechange();
				}
			},
			getAllResponseHeaders: function() {
				return this.responseHeaders;
			},
			setRequestHeader: function(key, value) {
				this.headers[key] = value;
			},
			open: function(method, url, b) {
				this.config.url = url;
			},
			upload: {
				addEventListener: function(evt, listener) {
					xhr.config.progress = listener;
				}
			},
			send: function(formData) {
				this.config.files = {
					file : formData.file
				};
				this.config.data = {}
				for (key in formData) {
					if (key != 'file' && key != 'append') {
						this.config.data[key] = formData[key];
					}
				}
				this.config.headers = this.headers;
				FileAPI.upload(this.config);
			},
			readyState: 0,
			status: 0,
			responseText: null
		};
		return xhr;
	} else {
		return new XMLHttpRequest();
	}
};

angularFileUpload.defineHttpUploadFile = function($http) {
	if (!$http.uploadFile) {
		$http.uploadFile = function(config) {
			var xhr = new angularFileUpload.XMLHttpRequest(), then, success, error, progress, response,
				formData = new FormData();
			formData.append(config.fileFormDataName || 'file', config.file);
			for (key in config.data) {
				formData.append(key, config.data[key]);
			}
			xhr.open(config.method || 'POST', config.url, true);

			config.headers = config.headers || {};
			for (key in config.headers) {
				xhr.setRequestHeader(key, config.headers[key]);
			}

			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/,
						data = xhr.responseText, responseHeaders = xhr.getAllResponseHeaders();
					if (typeof data == 'string') {
						// strip json vulnerability protection prefix
						data = data.replace(PROTECTION_PREFIX, '');
						if (JSON_START.test(data) && JSON_END.test(data))
							data = (typeof data === 'string') ? JSON.parse(data) : data;
					}
			        if (200 <= xhr.status && xhr.status < 300) {
						if (then) then(data, xhr.status, responseHeaders, config);
						if (success) success(data, xhr.status, responseHeaders, config);
					} else {
						if (error) error(data, xhr.status, responseHeaders, config);
					}
				}
			}

			xhr.upload.addEventListener('progress', function(e) {
				if (progress) progress(e);
			}, false);

			response = {
				then: function(func) {
					then = func;
					return response;
				},
				success: function(func) {
					success = func;
					return response;
				},
				error: function(func) {
					error = func;
					return response;
				},
				progress: function(func) {
					progress = func;
					return response;
				}
			};

			xhr.send(formData);

			return response;
		};
	}
}

angularFileUpload.directive('ngFileSelect', [ '$parse', '$http', function($parse, $http) {
	angularFileUpload.defineHttpUploadFile($http);

	return function(scope, elem, attr) {
		var fn = $parse(attr['ngFileSelect']);
		if (!angularFileUpload.html5) {
			elem.wrap('
');
		}
		elem.bind('change', function(evt) {
			var files = [], fileList, i;
			if (!angularFileUpload.html5) {
				files = FileAPI.getFiles(evt);
			} else {
				fileList = evt.target.files;
				if (fileList != null) {
					for (i = 0; i < fileList.length; i++) {
						files.push(fileList.item(i));
					}
				}
			}
			scope.$apply(function() {
				fn(scope, {
					$files : files,
					$event : evt
				});
			});
		});
	};
} ]);

angularFileUpload.directive('ngFileDropAvailable', [ '$parse', '$http', function($parse, $http) {
	return function(scope, elem, attr) {
		if ('draggable' in document.createElement('span')) {
			var fn = $parse(attr['ngFileDropAvailable']);
			if(!scope.$$phase) {
				scope.$apply(function() {
					fn(scope);
				});
			} else {
				fn(scope)
			}
		}
	};
} ]);

angularFileUpload.directive('ngFileDrop', [ '$parse', '$http', function($parse, $http) {
	angularFileUpload.defineHttpUploadFile($http);
	return function(scope, elem, attr) {
		if ('draggable' in document.createElement('span')) {
			var fn = $parse(attr['ngFileDrop']);
			elem[0].addEventListener("dragover", function(evt) {
				evt.stopPropagation();
				evt.preventDefault();
				elem.addClass("dragover");
			}, false);
			elem[0].addEventListener("dragleave", function(evt) {
				elem.removeClass("dragover");
			}, false);
			elem[0].addEventListener("drop", function(evt) {
				evt.stopPropagation();
				evt.preventDefault();
				elem.removeClass("dragover");
				var files = [], fileList = evt.dataTransfer.files, i;
				if (fileList != null) {
					for (i = 0; i < fileList.length; i++) {
						files.push(fileList.item(i));
					}
				}
				scope.$apply(function() {
					fn(scope, {
						$files : files,
						$event : evt
					});
				});
			}, false);
		} else {
			elem.css('display', 'none');
		}
	};
} ]);

})();<commit_msg>File is now the last field in the form data<commit_after>/**!
 * AngularJS file upload/drop directive with http post and progress
 * @author  Danial  <danial.farid@gmail.com>
 * @version 1.0.2
 */
(function() {

var angularFileUpload = angular.module('angularFileUpload', []);

angularFileUpload.html5 = !!window.FormData;

if (!angularFileUpload.html5) {
	(function () {
		//load FileAPI
		if (!window.FileAPI || !FileAPI.upload) {
			var base = '', script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index;
			if (window.FileAPI && window.FileAPI.jsPath) {
				base = window.FileAPI.jsPath;
			} else {
				for (i = 0; i < allScripts.length; i++) {
					index = allScripts[i].src.indexOf('angular-file-upload.js')
					if (index == -1) {
						index = allScripts[i].src.indexOf('angular-file-upload.min.js');
					}
					if (index > -1) {
						base = allScripts[i].src.substring(0, index);
						break;
					}
				}
			}

			if (!window.FileAPI || FileAPI.staticPath == null) {
				FileAPI = {
					staticPath: base
				}
			}

			script.setAttribute('src', base + 'FileAPI.min.js');
			document.getElementsByTagName('head')[0].appendChild(script);
		}
	})();
}

angularFileUpload.XMLHttpRequest = function() {
	if (!angularFileUpload.html5) {
		window.FormData = FormData = function() {
			return {
				append: function(key, val) {
					this[key] = val;
				}
			};
		};
		var xhr = {
			onreadystatechange: function(){},
			headers: {},
			responseHeaders: {},
			config: {
				complete: function(err, x) {
					xhr.status = x.status;
					xhr.readyState = 4;
					xhr.responseHeaders = x.getAllResponseHeaders();
					xhr.responseText = x.responseText;
					xhr.onreadystatechange();
				}
			},
			getAllResponseHeaders: function() {
				return this.responseHeaders;
			},
			setRequestHeader: function(key, value) {
				this.headers[key] = value;
			},
			open: function(method, url, b) {
				this.config.url = url;
			},
			upload: {
				addEventListener: function(evt, listener) {
					xhr.config.progress = listener;
				}
			},
			send: function(formData) {
				this.config.files = {
					file : formData.file
				};
				this.config.data = {}
				for (key in formData) {
					if (key != 'file' && key != 'append') {
						this.config.data[key] = formData[key];
					}
				}
				this.config.headers = this.headers;
				FileAPI.upload(this.config);
			},
			readyState: 0,
			status: 0,
			responseText: null
		};
		return xhr;
	} else {
		return new XMLHttpRequest();
	}
};

angularFileUpload.defineHttpUploadFile = function($http) {
	if (!$http.uploadFile) {
		$http.uploadFile = function(config) {
			var xhr = new angularFileUpload.XMLHttpRequest(), then, success, error, progress, response,
				formData = new FormData();
			for (key in config.data) {
				formData.append(key, config.data[key]);
			}
			formData.append(config.fileFormDataName || 'file', config.file);
			xhr.open(config.method || 'POST', config.url, true);

			config.headers = config.headers || {};
			for (key in config.headers) {
				xhr.setRequestHeader(key, config.headers[key]);
			}

			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4) {
					var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/,
						data = xhr.responseText, responseHeaders = xhr.getAllResponseHeaders();
					if (typeof data == 'string') {
						// strip json vulnerability protection prefix
						data = data.replace(PROTECTION_PREFIX, '');
						if (JSON_START.test(data) && JSON_END.test(data))
							data = (typeof data === 'string') ? JSON.parse(data) : data;
					}
			        if (200 <= xhr.status && xhr.status < 300) {
						if (then) then(data, xhr.status, responseHeaders, config);
						if (success) success(data, xhr.status, responseHeaders, config);
					} else {
						if (error) error(data, xhr.status, responseHeaders, config);
					}
				}
			}

			xhr.upload.addEventListener('progress', function(e) {
				if (progress) progress(e);
			}, false);

			response = {
				then: function(func) {
					then = func;
					return response;
				},
				success: function(func) {
					success = func;
					return response;
				},
				error: function(func) {
					error = func;
					return response;
				},
				progress: function(func) {
					progress = func;
					return response;
				}
			};

			xhr.send(formData);

			return response;
		};
	}
}

angularFileUpload.directive('ngFileSelect', [ '$parse', '$http', function($parse, $http) {
	angularFileUpload.defineHttpUploadFile($http);

	return function(scope, elem, attr) {
		var fn = $parse(attr['ngFileSelect']);
		if (!angularFileUpload.html5) {
			elem.wrap('
');
		}
		elem.bind('change', function(evt) {
			var files = [], fileList, i;
			if (!angularFileUpload.html5) {
				files = FileAPI.getFiles(evt);
			} else {
				fileList = evt.target.files;
				if (fileList != null) {
					for (i = 0; i < fileList.length; i++) {
						files.push(fileList.item(i));
					}
				}
			}
			scope.$apply(function() {
				fn(scope, {
					$files : files,
					$event : evt
				});
			});
		});
	};
} ]);

angularFileUpload.directive('ngFileDropAvailable', [ '$parse', '$http', function($parse, $http) {
	return function(scope, elem, attr) {
		if ('draggable' in document.createElement('span')) {
			var fn = $parse(attr['ngFileDropAvailable']);
			if(!scope.$$phase) {
				scope.$apply(function() {
					fn(scope);
				});
			} else {
				fn(scope)
			}
		}
	};
} ]);

angularFileUpload.directive('ngFileDrop', [ '$parse', '$http', function($parse, $http) {
	angularFileUpload.defineHttpUploadFile($http);
	return function(scope, elem, attr) {
		if ('draggable' in document.createElement('span')) {
			var fn = $parse(attr['ngFileDrop']);
			elem[0].addEventListener("dragover", function(evt) {
				evt.stopPropagation();
				evt.preventDefault();
				elem.addClass("dragover");
			}, false);
			elem[0].addEventListener("dragleave", function(evt) {
				elem.removeClass("dragover");
			}, false);
			elem[0].addEventListener("drop", function(evt) {
				evt.stopPropagation();
				evt.preventDefault();
				elem.removeClass("dragover");
				var files = [], fileList = evt.dataTransfer.files, i;
				if (fileList != null) {
					for (i = 0; i < fileList.length; i++) {
						files.push(fileList.item(i));
					}
				}
				scope.$apply(function() {
					fn(scope, {
						$files : files,
						$event : evt
					});
				});
			}, false);
		} else {
			elem.css('display', 'none');
		}
	};
} ]);

})();<|endoftext|>