<commit_before>var ft = {
	cardNumbers : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
	cardSuits : ["C", "D", "S", "H"],
	decks: 2,
	discardPile: null,
	drawPile : null,
	playStacks : [],
	dropZones : [],
	selectedCard : undefined,
	logOn : false,
	logs : [],
	undoCount : 0,
	timer : null,
	startTime : new Date(),
	moves : 0
};

ft.generateDeck = function generateDeck() {
	var deck = [];

	_.forEach(ft.cardNumbers, function(cardNumber) {
		_.forEach(ft.cardSuits, function(cardSuit) {
			deck.push(getCard(cardNumber, cardSuit));
			deck.push(getCard(cardNumber, cardSuit));
		});
	});

	//one shuffle didnt seem all that random. Similar cards seemed to beright next to each other
	deck = _(deck).shuffle().shuffle().shuffle().value();

    return deck;
};

ft.deal = function deal() {
	var deck, selector, i, j, stack;

    deck = ft.generateDeck();

    selector = '#s';
	ft.logOn = false;

    for(i = 0; i < 10; i++) {
		stack = getPlayStack(selector + i);

		ft.playStacks.push(stack);

        for(j = 0; j < 4; j++) {
            stack.pushCard(deck.pop());
        }

		stack.setup();
    }

    ft.drawPile = getDrawPile('.drawPile');
    while(deck.length > 0)
    {
        ft.drawPile.pushCard(deck.pop());
    }

    ft.discardPile = getDiscardPile('.discardPile');

	selector = '#d';
    for (i = 0; i < 8; i++) {
        stack = getDropZone(selector + i);
        ft.dropZones.push(stack);
		stack.setup();
    }

	$("#left, #right").click(deselectSelected);

	ft.logOn = true;
	ft.moves = 0;
};

function deselectSelected()
{
	if (ft.selectedCard != undefined)
        ft.selectedCard.getHtml().removeClass('selectedCard');
    ft.selectedCard = undefined;
}

/*********** Draw Pile */

function getDrawPile(sel) {
	var selector = sel;
	var stack = [];

	function pushCard(card) {
		stack.push(card);
		card.pile = this;

		if ($(selector).is(':empty')) {
			var cardBack = card.getBackHtml();
			cardBack.click(function () {
				var c = card.pile.draw();
				ft.discardPile.pushCard(c);
			});

			$(selector).append(cardBack);
		}
	}

	function draw() {
		var top = stack.pop();

		$(selector).empty();
		var nextToTop = stack.pop();

		if (nextToTop != undefined) {
			this.pushCard(nextToTop);
		}

		ft.moves++;
		return top;
	}

	return {
		draw : draw,
		pushCard : pushCard
	}
}

/********Discard Pie ********* */

function getDiscardPile(sel){
	var selector = sel;
	var stack = [];

	function draw() {
		var top = stack.pop();

		var nextToTop = stack.pop();
		if (nextToTop != undefined) {
			this.pushCard(nextToTop);
		}
		else {
			$(selector).empty();
		}

		return top;
	}

	function peekTop() {
		if (stack.length == 0)
			return undefined;

		return stack[stack.length - 1];
	}

	function pushCard(card) {
		stack.push(card);
		card.pile = this;
		$(selector).append(card.getHtml());

		if (ft.selectedCard != undefined)
			ft.selectedCard.getHtml().removeClass('selectedCard');
		ft.selectedCard = undefined;

		//remove the click event of all cards
		for (var i = 0; i < stack.length; i++) {
			stack[i].getHtml().unbind('click');
		}

		card.getHtml().click(card.clickHandler(card));

		ft.undoCount++;

	}

	function clickHandler(card) {
		if (ft.selectedCard != undefined) {
			if (card.canDropOnOpenCard(ft.selectedCard)) {
				card.pile.pushCard(ft.selectedCard.pile.pop());
			}
			else {
				//if we cant move, just deselect old card and select new
				ft.selectedCard.deselect();
				ft.selectedCard = card;
				ft.selectedCard.select();
			}
		}
		//if selected card doesnt exist yet, select this one
		else {
			ft.selectedCard = card;
			card.select();
		}
	}

	return {
		draw : draw,
		pop : draw,
		peekTop : peekTop,
		pushCard : pushCard,
		clickHandler : clickHandler
	};
}

/*************Play Stack*/

function getPlayStack(sel) {
	var selector = sel;
	var stack = [];

	function setup() {
		var pile = this;
		$(selector).click(function () {
			if (stack.length == 0 && ft.selectedCard && ft.selectedCard.pile) {
				pile.pushCard(ft.selectedCard.pile.pop());
			}
		});
	}

	function pop() {
		return stack.pop();
	}

	function peekTop() {
		if (stack.length == 0)
			return undefined;

		return stack[stack.length - 1];
	}

	function pushCard(card) {
		var cardHtml = card.getHtml();
		if (stack.length > 0) {
			cardHtml = cardHtml.css('top', stack.length * 25);
		}
		else {
			cardHtml = cardHtml.css('top', 0);
		}

		$(selector).append(cardHtml);

		stack.push(card);
		card.pile = this;

		card.getHtml().click(card.clickHandler());

		ft.undoCount = 0;
		ft.moves++;

	}

	function clickHandler(card) {
		if (ft.selectedCard != undefined) {
			if (card.canDropOnOpenCard(ft.selectedCard)) {
				card.pile.pushCard(ft.selectedCard.pile.pop());
			}
			else {
				//if we cant move, just deselect old card and select new
				ft.selectedCard.deselect();
				ft.selectedCard = card;
				ft.selectedCard.select();
			}
		}
		//if selected card doesnt exist yet, select this one
		else {
			ft.selectedCard = card;
			card.select();
		}
	}

	return {
		pop : pop,
		peekTop : peekTop,
		pushCard : pushCard,
		clickHandler : clickHandler,
		setup : setup
	};
}

/********* Drop Zone ****/

function getDropZone(sel) {
	var selector = sel;
	var stack = [];

	function isFull() {
		return stack.length == 13;
	}

	function peekTop() {
		var top = stack.pop();

		if (top != undefined)
			stack.push(top);
		return top;
	}

	function pop() {
		var popped = stack.pop();

		popped.getHtml().click(popped.clickHandler(popped));

		return stack.pop();
	}

	function pushCard(card) {
		var cardHtml = card.getHtml();

		cardHtml = cardHtml.css('top', 0);

		$(selector).append(cardHtml);

		stack.push(card);
		card.pile = this;

		for (var i = 0; i < stack.length; i++) {
			stack[i].getHtml().unbind('click');
		}

		card.getHtml().click(card.clickHandler(card));

		checkForWin();

		ft.undoCount = 0;

		if(ft.selectedCard) ft.selectedCard.deselect();
		ft.moves--;
	}

	function setup(){
		var pile = this;
		$(selector).click(function () {
			if (stack.length == 0 && (ft.selectedCard != undefined && ft.selectedCard.cardNumber == 1)) {
				pile.pushCard(ft.selectedCard.pile.pop());
			}
		});
	}

	function clickHandler(card) {
		if (ft.selectedCard != undefined) {
			if (card.canDropOnDropZoneCard(ft.selectedCard)) {
				card.pile.pushCard(ft.selectedCard.pile.pop());

				//not sure when ft.selectedCard becomes undefined between here and the if above... need to check it out
				if (ft.selectedCard != undefined) {
					ft.selectedCard.deselect();
				}
			}
			else {
				//if we cant move, just deselect old card and select new
				ft.selectedCard.deselect();
				ft.selectedCard = card;

				card.select();
			}
		}
	}

	return {
		peekTop : peekTop,
		pop : pop,
		pushCard : pushCard,
		clickHandler : clickHandler,
		isFull : isFull,
		setup : setup
	};
}

/******** Card */

function getCard(cardNum, cardS) {

    var cardNumber = cardNum;
    var cardSuit = cardS;
    var html = $('

');
    var htmlBack = $('

');

    var pile;

	function getHtml() {
		return html;
	}

	function getBackHtml() {
		return htmlBack;
	}

    function canDropOnZone(dropZone) {
        var topCard = zone.peekTop();
        return this.cardNumber - topCard.cardNumber == 1 && cardSuit == topCard.cardSuit;
    }

    function canDropOnOpenCard(card) {
        return cardNumber - card.cardNumber == 1 && cardSuit == card.cardSuit;
    }

    function canDropOnDropZoneCard(card) {
        return cardNumber - card.cardNumber == -1 && cardSuit == card.cardSuit;
    }

	function clickHandler() {
		var card = this;
		return (function () {
			//ignore click if this is not the top
			if (card.pile.peekTop() != card) {
				return;
			}
			card.pile.clickHandler(card);
		});
	}

	function select() {
		ft.selectedCard = this;
		html.addClass('selectedCard');
	}

	function deselect() {
		html.removeClass('selectedCard');
		ft.selectedCard = undefined;
	}

	return {
		canDropOnZone : canDropOnZone,
		canDropOnOpenCard : canDropOnOpenCard,
		canDropOnDropZoneCard : canDropOnDropZoneCard,
		clickHandler : clickHandler,
		getHtml : getHtml,
		getBackHtml : getBackHtml,
		select : select,
		deselect : deselect,
		cardNumber : cardNumber,
		cardSuit : cardSuit,
		pile : pile
	};
}

function undo() {
	if(ft.undoCount <= 0 || !ft.discardPile.peekTop()) {
		alert('INVALID: cannot undo.');
		return;
	}

	ft.drawPile.pushCard(ft.discardPile.pop());
	ft.undoCount--;

	if(ft.selectedCard)
		ft.selectedCard.deselect();
	ft.moves+=5;
}

function checkForWin() {

    for (var i = 0; i < ft.dropZones.length; i++) {
        var dropZone = ft.dropZones[i];
        if(!dropZone.isFull()) return;
    }

	for(i=0;i<10;i++) {
		cornify_add();
	}
}

function toggleInfo() {
	var infoPanel = $('#infoPanel');

	var off = infoPanel.css('display') == 'none';
	if(off)
		infoPanel.css('display', 'block');
	else
		infoPanel.css('display', 'none');

	$('#btnInfo').html(off ? 'Hide Info' : 'Show Info');
}

function viewLog() {
	var list = $('#log');
	list.empty();

	for(var i = 0; i< ft.logs.length; i++) {
		list.append('
' + ft.logs[i] + '
');
	}
}

function newGame() {
	location.reload(true);
}

function updateStatus() {

	//memory leak?
	var elapsed, elapsedMins, elapsedSecs,
		str,
		seconds, minutes;

	seconds = 1000;
	minutes = seconds * 60;

	elapsed = new Date().getTime() - ft.startTime.getTime();
	elapsedMins = Math.floor(elapsed/minutes);
	elapsedSecs = Math.floor((elapsed/seconds)%60);

	if(elapsedSecs < 10)
		elapsedSecs = '0' + elapsedSecs;

	str = 'Time: ' + elapsedMins + ':' + elapsedSecs + ' Score: ' + ft.moves;

	$('#lblInfo').text(str);

	ft.timer = setTimeout(updateStatus, 250);
}

$(document).ready(function () {
	$('#btnNewGame').click(newGame);
	$('#btnUndo').click(undo);
	$('#btnInfo').click(toggleInfo);
	$('#btnViewLog').click(viewLog);

	updateStatus();
	ft.timer = setTimeout(updateStatus, 250);

	ft.deal();

});
<commit_msg>self invoking function to avoid putting everything on the global<commit_after>(function() {
	var ft = {
		cardNumbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
		cardSuits: ["C", "D", "S", "H"],
		decks: 2,
		discardPile: null,
		drawPile: null,
		playStacks: [],
		dropZones: [],
		selectedCard: undefined,
		logOn: false,
		logs: [],
		undoCount: 0,
		timer: null,
		startTime: new Date(),
		moves: 0
	};

	ft.generateDeck = function generateDeck() {
		var deck = [];

		_.forEach(ft.cardNumbers, function (cardNumber) {
			_.forEach(ft.cardSuits, function (cardSuit) {
				deck.push(getCard(cardNumber, cardSuit));
				deck.push(getCard(cardNumber, cardSuit));
			});
		});

		//one shuffle didnt seem all that random. Similar cards seemed to beright next to each other
		deck = _(deck).shuffle().shuffle().shuffle().value();

		return deck;
	};

	ft.deal = function deal() {
		var deck, selector, i, j, stack;

		deck = ft.generateDeck();

		selector = '#s';
		ft.logOn = false;

		for (i = 0; i < 10; i++) {
			stack = getPlayStack(selector + i);

			ft.playStacks.push(stack);

			for (j = 0; j < 4; j++) {
				stack.pushCard(deck.pop());
			}

			stack.setup();
		}

		ft.drawPile = getDrawPile('.drawPile');
		while (deck.length > 0) {
			ft.drawPile.pushCard(deck.pop());
		}

		ft.discardPile = getDiscardPile('.discardPile');

		selector = '#d';
		for (i = 0; i < 8; i++) {
			stack = getDropZone(selector + i);
			ft.dropZones.push(stack);
			stack.setup();
		}

		$("#left, #right").click(deselectSelected);

		ft.logOn = true;
		ft.moves = 0;
	};

	function deselectSelected() {
		if (ft.selectedCard != undefined)
			ft.selectedCard.getHtml().removeClass('selectedCard');
		ft.selectedCard = undefined;
	}

	/*********** Draw Pile */

	function getDrawPile(sel) {
		var selector = sel;
		var stack = [];

		function pushCard(card) {
			stack.push(card);
			card.pile = this;

			if ($(selector).is(':empty')) {
				var cardBack = card.getBackHtml();
				cardBack.click(function () {
					var c = card.pile.draw();
					ft.discardPile.pushCard(c);
				});

				$(selector).append(cardBack);
			}
		}

		function draw() {
			var top = stack.pop();

			$(selector).empty();
			var nextToTop = stack.pop();

			if (nextToTop != undefined) {
				this.pushCard(nextToTop);
			}

			ft.moves++;
			return top;
		}

		return {
			draw: draw,
			pushCard: pushCard
		}
	}

	/********Discard Pie ********* */

	function getDiscardPile(sel) {
		var selector = sel;
		var stack = [];

		function draw() {
			var top = stack.pop();

			var nextToTop = stack.pop();
			if (nextToTop != undefined) {
				this.pushCard(nextToTop);
			}
			else {
				$(selector).empty();
			}

			return top;
		}

		function peekTop() {
			if (stack.length == 0)
				return undefined;

			return stack[stack.length - 1];
		}

		function pushCard(card) {
			stack.push(card);
			card.pile = this;
			$(selector).append(card.getHtml());

			if (ft.selectedCard != undefined)
				ft.selectedCard.getHtml().removeClass('selectedCard');
			ft.selectedCard = undefined;

			//remove the click event of all cards
			for (var i = 0; i < stack.length; i++) {
				stack[i].getHtml().unbind('click');
			}

			card.getHtml().click(card.clickHandler(card));

			ft.undoCount++;

		}

		function clickHandler(card) {
			if (ft.selectedCard != undefined) {
				if (card.canDropOnOpenCard(ft.selectedCard)) {
					card.pile.pushCard(ft.selectedCard.pile.pop());
				}
				else {
					//if we cant move, just deselect old card and select new
					ft.selectedCard.deselect();
					ft.selectedCard = card;
					ft.selectedCard.select();
				}
			}
			//if selected card doesnt exist yet, select this one
			else {
				ft.selectedCard = card;
				card.select();
			}
		}

		return {
			draw: draw,
			pop: draw,
			peekTop: peekTop,
			pushCard: pushCard,
			clickHandler: clickHandler
		};
	}

	/*************Play Stack*/

	function getPlayStack(sel) {
		var selector = sel;
		var stack = [];

		function setup() {
			var pile = this;
			$(selector).click(function () {
				if (stack.length == 0 && ft.selectedCard && ft.selectedCard.pile) {
					pile.pushCard(ft.selectedCard.pile.pop());
				}
			});
		}

		function pop() {
			return stack.pop();
		}

		function peekTop() {
			if (stack.length == 0)
				return undefined;

			return stack[stack.length - 1];
		}

		function pushCard(card) {
			var cardHtml = card.getHtml();
			if (stack.length > 0) {
				cardHtml = cardHtml.css('top', stack.length * 25);
			}
			else {
				cardHtml = cardHtml.css('top', 0);
			}

			$(selector).append(cardHtml);

			stack.push(card);
			card.pile = this;

			card.getHtml().click(card.clickHandler());

			ft.undoCount = 0;
			ft.moves++;

		}

		function clickHandler(card) {
			if (ft.selectedCard != undefined) {
				if (card.canDropOnOpenCard(ft.selectedCard)) {
					card.pile.pushCard(ft.selectedCard.pile.pop());
				}
				else {
					//if we cant move, just deselect old card and select new
					ft.selectedCard.deselect();
					ft.selectedCard = card;
					ft.selectedCard.select();
				}
			}
			//if selected card doesnt exist yet, select this one
			else {
				ft.selectedCard = card;
				card.select();
			}
		}

		return {
			pop: pop,
			peekTop: peekTop,
			pushCard: pushCard,
			clickHandler: clickHandler,
			setup: setup
		};
	}

	/********* Drop Zone ****/

	function getDropZone(sel) {
		var selector = sel;
		var stack = [];

		function isFull() {
			return stack.length == 13;
		}

		function peekTop() {
			var top = stack.pop();

			if (top != undefined)
				stack.push(top);
			return top;
		}

		function pop() {
			var popped = stack.pop();

			popped.getHtml().click(popped.clickHandler(popped));

			return stack.pop();
		}

		function pushCard(card) {
			var cardHtml = card.getHtml();

			cardHtml = cardHtml.css('top', 0);

			$(selector).append(cardHtml);

			stack.push(card);
			card.pile = this;

			for (var i = 0; i < stack.length; i++) {
				stack[i].getHtml().unbind('click');
			}

			card.getHtml().click(card.clickHandler(card));

			checkForWin();

			ft.undoCount = 0;

			if (ft.selectedCard) ft.selectedCard.deselect();
			ft.moves--;
		}

		function setup() {
			var pile = this;
			$(selector).click(function () {
				if (stack.length == 0 && (ft.selectedCard != undefined && ft.selectedCard.cardNumber == 1)) {
					pile.pushCard(ft.selectedCard.pile.pop());
				}
			});
		}

		function clickHandler(card) {
			if (ft.selectedCard != undefined) {
				if (card.canDropOnDropZoneCard(ft.selectedCard)) {
					card.pile.pushCard(ft.selectedCard.pile.pop());

					//not sure when ft.selectedCard becomes undefined between here and the if above... need to check it out
					if (ft.selectedCard != undefined) {
						ft.selectedCard.deselect();
					}
				}
				else {
					//if we cant move, just deselect old card and select new
					ft.selectedCard.deselect();
					ft.selectedCard = card;

					card.select();
				}
			}
		}

		return {
			peekTop: peekTop,
			pop: pop,
			pushCard: pushCard,
			clickHandler: clickHandler,
			isFull: isFull,
			setup: setup
		};
	}

	/******** Card */

	function getCard(cardNum, cardS) {

		var cardNumber = cardNum;
		var cardSuit = cardS;
		var html = $('

');
		var htmlBack = $('

');

		var pile;

		function getHtml() {
			return html;
		}

		function getBackHtml() {
			return htmlBack;
		}

		function canDropOnZone(dropZone) {
			var topCard = zone.peekTop();
			return this.cardNumber - topCard.cardNumber == 1 && cardSuit == topCard.cardSuit;
		}

		function canDropOnOpenCard(card) {
			return cardNumber - card.cardNumber == 1 && cardSuit == card.cardSuit;
		}

		function canDropOnDropZoneCard(card) {
			return cardNumber - card.cardNumber == -1 && cardSuit == card.cardSuit;
		}

		function clickHandler() {
			var card = this;
			return (function () {
				//ignore click if this is not the top
				if (card.pile.peekTop() != card) {
					return;
				}
				card.pile.clickHandler(card);
			});
		}

		function select() {
			ft.selectedCard = this;
			html.addClass('selectedCard');
		}

		function deselect() {
			html.removeClass('selectedCard');
			ft.selectedCard = undefined;
		}

		return {
			canDropOnZone: canDropOnZone,
			canDropOnOpenCard: canDropOnOpenCard,
			canDropOnDropZoneCard: canDropOnDropZoneCard,
			clickHandler: clickHandler,
			getHtml: getHtml,
			getBackHtml: getBackHtml,
			select: select,
			deselect: deselect,
			cardNumber: cardNumber,
			cardSuit: cardSuit,
			pile: pile
		};
	}

	function undo() {
		if (ft.undoCount <= 0 || !ft.discardPile.peekTop()) {
			alert('INVALID: cannot undo.');
			return;
		}

		ft.drawPile.pushCard(ft.discardPile.pop());
		ft.undoCount--;

		if (ft.selectedCard)
			ft.selectedCard.deselect();
		ft.moves += 5;
	}

	function checkForWin() {

		for (var i = 0; i < ft.dropZones.length; i++) {
			var dropZone = ft.dropZones[i];
			if (!dropZone.isFull()) return;
		}

		for (i = 0; i < 10; i++) {
			cornify_add();
		}
	}

	function toggleInfo() {
		var infoPanel = $('#infoPanel');

		var off = infoPanel.css('display') == 'none';
		if (off)
			infoPanel.css('display', 'block');
		else
			infoPanel.css('display', 'none');

		$('#btnInfo').html(off ? 'Hide Info' : 'Show Info');
	}

	function viewLog() {
		var list = $('#log');
		list.empty();

		for (var i = 0; i < ft.logs.length; i++) {
			list.append('
' + ft.logs[i] + '
');
		}
	}

	function newGame() {
		location.reload(true);
	}

	function updateStatus() {

		//memory leak?
		var elapsed, elapsedMins, elapsedSecs,
			str,
			seconds, minutes;

		seconds = 1000;
		minutes = seconds * 60;

		elapsed = new Date().getTime() - ft.startTime.getTime();
		elapsedMins = Math.floor(elapsed / minutes);
		elapsedSecs = Math.floor((elapsed / seconds) % 60);

		if (elapsedSecs < 10)
			elapsedSecs = '0' + elapsedSecs;

		str = 'Time: ' + elapsedMins + ':' + elapsedSecs + ' Score: ' + ft.moves;

		$('#lblInfo').text(str);

		ft.timer = setTimeout(updateStatus, 250);
	}

	$(document).ready(function () {
		$('#btnNewGame').click(newGame);
		$('#btnUndo').click(undo);
		$('#btnInfo').click(toggleInfo);
		$('#btnViewLog').click(viewLog);

		updateStatus();
		ft.timer = setTimeout(updateStatus, 250);

		ft.deal();

	});
})();<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { connect } from 'react-redux'
import cx from 'classnames'
import pathModule from 'path'
import SplitPane from 'react-split-pane'
import FaFolder from 'react-icons/fa/folder'
import IconClose from 'react-icons/md/close'
import IconEdit from 'react-icons/md/mode-edit'

import { openModal } from 'reducers/modals'

import { readDir, sortFiles, fsRename } from 'helpers/fs'
import { setPreview } from 'actions/preview'
import { updateSettings } from 'actions/settings'

import FileEditor from 'components/FileEditor'
import FilePreview from './FilePreview'

import './styles.scss'

function renameFile (path, oldName, newName, files) {
  if (oldName === newName) { return }
  const filesWithoutOld = files.filter(f => f.name !== oldName)
  const fileExists = filesWithoutOld.some(f => f.name === newName)
  if (fileExists) {
    throw new Error('File already exists')
  }
  const oldFullName = pathModule.join(path, oldName)
  const newFullName = pathModule.join(path, newName)
  return fsRename(oldFullName, newFullName)
}

@connect(state => ({
  previewSize: state.settings.get('previewSize'),
}), {
  setPreview,
  openModal,
  updateSettings,
}, null, { withRef: true })
class FilesList extends Component {

  state = {
    isLoading: true,
    isAdding: false,
    files: [],
    preview: null,
    editingFile: null,
    isDragging: false,
    renamedFile: null,
    newName: '',
  }

  componentWillMount () {
    this._hasFocused = false
  }

  componentDidMount () {
    this.refresh()
  }

  componentDidUpdate (prevProps, prevState) {
    if (prevProps.path !== this.props.path) {
      this.refresh()
    }
    if (!prevState.isAdding && this.state.isAdding) {
      this._inputName.focus()
    }
    if (this.state.files.length > prevState.files.length && this._lastCreated) {
      this._refs[this._lastCreated].focus()
    }
    if (!prevState.renamedFile && this.state.renamedFile) {
      this._renameInput.select()
    }
  }

  componentWillUnmount () {
    this._unmounted = true
  }

  handleSubmit = e => {
    e.preventDefault()
    const { path, onAddFile, onActiveFileChange } = this.props
    let name = this._inputName.value
    if (!name) { return }
    name = `${name}.mjml`
    const fileName = pathModule.join(path, name)
    onAddFile(fileName)
    onActiveFileChange({
      isFolder: false,
      name,
    })
    this._lastCreated = name
    this.toggleAdding()
  }

  handleClickFactory = f => () => {
    const p = pathModule.join(this.props.path, f.name)
    if (f.isFolder) {
      return this.props.onPathChange(p)
    }
    if (this.props.onFileClick) {
      this.props.onFileClick(p)
    }
    // preview will be set by the onChange on editor
    // no need to trigger it here
    if (!p.endsWith('.mjml')) {
      if (p.endsWith('.html')) {
        this.props.setPreview(p)
      } else {
        this.props.setPreview(null)
      }
    }
    this.props.onActiveFileChange(f)
  }

  handleClickDirectFactory = (items, i) => () => {
    const sub = items.slice(0, i + 1)
    const relativePath = sub.join(pathModule.sep)
    const path = pathModule.join(this.props.rootPath, relativePath)
    this.props.onPathChange(path)
  }

  handleRemoveFileFactory = f => e => {
    if (e) { e.preventDefault() }
    const p = pathModule.join(this.props.path, f.name)
    this.props.onRemoveFile(p)
  }

  handleNavigateUp = () => {
    this.props.onPathChange(pathModule.dirname(this.props.path))
  }

  handlePreviewPanelStopDrag = (size) => {
    this.setCurrentSize(size)
    this.stopDrag()
  }

  handleChangeNewName = e => {
    this.setState({ newName: e.target.value })
  }

  handleCancelRename = () => this.setState({
    renamedFile: null,
    newName: '',
  })

  handleRenameInputKeyDown = async e => {
    switch (e.which) { // eslint-disable-line
    case 27:
      this.handleCancelRename()
      break
    case 13:
      try {
        const { path } = this.props
        const {
          newName,
          renamedFile,
          files,
        } = this.state
        await renameFile(
          path,
          renamedFile.name,
          newName,
          files,
        )
        const newFile = { name: newName, isFolder: false }
        const newFiles = files.map(f => {
          if (f === renamedFile) { return newFile }
          return f
        })
        sortFiles(newFiles)
        this.setState({ files: newFiles })
        this.props.onActiveFileChange(newFile)
        this.handleCancelRename()
      } catch (e) {} // eslint-disable-line
      break
    }
  }

  setCurrentSize = size => {
    this.props.updateSettings(settings => {
      return settings
        .setIn(['previewSize', 'current'], size)
    })
  }

  refsFactory = () => {
    this._refs = {}
    return refName => node => {
      this._refs[refName] = node
    }
  }

  refresh = () => {
    const { path } = this.props
    readDir(path).then(files => {
      if (this._unmounted) { return }
      sortFiles(files)
      this.setState({
        isLoading: false,
        files,
      })
      window.requestIdleCallback(() => {
        if (files.length && !this._hasFocused) {
          const indexOfIndexFile = files.findIndex(f => f.name === 'index.mjml')
          this.props.onActiveFileChange(files[indexOfIndexFile === -1 ? 0 : indexOfIndexFile])
          this._hasFocused = true
        }
      })
    })
  }

  startDrag = () => this.setState({ isDragging: true })
  stopDrag = () => {
    this.setState({ isDragging: false })
    if (!this._editor) { return }
    const editor = this._editor.getWrappedInstance()
    editor.refresh()
    editor.focus()
  }

  toggleAdding = e => {
    if (e) { e.preventDefault() }
    this.setState(s => ({ isAdding: !s.isAdding }))
  }

  cancelAdd = e => {
    if (e) { e.preventDefault() }
    this.setState(s => ({ isAdding: !s.isAdding }), () => {
      this._addBtn.focus()
    })
  }

  render () {

    const {
      files,
      isDragging,
      renamedFile,
      newName,
    } = this.state

    const {
      onRef,
      activeFile,
      path,
      rootPath,
      openModal,
      previewSize,
    } = this.props

    onRef(this)

    const setRef = this.refsFactory()

    const rootPathItems = rootPath.split(pathModule.sep)
    const pathItems = path
      .split(pathModule.sep)
      .slice(rootPathItems.length)

    const fullActiveFile = pathModule.join(path, (activeFile && activeFile.name) || '')

    return (

          <SplitPane
            split='vertical'
            defaultSize={180}
            maxSize={250}
            onDragStarted={this.startDrag}
            onDragFinished={this.stopDrag}
          >

                {!!pathItems.length && (
                  <button
                    className='FilesList--file d-f ai-c'
                    tabIndex={0}
                    onClick={this.handleNavigateUp}
                  >

                        {'..'}

                  </button>
                )}
                {files.map(f => renamedFile === f ? (

                    <input
                      ref={n => this._renameInput = n}
                      autoFocus
                      type='text'
                      value={newName}
                      onKeyDown={this.handleRenameInputKeyDown}
                      onChange={this.handleChangeNewName}
                      onBlur={this.handleCancelRename}
                    />

                ) : (
                  <button
                    ref={setRef(f.name)}
                    key={f.name}
                    className={cx('FilesList--file d-f ai-c', {
                      active: activeFile && activeFile.name === f.name,
                    })}
                    tabIndex={0}
                    onClick={this.handleClickFactory(f)}
                  >
                    {f.isFolder && (

                        <FaFolder />

                    )}

                        {f.name}

 this.setState({
                          renamedFile: f,
                          newName: f.name,
                        })}
                        className='action action-rename'
                      >
                        <IconEdit />

 openModal('removeFile', f)}
                        className='action action-remove'
                      >
                        <IconClose />

                  </button>
                ))}

            <SplitPane
              ref={n => this._previewSplitPane = n}
              split='vertical'
              size={previewSize.get('current')}
              maxSize={previewSize.get('desktop')}
              minSize={previewSize.get('mobile')}
              primary='second'
              onDragStarted={this.startDrag}
              onDragFinished={this.handlePreviewPanelStopDrag}
            >

                {activeFile && activeFile.name.endsWith('.mjml') && (
                  <FileEditor
                    ref={n => this._editor = n}
                    fileName={fullActiveFile}
                    disablePointer={isDragging}
                  />
                )}

                <FilePreview
                  disablePointer={isDragging}
                  onSetSize={this.setCurrentSize}
                />

            </SplitPane>
          </SplitPane>

    )
  }

}

export default FilesList
<commit_msg>Ability to completely hide the files list by dragging the bar to the left<commit_after>import React, { Component } from 'react'
import { connect } from 'react-redux'
import cx from 'classnames'
import pathModule from 'path'
import SplitPane from 'react-split-pane'
import FaFolder from 'react-icons/fa/folder'
import IconClose from 'react-icons/md/close'
import IconEdit from 'react-icons/md/mode-edit'

import { openModal } from 'reducers/modals'

import { readDir, sortFiles, fsRename } from 'helpers/fs'
import { setPreview } from 'actions/preview'
import { updateSettings } from 'actions/settings'

import FileEditor from 'components/FileEditor'
import FilePreview from './FilePreview'

import './styles.scss'

function renameFile (path, oldName, newName, files) {
  if (oldName === newName) { return }
  const filesWithoutOld = files.filter(f => f.name !== oldName)
  const fileExists = filesWithoutOld.some(f => f.name === newName)
  if (fileExists) {
    throw new Error('File already exists')
  }
  const oldFullName = pathModule.join(path, oldName)
  const newFullName = pathModule.join(path, newName)
  return fsRename(oldFullName, newFullName)
}

@connect(state => ({
  previewSize: state.settings.get('previewSize'),
}), {
  setPreview,
  openModal,
  updateSettings,
}, null, { withRef: true })
class FilesList extends Component {

  state = {
    isLoading: true,
    isAdding: false,
    files: [],
    preview: null,
    editingFile: null,
    isDragging: false,
    renamedFile: null,
    newName: '',
  }

  componentWillMount () {
    this._hasFocused = false
  }

  componentDidMount () {
    this.refresh()
  }

  componentDidUpdate (prevProps, prevState) {
    if (prevProps.path !== this.props.path) {
      this.refresh()
    }
    if (!prevState.isAdding && this.state.isAdding) {
      this._inputName.focus()
    }
    if (this.state.files.length > prevState.files.length && this._lastCreated) {
      this._refs[this._lastCreated].focus()
    }
    if (!prevState.renamedFile && this.state.renamedFile) {
      this._renameInput.select()
    }
  }

  componentWillUnmount () {
    this._unmounted = true
  }

  handleSubmit = e => {
    e.preventDefault()
    const { path, onAddFile, onActiveFileChange } = this.props
    let name = this._inputName.value
    if (!name) { return }
    name = `${name}.mjml`
    const fileName = pathModule.join(path, name)
    onAddFile(fileName)
    onActiveFileChange({
      isFolder: false,
      name,
    })
    this._lastCreated = name
    this.toggleAdding()
  }

  handleClickFactory = f => () => {
    const p = pathModule.join(this.props.path, f.name)
    if (f.isFolder) {
      return this.props.onPathChange(p)
    }
    if (this.props.onFileClick) {
      this.props.onFileClick(p)
    }
    // preview will be set by the onChange on editor
    // no need to trigger it here
    if (!p.endsWith('.mjml')) {
      if (p.endsWith('.html')) {
        this.props.setPreview(p)
      } else {
        this.props.setPreview(null)
      }
    }
    this.props.onActiveFileChange(f)
  }

  handleClickDirectFactory = (items, i) => () => {
    const sub = items.slice(0, i + 1)
    const relativePath = sub.join(pathModule.sep)
    const path = pathModule.join(this.props.rootPath, relativePath)
    this.props.onPathChange(path)
  }

  handleRemoveFileFactory = f => e => {
    if (e) { e.preventDefault() }
    const p = pathModule.join(this.props.path, f.name)
    this.props.onRemoveFile(p)
  }

  handleNavigateUp = () => {
    this.props.onPathChange(pathModule.dirname(this.props.path))
  }

  handlePreviewPanelStopDrag = (size) => {
    this.setCurrentSize(size)
    this.stopDrag()
  }

  handleChangeNewName = e => {
    this.setState({ newName: e.target.value })
  }

  handleCancelRename = () => this.setState({
    renamedFile: null,
    newName: '',
  })

  handleRenameInputKeyDown = async e => {
    switch (e.which) { // eslint-disable-line
    case 27:
      this.handleCancelRename()
      break
    case 13:
      try {
        const { path } = this.props
        const {
          newName,
          renamedFile,
          files,
        } = this.state
        await renameFile(
          path,
          renamedFile.name,
          newName,
          files,
        )
        const newFile = { name: newName, isFolder: false }
        const newFiles = files.map(f => {
          if (f === renamedFile) { return newFile }
          return f
        })
        sortFiles(newFiles)
        this.setState({ files: newFiles })
        this.props.onActiveFileChange(newFile)
        this.handleCancelRename()
      } catch (e) {} // eslint-disable-line
      break
    }
  }

  setCurrentSize = size => {
    this.props.updateSettings(settings => {
      return settings
        .setIn(['previewSize', 'current'], size)
    })
  }

  refsFactory = () => {
    this._refs = {}
    return refName => node => {
      this._refs[refName] = node
    }
  }

  refresh = () => {
    const { path } = this.props
    readDir(path).then(files => {
      if (this._unmounted) { return }
      sortFiles(files)
      this.setState({
        isLoading: false,
        files,
      })
      window.requestIdleCallback(() => {
        if (files.length && !this._hasFocused) {
          const indexOfIndexFile = files.findIndex(f => f.name === 'index.mjml')
          this.props.onActiveFileChange(files[indexOfIndexFile === -1 ? 0 : indexOfIndexFile])
          this._hasFocused = true
        }
      })
    })
  }

  startDrag = () => this.setState({ isDragging: true })
  stopDrag = () => {
    this.setState({ isDragging: false })
    if (!this._editor) { return }
    const editor = this._editor.getWrappedInstance()
    editor.refresh()
    editor.focus()
  }

  toggleAdding = e => {
    if (e) { e.preventDefault() }
    this.setState(s => ({ isAdding: !s.isAdding }))
  }

  cancelAdd = e => {
    if (e) { e.preventDefault() }
    this.setState(s => ({ isAdding: !s.isAdding }), () => {
      this._addBtn.focus()
    })
  }

  render () {

    const {
      files,
      isDragging,
      renamedFile,
      newName,
    } = this.state

    const {
      onRef,
      activeFile,
      path,
      rootPath,
      openModal,
      previewSize,
    } = this.props

    onRef(this)

    const setRef = this.refsFactory()

    const rootPathItems = rootPath.split(pathModule.sep)
    const pathItems = path
      .split(pathModule.sep)
      .slice(rootPathItems.length)

    const fullActiveFile = pathModule.join(path, (activeFile && activeFile.name) || '')

    return (

          <SplitPane
            split='vertical'
            defaultSize={180}
            minSize={2}
            maxSize={250}
            onDragStarted={this.startDrag}
            onDragFinished={this.stopDrag}
          >

                {!!pathItems.length && (
                  <button
                    className='FilesList--file d-f ai-c'
                    tabIndex={0}
                    onClick={this.handleNavigateUp}
                  >

                        {'..'}

                  </button>
                )}
                {files.map(f => renamedFile === f ? (

                    <input
                      ref={n => this._renameInput = n}
                      autoFocus
                      type='text'
                      value={newName}
                      onKeyDown={this.handleRenameInputKeyDown}
                      onChange={this.handleChangeNewName}
                      onBlur={this.handleCancelRename}
                    />

                ) : (
                  <button
                    ref={setRef(f.name)}
                    key={f.name}
                    className={cx('FilesList--file d-f ai-c', {
                      active: activeFile && activeFile.name === f.name,
                    })}
                    tabIndex={0}
                    onClick={this.handleClickFactory(f)}
                  >
                    {f.isFolder && (

                        <FaFolder />

                    )}

                        {f.name}

 this.setState({
                          renamedFile: f,
                          newName: f.name,
                        })}
                        className='action action-rename'
                      >
                        <IconEdit />

 openModal('removeFile', f)}
                        className='action action-remove'
                      >
                        <IconClose />

                  </button>
                ))}

            <SplitPane
              ref={n => this._previewSplitPane = n}
              split='vertical'
              size={previewSize.get('current')}
              maxSize={previewSize.get('desktop')}
              minSize={previewSize.get('mobile')}
              primary='second'
              onDragStarted={this.startDrag}
              onDragFinished={this.handlePreviewPanelStopDrag}
            >

                {activeFile && activeFile.name.endsWith('.mjml') && (
                  <FileEditor
                    ref={n => this._editor = n}
                    fileName={fullActiveFile}
                    disablePointer={isDragging}
                  />
                )}

                <FilePreview
                  disablePointer={isDragging}
                  onSetSize={this.setCurrentSize}
                />

            </SplitPane>
          </SplitPane>

    )
  }

}

export default FilesList
<|endoftext|>


<commit_before>/* eslint-disable no-console */

const { MongoClient } = require('mongodb');

const init = (connectionString) => {
    return MongoClient.connect(connectionString)
        .then((db) => {
            console.log('Car Rentals databases connected!');
            return db;
        });
};

module.exports = { init };
<commit_msg>message about which database is connected<commit_after>/* eslint-disable no-console */

const { MongoClient } = require('mongodb');

const init = (connectionString) => {
    return MongoClient.connect(connectionString)
        .then((db) => {
            console.log(`Car Rentals databases connected at ${connectionString}`);
            return db;
        });
};

module.exports = { init };
<|endoftext|>


<commit_before>/**
 *
 * Helpers
 *
 * Copyright 2015, Author Name
 * Some information on the license.
 *
**/

;(function(Helper, window, undefined){
	'use strict';

	/**
	 * Helper.log
	 * Customised and cross browser console.log.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.log = function(message, type, alertlog){
		if(window.helper_log){
			alertlog = (typeof alertlog === 'undefined') ? true : false;
			if(typeof console === 'undefined' || typeof console.log === 'undefined'){
				if(alertlog){
					alert(message);
				}
			}
			else {
				var color = (type == 'positive') ? '#097809' : (type == 'negative') ? '#c5211d' : (typeof type !== 'undefined') ? type : '#240ad0';
				console.log('%c DEBUG: -----------------------------------------------', 'color: ' + color);
				if(message instanceof Array || message instanceof Object){
					console.log(' DEBUG:', message);
				}
				else{
					console.log('%c DEBUG: ' + message, 'color: ' + color);
				}
				console.log('%c DEBUG: -----------------------------------------------', 'color: ' + color);
				console.log('');
			}
		}
	}

	/**
	 * Helper.breakpoint
	 * Checks the window against a certain breakpoint.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.breakpoint = function(breakpoint){
		return (window.innerWidth <= breakpoint) ? true : false;
	}

	/**
	 * Helper.mhi
	 * Measures a hidden element.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.mhi = function(el){
		// Clone element.
		var clone = el.clone();
		// Place above viewport and measure height.
		var height = clone.css({'position': 'absolute', 'top': '-100%', 'display': 'block', 'max-height': 'none', 'height': 'auto'}).prependTo(el.parent()).outerHeight();
		// Destroy the clone.
		clone.remove();

		return height;
	}

	/**
	 * Helper.isEmpty
	 * Checks if a value is empty, undefined or false.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
    Helper.isEmpty = function(value){
        return (value == null || value === '' || value.length === 0);
    }

	/**
	 * Helper.debounce
	 * Returns a function, that, as long as it continues to be invoked, will not
	 * be triggered. The function will be called after it stops being called for
	 * N milliseconds. If `immediate` is passed, trigger the function on the
	 * leading edge, instead of the trailing.
	 *
	 * $(window).on('resize', Module.test);
	 *
	 * Module.test = Helpers.debounce(function(){
	 *     console.log('This has been debounced');
	 * }, 250);
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.debounce = function(func, wait, immediate){
		var timeout;

		return function(){
			var _this = this,
				args  = arguments;

			var later = function(){
				timeout = null;
				if(!immediate){
					func.apply(_this, args);
				}
			};
			var call_now = immediate && !timeout;
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
			if(call_now){
				func.apply(_this, args);
			}
		};
	}

	/**
	 * Helper.preloader
	 * Generates a preloader.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.preloader = function(el, destroy){
		destroy = (typeof destroy === 'undefined') ? false : true;
		el      = (typeof el === 'undefined') ? $('body') : el;
		var loader = $('
<svg class="spinner" width="35px" height="35px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg>
');

		if(!destroy){
			if(!$('.spinner-wrapper', el).length){
				el.css({'position': 'relative'}).prepend(loader);
			}
		}
		else{
			$('.spinner-wrapper', el).fadeOut(500, function(){
				$(this).remove();
			});
		}
	}

    /**
     * Helper.ajax
     * Returns a simple Ajax request. Should use the result with a promise.
     * Will automatically parse any URL parameters and place them in the JSON
     * body instead.
     *
     * @since 1.0.0
     * @version 1.0.0
     */
    Helper.ajax = function(url, request, type, dataType, preloader_el){
    	// Default data.
    	var default_params = {
			ajaxrequest: true,
			request    : (!_.isEmpty(request)) ? request : false
    	};
    	// Get params (if any).
    	var optional_params = Helper.parse_url_params(url);
    	// Merge params to get data.
    	var data = $.extend({}, default_params, optional_params);
		// Request.
        return $.ajax({
            url     : (url.indexOf('?') != -1) ? url.split('?')[0] : url,
            type    : (!Helper.isEmpty(type)) ? type : 'POST',
            dataType: (!Helper.isEmpty(dataType)) ? dataType : 'JSON',
            data    : data,
            beforeSend: function(jqXHR, settings){
            	// Log full URL.
            	Helpers.log(settings.url + '?' + settings.data);
                // Add preloader.
                Helper.preloader((Helper.isEmpty(preloader_el)) ? $('body') : preloader_el);
            },
            complete: function(jqXHR){
                // Destroy preloader.
                Helper.preloader((Helper.isEmpty(preloader_el)) ? $('body') : preloader_el, true);
            }
        });
    }

	/**
	 * Helper.parse_url_params
	 * Converts the URL parameters into an object.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.parse_url_params = function(url){
		// Check if URL contains a ?.
		if(url.indexOf('?') != -1){
			// Split URL at ?
			var url_parsed = url.split('?')[1],
				url_params = (!Helper.isEmpty(url_parsed)) ? url_parsed : false;

			return (url_params) ? JSON.parse('{"' + decodeURI(url_params).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}') : false;
		}
		else{
			return {};
		}
	}

    /**
     * Helper.decode_entities
     * Decodes HTML entities.
     *
     * @since 1.0.0
     * @version 1.0.0
     */
    Helper.decode_entities = function(string){
    	// Create pseudo element.
	    var pseudo = document.createElement('textarea');
	    // Decode.
	    pseudo.innerHTML = string;

	    return pseudo.value;
	}

	// Export
	module.exports = Helpers;

}(window.Helpers = window.Helpers || {}, window));
<commit_msg>Added undefined to list of isEmpty values<commit_after>/**
 *
 * Helpers
 *
 * Copyright 2015, Author Name
 * Some information on the license.
 *
**/

;(function(Helper, window, undefined){
	'use strict';

	/**
	 * Helper.log
	 * Customised and cross browser console.log.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.log = function(message, type, alertlog){
		if(window.helper_log){
			alertlog = (typeof alertlog === 'undefined') ? true : false;
			if(typeof console === 'undefined' || typeof console.log === 'undefined'){
				if(alertlog){
					alert(message);
				}
			}
			else {
				var color = (type == 'positive') ? '#097809' : (type == 'negative') ? '#c5211d' : (typeof type !== 'undefined') ? type : '#240ad0';
				console.log('%c DEBUG: -----------------------------------------------', 'color: ' + color);
				if(message instanceof Array || message instanceof Object){
					console.log(' DEBUG:', message);
				}
				else{
					console.log('%c DEBUG: ' + message, 'color: ' + color);
				}
				console.log('%c DEBUG: -----------------------------------------------', 'color: ' + color);
				console.log('');
			}
		}
	}

	/**
	 * Helper.breakpoint
	 * Checks the window against a certain breakpoint.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.breakpoint = function(breakpoint){
		return (window.innerWidth <= breakpoint) ? true : false;
	}

	/**
	 * Helper.mhi
	 * Measures a hidden element.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.mhi = function(el){
		// Clone element.
		var clone = el.clone();
		// Place above viewport and measure height.
		var height = clone.css({'position': 'absolute', 'top': '-100%', 'display': 'block', 'max-height': 'none', 'height': 'auto'}).prependTo(el.parent()).outerHeight();
		// Destroy the clone.
		clone.remove();

		return height;
	}

	/**
	 * Helper.isEmpty
	 * Checks if a value is empty, undefined or false.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
    Helper.isEmpty = function(value){
        return (value == undefined || value == null || value === '' || value.length === 0);
    }

	/**
	 * Helper.debounce
	 * Returns a function, that, as long as it continues to be invoked, will not
	 * be triggered. The function will be called after it stops being called for
	 * N milliseconds. If `immediate` is passed, trigger the function on the
	 * leading edge, instead of the trailing.
	 *
	 * $(window).on('resize', Module.test);
	 *
	 * Module.test = Helpers.debounce(function(){
	 *     console.log('This has been debounced');
	 * }, 250);
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.debounce = function(func, wait, immediate){
		var timeout;

		return function(){
			var _this = this,
				args  = arguments;

			var later = function(){
				timeout = null;
				if(!immediate){
					func.apply(_this, args);
				}
			};
			var call_now = immediate && !timeout;
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
			if(call_now){
				func.apply(_this, args);
			}
		};
	}

	/**
	 * Helper.preloader
	 * Generates a preloader.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.preloader = function(el, destroy){
		destroy = (typeof destroy === 'undefined') ? false : true;
		el      = (typeof el === 'undefined') ? $('body') : el;
		var loader = $('
<svg class="spinner" width="35px" height="35px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg>
');

		if(!destroy){
			if(!$('.spinner-wrapper', el).length){
				el.css({'position': 'relative'}).prepend(loader);
			}
		}
		else{
			$('.spinner-wrapper', el).fadeOut(500, function(){
				$(this).remove();
			});
		}
	}

    /**
     * Helper.ajax
     * Returns a simple Ajax request. Should use the result with a promise.
     * Will automatically parse any URL parameters and place them in the JSON
     * body instead.
     *
     * @since 1.0.0
     * @version 1.0.0
     */
    Helper.ajax = function(url, request, type, dataType, preloader_el){
    	// Default data.
    	var default_params = {
			ajaxrequest: true,
			request    : (!_.isEmpty(request)) ? request : false
    	};
    	// Get params (if any).
    	var optional_params = Helper.parse_url_params(url);
    	// Merge params to get data.
    	var data = $.extend({}, default_params, optional_params);
		// Request.
        return $.ajax({
            url     : (url.indexOf('?') != -1) ? url.split('?')[0] : url,
            type    : (!Helper.isEmpty(type)) ? type : 'POST',
            dataType: (!Helper.isEmpty(dataType)) ? dataType : 'JSON',
            data    : data,
            beforeSend: function(jqXHR, settings){
            	// Log full URL.
            	Helpers.log(settings.url + '?' + settings.data);
                // Add preloader.
                Helper.preloader((Helper.isEmpty(preloader_el)) ? $('body') : preloader_el);
            },
            complete: function(jqXHR){
                // Destroy preloader.
                Helper.preloader((Helper.isEmpty(preloader_el)) ? $('body') : preloader_el, true);
            }
        });
    }

	/**
	 * Helper.parse_url_params
	 * Converts the URL parameters into an object.
     *
     * @since 1.0.0
     * @version 1.0.0
	**/
	Helper.parse_url_params = function(url){
		// Check if URL contains a ?.
		if(url.indexOf('?') != -1){
			// Split URL at ?
			var url_parsed = url.split('?')[1],
				url_params = (!Helper.isEmpty(url_parsed)) ? url_parsed : false;

			return (url_params) ? JSON.parse('{"' + decodeURI(url_params).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}') : false;
		}
		else{
			return {};
		}
	}

    /**
     * Helper.decode_entities
     * Decodes HTML entities.
     *
     * @since 1.0.0
     * @version 1.0.0
     */
    Helper.decode_entities = function(string){
    	// Create pseudo element.
	    var pseudo = document.createElement('textarea');
	    // Decode.
	    pseudo.innerHTML = string;

	    return pseudo.value;
	}

	// Export
	module.exports = Helpers;

}(window.Helpers = window.Helpers || {}, window));
<|endoftext|>


<commit_before>var validateHTTP = require("./validateHTTP.js"),
    restify = require('restify'),
    request = require('request'),
    rand = require('csprng'),
    sha1 = require('sha1'),
    uuid = require('node-uuid'),
    neo4j = require('node-neo4j'),
    Promise = require('promise');
module.exports.creategroup = function(req, res, next) {
    if((validateHTTP.validateHTTP(req, res, next, 'users')) === true) {
        db = new neo4j('http://localhost:7474');
        console.log('NEW GROUP!');
        console.log('PUT: ' + req.params.groupname)
        console.log('FOR COMPETITION: ' + req.params.competition)
        var url = 'http://localhost:5984/groups/' + req.params.groupname;
        var competition = req.params.competition
        var groupname = req.params.groupname
        var description = req.params.description
        var groupid = 0;
        var userid = 0;
        validateHTTP.validateHTTP(req, res, next, 'users')
        var topres = res
        request.get(url, function(err, response, body) {
            if(err) {
                return next(new restify.InternalServerError('Error has occured'));
            }
            // if the document isnt found it will create it from sratch
            console.log('code' + response.statusCode)
            if(response.statusCode === 200) {
                return next(new restify.ConflictError('Group Already Created'));
            } else if(response.statusCode === 404) {
                db.cypherQuery(" MATCH (n:competition) WHERE n.name ='" + competition + "' RETURN n", function(err, result) {
                    if(err) throw err;
                    if(result.data.length == 0) {
                        return next(new restify.InternalServerError('no competition found'));
                    } else {
                        var competitionid = result.data[0]._id
                        console.log('Groupname = ' + groupname)
                        db.cypherQuery("MATCH (n:group) WHERE n.name ='" + groupname + "' RETURN n", function(err, results) {
                            if(err) throw err;
                            console.log('Group data = ' + results.data)
                            if(results.data.length == 0) {
                                db.insertNode({
                                    name: groupname,
                                    description: description
                                }, ['Group', competition], function(err, node) {
                                    if(err) throw err;
                                    // Output node properties.
                                    console.log('New neo4j node created with Groupname  = ' + node.name);
                                    groupid = node._id
                                    console.log('group id = ' + groupid)
                                    console.log('starting insert relationship')
                                    db.insertRelationship(node._id, competitionid, 'COMPETING_IN', {
                                        description: 'competiting in this competition'
                                    }, function(err, relationship) {
                                        if(err) throw err;
                                        console.log('relationship made')
                                        // Output relationship id.
                                        console.log(relationship._id);
                                        // Output relationship start_node_id.
                                        console.log(relationship._start);
                                        // Output relationship end_node_id.
                                        console.log(relationship._end);
                                        db.cypherQuery(" MATCH (n:User) WHERE n.name ='" + req.authorization.basic.username + "' RETURN n", function(err, Results) {
                                            if(err) throw err;
                                            console.log('name = ' + Results.data[0])
                                            console.log('user = ' + Results.data[0]._id)
                                            userid = Results.data[0]._id
                                            console.log('userid =' + userid)
                                            console.log(groupid)
                                            db.insertRelationship(userid, groupid, 'IN_GROUP', {
                                                description: 'Created this group'
                                            }, function(err, relationship) {
                                                if(err) throw err;
                                                console.log('relationship made')
                                                // Output relationship id.
                                                console.log(relationship._id);
                                                // Output relationship start_node_id.
                                                console.log(relationship._start);
                                                // Output relationship end_node_id.
                                                console.log(relationship._end);
                                                var d = new Date(),
                                                    date = d.toUTCString();
                                                console.log(date);
                                                var doc = {
                                                    groupname: groupname,
                                                    description: description,
                                                    date_joined: date,
                                                    last_modified: date,
                                                    createdby: req.authorization.basic.username,
                                                    grouppoints: 0,
                                                    transactions: [],
                                                    usersjoined: [req.authorization.basic.username],
                                                    competition: competition,
                                                    groupnodeid: groupid
                                                };
                                                var docStr = JSON.stringify(doc);
                                                var params = {
                                                    uri: url,
                                                    body: JSON.stringify(doc)
                                                };
                                                request.put(params, function(err, response, body) {
                                                    if(err) {
                                                        return next(new restify.InternalServerError('Cant create document'));
                                                    }
                                                    // document has been inserted into database
                                                    body = JSON.parse(body);
                                                    console.log('about to sent res')
                                                    topres.send({
                                                        Group: req.params
                                                    });
                                                    topres.end();
                                                });
                                            });
                                        });
                                    });
                                });
                            } else {
                                console.log(result.data[0])
                                return next(new restify.ConflictError('Group already created'));
                            }
                        })
                    }
                    console.log(result.data.length); // delivers an array of query results
                });
                //
            };
        });
        // if the document is found, that means the user is already created.
    }
};
module.exports.showgroup = function(req, res, next) {
    db = new neo4j('http://localhost:7474');
    console.log('GET');
    console.log('GET: ' + req.params.groupname);
    var url = 'http://localhost:5984/groups/' + req.params.groupname;
    validateHTTP.validateHTTP(req, res, next, "users")
    var topres = res
    request.get(url, function(err, response, body) {
        if(err) {
            return next(new restify.InternalServerError('Failed To Connect To Database'));
        }
        // if the document isnt found it will create it from sratch
        console.log('code' + response.statusCode)
        if(response.statusCode === 200) {
            body = JSON.parse(body);
            //res.header('ETag', body._rev);
            res.header('Last-Modified', body.last_modified);
            res.header('Accepts', 'GET');
            group = {
                id: body._id,
                groupname: body.groupname,
                description: body.description,
                last_modified: body.last_modified,
                points: body.grouppoints,
                transactions: body.transactions,
                owner: body.createdby,
                groupmemebers: body.usersjoined
            }
            console.log(group)
            console.log("Set Group data");
            res.send(group);
            console.log("sent group data");
            res.end();
        } else if(response.statusCode === 404) {
            return next(new restify.ConflictError('Group Already Created'));
        }
    });
};
module.exports.showcompetitiongroup = function(req, res, next) {
    //match (n:freshers)-[COMPETING_IN]->r return n,r
    db = new neo4j('http://localhost:7474');
    console.log('GET');
    console.log('GET COMPETITION GROUPS: ' + req.params.competition)
    var url = 'http://localhost:5984/groups/' + req.params.groupname;
    var competition = req.params.competition
    validateHTTP.validateHTTP(req, res, next)
    var topres = res
    db.cypherQuery("match (n:" + competition + ")-[COMPETING_IN]->r return labels(n),n,r", function(err, Results) {
        if(err) throw err;
        if(Results.data == 0) {
            return next(new restify.NotFoundError('Competition not found'));
        } else {
            res.send(Results.data);
            console.log("competition data sent");
            res.end();
        }
    });
};
module.exports.joinGroup = function(req, res, next) {
    var db = new neo4j('http://localhost:7474');
    console.log('PUT');
    console.log('JOIN GROUP: ' + req.params.username + ' ' + req.params.groupname)
    var url = 'http://localhost:5984/users/' + req.authorization.basic.username;
    var groupurl = 'http://localhost:5984/groups/' + req.params.groupname;
    var userid = 0,
        groupid = 0,
        groupname = req.params.groupname,
        username = req.authorization.basic.username;
    validateHTTP.validateHTTP(req, res, next, "users");
    var topres = res
    //check user exists
    request.get(url, function(err, response, body) {
        console.log("request started")
        // if user is not found will send 404 error
        if(response.statusCode == 404) {
            return next(new restify.BadRequestError('User Not Found'))
        };
        if(response.statusCode == 200) {
            body = JSON.parse(body);
            console.log('set user id')
            userid = body.nodeid;
            //check group exists
            db.cypherQuery("match n where n.name='" + groupname + "' return n", function(err, Results) {
                if(err) throw err;
                if(Results.data == 0) {
                    return next(new restify.NotFoundError('Group not found'));
                } else {
                    groupid = Results.data[0]._id
                    console.log("Group ID set");
                    var d = new Date(),
                        date = d.toUTCString();
                    console.log(date);
                    //make relationship
                    db.insertRelationship(userid, groupid, 'IN_GROUP', {
                        datejoined: date,
                    }, function(err, relationship) {
                        if(err) throw err;
                        console.log("set user");
                        res.send("relationship created @ " + date);
                        console.log("sent data");
                        res.end();
                    });
                }
            });
        };
    });
};
// rebuilding with promises and closures
var groups = (function() {
    var url = "",
        competition = "",
        groupname = "",
        description = "",
        groupid = 0,
        userid = 0,
        competitionid = "";
    return {
        createGroup: function(req, res, next) {
            url = 'http://localhost:5984/groups/' + req.params.groupname
            var competition = req.params.competition
            var groupname = req.params.groupname
            var description = req.params.description
            req.
            var groupid = 0;
            var userid = 0;
            getRequest(url).
            catch(function(err) {
                return next(new restify.InternalServerError('Error has occured'));
            }).then(function(call) {
                if(response.statusCode === 200) {
                    return next(new restify.ConflictError('Group Already Created'));
                }
            }).then(db.cypherQuery(" MATCH (n:competition) WHERE n.name ='" + competition + "' RETURN n", function(err, result) {
                if(err) throw err;
                if(result.data.length == 0) {
                    return next(new restify.InternalServerError('no competition found'));
                }
                return competitionid = result.data[0]._id
            })).then(function(i1d) {
                db.cypherQuery("MATCH (n:group) WHERE n.name ='" + groupname + "' RETURN n", function(err, results) {
                    if(err) throw err;
                    if(results.data.length == 0) {
                        return results.data
                    } else {
                        console.log(result.data[0])
                        return next(new restify.ConflictError('Group already created'));
                    }
                })
            }).then(function(data) {
                db.insertNode({
                    name: groupname,
                    description: description
                }, ['Group', competition], function(err, node) {
                    if(err) throw err;
                    // Output node properties.
                    console.log('New neo4j node created with Groupname  = ' + node.name);
                    groupid = node._id
                    console.log('group id = ' + groupid)
                    return node._id
                });
            }).then(function(nodeid) {
                db.insertRelationship(node._id, competitionid, 'COMPETING_IN', {
                    description: 'competiting in this competition'
                }, function(err, relationship) {
                    if(err) throw err;
                    console.log('relationship made')
                    // Output relationship id.
                    console.log(relationship._id);
                    // Output relationship start_node_id.
                    console.log(relationship._start);
                    // Output relationship end_node_id.
                    console.log(relationship._end);
                })
            }).then(function() {
                db.cypherQuery(" MATCH (n:User) WHERE n.name ='" + req.authorization.basic.username + "' RETURN n", function(err, Results) {
                    if(err) throw err;
                    console.log('name = ' + Results.data[0])
                    console.log('user = ' + Results.data[0]._id)
                    userid = Results.data[0]._id
                    console.log('userid =' + userid)
                    console.log(groupid)
                    return userid
                })
            }).then(function(id) {
                db.insertRelationship(userid, groupid, 'IN_GROUP', {
                    description: 'Created this group'
                }, function(err, relationship) {
                    if(err) throw err;
                    console.log('relationship made')
                    // Output relationship id.
                    console.log(relationship._id);
                    // Output relationship start_node_id.
                    console.log(relationship._start);
                    // Output relationship end_node_id.
                    console.log(relationship._end);
                })
            }).then(function() {
                var d = new Date(),
                    date = d.toUTCString();
                console.log(date);
                var doc = {
                    groupname: groupname,
                    description: description,
                    date_joined: date,
                    last_modified: date,
                    createdby: req.authorization.basic.username,
                    grouppoints: 0,
                    transactions: [],
                    usersjoined: [req.authorization.basic.username],
                    competition: competition,
                    groupnodeid: groupid
                };
                var docStr = JSON.stringify(doc);
                var params = {
                    uri: url,
                    body: JSON.stringify(doc)
                };
                return params
            }).then(function(params) {
                request.put(params, function(err, response, body) {
                    if(err) {
                        return next(new restify.InternalServerError('Cant create document'));
                    }
                    // document has been inserted into database
                    body = JSON.parse(body);
                    console.log('about to sent res')
                    res.send({
                        Group: req.params
                    });
                    res.end();
                });
            })
        },
        getRequest: function(url) {
            // set up initial get request.
            return new Promise(function(resolve, reject) {
                request.get(url, function(err, response, body) {
                    if(err) reject(err);
                    // if the document isnt found it will create it from sratch
                    console.log('code' + response.statusCode)
                    resolve({
                        response: response,
                        body: body
                    })
                })
            });
        },
        putRequest: function(params) {
            return new Promise(function(resolve, reject) {
                request.put(params, function(err, response, body) {
                    if(err) reject(err);
                    // if the document isnt found it will create it from sratch
                    console.log('code' + response.statusCode)
                    resolve({
                        response: response,
                        body: body
                    })
                })
            });
        },
        nodequery: function(query) {
            return new Promise(function(resolve, reject) {})
        }
    }
})();
module.exports.delgroup = function(req, res, next) {
    // check group exists
    // check owner is correct
    // delete relationships
    // delete couchdb
    //
    // send back success.
}

module.exports = groups;<commit_msg>removed stray req.<commit_after>var validateHTTP = require("./validateHTTP.js"),
    restify = require('restify'),
    request = require('request'),
    rand = require('csprng'),
    sha1 = require('sha1'),
    uuid = require('node-uuid'),
    neo4j = require('node-neo4j'),
    Promise = require('promise');
module.exports.creategroup = function(req, res, next) {
    if((validateHTTP.validateHTTP(req, res, next, 'users')) === true) {
        db = new neo4j('http://localhost:7474');
        console.log('NEW GROUP!');
        console.log('PUT: ' + req.params.groupname)
        console.log('FOR COMPETITION: ' + req.params.competition)
        var url = 'http://localhost:5984/groups/' + req.params.groupname;
        var competition = req.params.competition
        var groupname = req.params.groupname
        var description = req.params.description
        var groupid = 0;
        var userid = 0;
        validateHTTP.validateHTTP(req, res, next, 'users')
        var topres = res
        request.get(url, function(err, response, body) {
            if(err) {
                return next(new restify.InternalServerError('Error has occured'));
            }
            // if the document isnt found it will create it from sratch
            console.log('code' + response.statusCode)
            if(response.statusCode === 200) {
                return next(new restify.ConflictError('Group Already Created'));
            } else if(response.statusCode === 404) {
                db.cypherQuery(" MATCH (n:competition) WHERE n.name ='" + competition + "' RETURN n", function(err, result) {
                    if(err) throw err;
                    if(result.data.length == 0) {
                        return next(new restify.InternalServerError('no competition found'));
                    } else {
                        var competitionid = result.data[0]._id
                        console.log('Groupname = ' + groupname)
                        db.cypherQuery("MATCH (n:group) WHERE n.name ='" + groupname + "' RETURN n", function(err, results) {
                            if(err) throw err;
                            console.log('Group data = ' + results.data)
                            if(results.data.length == 0) {
                                db.insertNode({
                                    name: groupname,
                                    description: description
                                }, ['Group', competition], function(err, node) {
                                    if(err) throw err;
                                    // Output node properties.
                                    console.log('New neo4j node created with Groupname  = ' + node.name);
                                    groupid = node._id
                                    console.log('group id = ' + groupid)
                                    console.log('starting insert relationship')
                                    db.insertRelationship(node._id, competitionid, 'COMPETING_IN', {
                                        description: 'competiting in this competition'
                                    }, function(err, relationship) {
                                        if(err) throw err;
                                        console.log('relationship made')
                                        // Output relationship id.
                                        console.log(relationship._id);
                                        // Output relationship start_node_id.
                                        console.log(relationship._start);
                                        // Output relationship end_node_id.
                                        console.log(relationship._end);
                                        db.cypherQuery(" MATCH (n:User) WHERE n.name ='" + req.authorization.basic.username + "' RETURN n", function(err, Results) {
                                            if(err) throw err;
                                            console.log('name = ' + Results.data[0])
                                            console.log('user = ' + Results.data[0]._id)
                                            userid = Results.data[0]._id
                                            console.log('userid =' + userid)
                                            console.log(groupid)
                                            db.insertRelationship(userid, groupid, 'IN_GROUP', {
                                                description: 'Created this group'
                                            }, function(err, relationship) {
                                                if(err) throw err;
                                                console.log('relationship made')
                                                // Output relationship id.
                                                console.log(relationship._id);
                                                // Output relationship start_node_id.
                                                console.log(relationship._start);
                                                // Output relationship end_node_id.
                                                console.log(relationship._end);
                                                var d = new Date(),
                                                    date = d.toUTCString();
                                                console.log(date);
                                                var doc = {
                                                    groupname: groupname,
                                                    description: description,
                                                    date_joined: date,
                                                    last_modified: date,
                                                    createdby: req.authorization.basic.username,
                                                    grouppoints: 0,
                                                    transactions: [],
                                                    usersjoined: [req.authorization.basic.username],
                                                    competition: competition,
                                                    groupnodeid: groupid
                                                };
                                                var docStr = JSON.stringify(doc);
                                                var params = {
                                                    uri: url,
                                                    body: JSON.stringify(doc)
                                                };
                                                request.put(params, function(err, response, body) {
                                                    if(err) {
                                                        return next(new restify.InternalServerError('Cant create document'));
                                                    }
                                                    // document has been inserted into database
                                                    body = JSON.parse(body);
                                                    console.log('about to sent res')
                                                    topres.send({
                                                        Group: req.params
                                                    });
                                                    topres.end();
                                                });
                                            });
                                        });
                                    });
                                });
                            } else {
                                console.log(result.data[0])
                                return next(new restify.ConflictError('Group already created'));
                            }
                        })
                    }
                    console.log(result.data.length); // delivers an array of query results
                });
                //
            };
        });
        // if the document is found, that means the user is already created.
    }
};
module.exports.showgroup = function(req, res, next) {
    db = new neo4j('http://localhost:7474');
    console.log('GET');
    console.log('GET: ' + req.params.groupname);
    var url = 'http://localhost:5984/groups/' + req.params.groupname;
    validateHTTP.validateHTTP(req, res, next, "users")
    var topres = res
    request.get(url, function(err, response, body) {
        if(err) {
            return next(new restify.InternalServerError('Failed To Connect To Database'));
        }
        // if the document isnt found it will create it from sratch
        console.log('code' + response.statusCode)
        if(response.statusCode === 200) {
            body = JSON.parse(body);
            //res.header('ETag', body._rev);
            res.header('Last-Modified', body.last_modified);
            res.header('Accepts', 'GET');
            group = {
                id: body._id,
                groupname: body.groupname,
                description: body.description,
                last_modified: body.last_modified,
                points: body.grouppoints,
                transactions: body.transactions,
                owner: body.createdby,
                groupmemebers: body.usersjoined
            }
            console.log(group)
            console.log("Set Group data");
            res.send(group);
            console.log("sent group data");
            res.end();
        } else if(response.statusCode === 404) {
            return next(new restify.ConflictError('Group Already Created'));
        }
    });
};
module.exports.showcompetitiongroup = function(req, res, next) {
    //match (n:freshers)-[COMPETING_IN]->r return n,r
    db = new neo4j('http://localhost:7474');
    console.log('GET');
    console.log('GET COMPETITION GROUPS: ' + req.params.competition)
    var url = 'http://localhost:5984/groups/' + req.params.groupname;
    var competition = req.params.competition
    validateHTTP.validateHTTP(req, res, next)
    var topres = res
    db.cypherQuery("match (n:" + competition + ")-[COMPETING_IN]->r return labels(n),n,r", function(err, Results) {
        if(err) throw err;
        if(Results.data == 0) {
            return next(new restify.NotFoundError('Competition not found'));
        } else {
            res.send(Results.data);
            console.log("competition data sent");
            res.end();
        }
    });
};
module.exports.joinGroup = function(req, res, next) {
    var db = new neo4j('http://localhost:7474');
    console.log('PUT');
    console.log('JOIN GROUP: ' + req.params.username + ' ' + req.params.groupname)
    var url = 'http://localhost:5984/users/' + req.authorization.basic.username;
    var groupurl = 'http://localhost:5984/groups/' + req.params.groupname;
    var userid = 0,
        groupid = 0,
        groupname = req.params.groupname,
        username = req.authorization.basic.username;
    validateHTTP.validateHTTP(req, res, next, "users");
    var topres = res
    //check user exists
    request.get(url, function(err, response, body) {
        console.log("request started")
        // if user is not found will send 404 error
        if(response.statusCode == 404) {
            return next(new restify.BadRequestError('User Not Found'))
        };
        if(response.statusCode == 200) {
            body = JSON.parse(body);
            console.log('set user id')
            userid = body.nodeid;
            //check group exists
            db.cypherQuery("match n where n.name='" + groupname + "' return n", function(err, Results) {
                if(err) throw err;
                if(Results.data == 0) {
                    return next(new restify.NotFoundError('Group not found'));
                } else {
                    groupid = Results.data[0]._id
                    console.log("Group ID set");
                    var d = new Date(),
                        date = d.toUTCString();
                    console.log(date);
                    //make relationship
                    db.insertRelationship(userid, groupid, 'IN_GROUP', {
                        datejoined: date,
                    }, function(err, relationship) {
                        if(err) throw err;
                        console.log("set user");
                        res.send("relationship created @ " + date);
                        console.log("sent data");
                        res.end();
                    });
                }
            });
        };
    });
};
// rebuilding with promises and closures
var groups = (function() {
    var url = "",
        competition = "",
        groupname = "",
        description = "",
        groupid = 0,
        userid = 0,
        competitionid = "";
    return {
        createGroup: function(req, res, next) {
            url = 'http://localhost:5984/groups/' + req.params.groupname
            var competition = req.params.competition;
            var groupname = req.params.groupname;
            var description = req.params.description;
            var groupid = 0;
            var userid = 0;
            getRequest(url).
            catch(function(err) {
                return next(new restify.InternalServerError('Error has occured'));
            }).then(function(call) {
                if(response.statusCode === 200) {
                    return next(new restify.ConflictError('Group Already Created'));
                }
            }).then(db.cypherQuery(" MATCH (n:competition) WHERE n.name ='" + competition + "' RETURN n", function(err, result) {
                if(err) throw err;
                if(result.data.length == 0) {
                    return next(new restify.InternalServerError('no competition found'));
                }
                return competitionid = result.data[0]._id
            })).then(function(i1d) {
                db.cypherQuery("MATCH (n:group) WHERE n.name ='" + groupname + "' RETURN n", function(err, results) {
                    if(err) throw err;
                    if(results.data.length == 0) {
                        return results.data
                    } else {
                        console.log(result.data[0])
                        return next(new restify.ConflictError('Group already created'));
                    }
                })
            }).then(function(data) {
                db.insertNode({
                    name: groupname,
                    description: description
                }, ['Group', competition], function(err, node) {
                    if(err) throw err;
                    // Output node properties.
                    console.log('New neo4j node created with Groupname  = ' + node.name);
                    groupid = node._id
                    console.log('group id = ' + groupid)
                    return node._id
                });
            }).then(function(nodeid) {
                db.insertRelationship(node._id, competitionid, 'COMPETING_IN', {
                    description: 'competiting in this competition'
                }, function(err, relationship) {
                    if(err) throw err;
                    console.log('relationship made')
                    // Output relationship id.
                    console.log(relationship._id);
                    // Output relationship start_node_id.
                    console.log(relationship._start);
                    // Output relationship end_node_id.
                    console.log(relationship._end);
                })
            }).then(function() {
                db.cypherQuery(" MATCH (n:User) WHERE n.name ='" + req.authorization.basic.username + "' RETURN n", function(err, Results) {
                    if(err) throw err;
                    console.log('name = ' + Results.data[0])
                    console.log('user = ' + Results.data[0]._id)
                    userid = Results.data[0]._id
                    console.log('userid =' + userid)
                    console.log(groupid)
                    return userid
                })
            }).then(function(id) {
                db.insertRelationship(userid, groupid, 'IN_GROUP', {
                    description: 'Created this group'
                }, function(err, relationship) {
                    if(err) throw err;
                    console.log('relationship made')
                    // Output relationship id.
                    console.log(relationship._id);
                    // Output relationship start_node_id.
                    console.log(relationship._start);
                    // Output relationship end_node_id.
                    console.log(relationship._end);
                })
            }).then(function() {
                var d = new Date(),
                    date = d.toUTCString();
                console.log(date);
                var doc = {
                    groupname: groupname,
                    description: description,
                    date_joined: date,
                    last_modified: date,
                    createdby: req.authorization.basic.username,
                    grouppoints: 0,
                    transactions: [],
                    usersjoined: [req.authorization.basic.username],
                    competition: competition,
                    groupnodeid: groupid
                };
                var docStr = JSON.stringify(doc);
                var params = {
                    uri: url,
                    body: JSON.stringify(doc)
                };
                return params
            }).then(function(params) {
                request.put(params, function(err, response, body) {
                    if(err) {
                        return next(new restify.InternalServerError('Cant create document'));
                    }
                    // document has been inserted into database
                    body = JSON.parse(body);
                    console.log('about to sent res')
                    res.send({
                        Group: req.params
                    });
                    res.end();
                });
            })
        },
        getRequest: function(url) {
            // set up initial get request.
            return new Promise(function(resolve, reject) {
                request.get(url, function(err, response, body) {
                    if(err) reject(err);
                    // if the document isnt found it will create it from sratch
                    console.log('code' + response.statusCode)
                    resolve({
                        response: response,
                        body: body
                    })
                })
            });
        },
        putRequest: function(params) {
            return new Promise(function(resolve, reject) {
                request.put(params, function(err, response, body) {
                    if(err) reject(err);
                    // if the document isnt found it will create it from sratch
                    console.log('code' + response.statusCode)
                    resolve({
                        response: response,
                        body: body
                    })
                })
            });
        },
        nodequery: function(query) {
            return new Promise(function(resolve, reject) {})
        }
    }
})();
module.exports.delgroup = function(req, res, next) {
    // check group exists
    // check owner is correct
    // delete relationships
    // delete couchdb
    //
    // send back success.
}

module.exports = groups;<|endoftext|>