<commit_before>var _ = require('lodash');
var blessed = require('blessed');
var htmlentities = require('ent');
var colors = require('colors');

var utils = require('./utils');
var updates = require('./updates');

var screen;
var googleList;
var answersList;
var logBox;

function exit() {
    screen.destroy();
    var msg = updates.getResult();
    if(msg) {
        console.error(msg);
    }
    process.exit(0);
}

function start() {
    updates.checkForUpdates();

    screen = blessed.screen({
        smartCSR: true,
        autoPadding: true
    });

    screen.title = 'how2';

    screen.key(['C-c'], function(ch, key) {
        exit();
    });

    var logText =
        colors.bgBlue.white.bold(' Enter/Space ')+' open link '+
        colors.bgBlue.white.bold(' B ') + ' open browser '+
        colors.bgBlue.white.bold(' Esc ') + ' close window';
    logBox = blessed.box({
        width: '100%',
        top: '100%-1',
        content: logText
    });
    screen.append(logBox);
    screen.render();
}

function listStyle() {
    return {
        selectedBg: 'blue',
        selectedFg: 'white',
        mouse: true,
        keys: true,
        vi: true
    };
}

function showGoogling() {
    var box = blessed.box({
        content: 'Googling...'
    });
    screen.append(box);
    screen.render();
}

function showGoogleList(links, titles, callback) {
    var options = {
        parent: screen,
        width: '100%',
        height: '100%-1',
        top: 'center',
        left: 'center',
        padding: 1,
        title: 'Select Answer:',
        mouse: true
    }
    _.extend(options, listStyle());
    googleList = blessed.list(options);

    googleList.setItems(titles);

    googleList.prepend(new blessed.Text({
        content: 'Select one code tip:'
    }));

    googleList.on('select', function(event) {
        callback(this.selected);
    });

    googleList.key(['space', 'o'], function() {
        googleList.enterSelected();
        screen.render();
    });

    googleList.key(['escape', 'q'], function() {
        exit();
    });

    googleList.key(['b'], function() {
        var link = links[this.selected]
        try {
            require('openurl').open(link.link);
        }
        catch(e) {}
    });

    googleList.select(0);
    googleList.focus();
    screen.render();
}

function makeTitleForAnswer(answer) {
    var withColors = utils.marked(answer.body_markdown);

    var lines = withColors.split('\n');

    var firstLine;
    for(var i=0; i < lines.length; i++) {
        firstLine = lines[i]
        if(firstLine !== '') break;
    }
    firstLine = htmlentities.decode(firstLine);
    var score = '('+answer.score+') ';
    return score + firstLine;
}

function showAnswers(answers, callback) {
    var listBox = blessed.box({
        top: 'center',
        left: 'center',
        width: '90%',
        height: '90%',
        border: {
            type: 'line',
        },
        tags: true,
    });

    var listOptions = {
        parent: listBox,
        border: {
            type: 'bg',
        },
    };
    _.extend(listOptions, listStyle());
    answersList = blessed.list(listOptions);

    answersList.setItems(answers.map(makeTitleForAnswer));

    answersList.on('select', function() {
        callback(this.selected);
    });

    answersList.key(['space', 'o'], function() {
        answersList.enterSelected();
        screen.render();
    });

    answersList.key(['b'], function(event) {
        var answer = answers[this.selected];
        require('openurl').open(answer.link);
    });

    answersList.key(['escape', 'q'], function() {
        screen.remove(listBox);
        googleList.focus();
        screen.render();
    });

    listBox.append(answersList);
    answersList.focus();
    screen.append(listBox);
    screen.render();
}

function showAnswer(answer) {
    var text = utils.toEscapedMarkdown(answer.body_markdown);

    var answerBox = blessed.box({
        top: 'center',
        left: 'center',
        width: '80%',
        height: '80%',
        border: {
            type: 'line',
        },
        padding : 1,
        scrollable: true,
        alwaysScroll: true,
        scrollbar: {
            border: {
                bg: 'yellow'
            },
            bg: 'yellow'
        },
        keys: true,
        vi: true,
        mouse: true
    });

    answerBox.setContent(text);

    answerBox.key(['escape', 'q'], function() {
        screen.remove(answerBox);
        answersList.focus();
        screen.render();
    });

    screen.append(answerBox);
    answerBox.focus();
    screen.render();
}

function magicSelect(rows) {
    screen = blessed.screen({
        autoPadding: true
    });
    var list = blessed.list({
    });
    list.setItems(rows);
    screen.append(list);
    screen.render();
}

module.exports = {
    start: start,
    stop: function() {
        if(screen) {
            screen.destroy();
        }
    },
    showGoogling: showGoogling,
    showGoogleList: showGoogleList,
    showAnswers: showAnswers,
    showAnswer: showAnswer,
    magicSelect: magicSelect
};
<commit_msg>removed mouse:true. now you can copy-paste<commit_after>var _ = require('lodash');
var blessed = require('blessed');
var htmlentities = require('ent');
var colors = require('colors');

var utils = require('./utils');
var updates = require('./updates');

var screen;
var googleList;
var answersList;
var logBox;

function exit() {
    screen.destroy();
    var msg = updates.getResult();
    if(msg) {
        console.error(msg);
    }
    process.exit(0);
}

function start() {
    updates.checkForUpdates();

    screen = blessed.screen({
        smartCSR: true,
        autoPadding: true
    });

    screen.title = 'how2';

    screen.key(['C-c'], function(ch, key) {
        exit();
    });

    var logText =
        colors.bgBlue.white.bold(' Enter/Space ')+' open link '+
        colors.bgBlue.white.bold(' B ') + ' open browser '+
        colors.bgBlue.white.bold(' Esc ') + ' close window';
    logBox = blessed.box({
        width: '100%',
        top: '100%-1',
        content: logText
    });
    screen.append(logBox);
    screen.render();
}

function listStyle() {
    return {
        selectedBg: 'blue',
        selectedFg: 'white',
        // mouse: true,
        keys: true,
        vi: true
    };
}

function showGoogling() {
    var box = blessed.box({
        content: 'Googling...'
    });
    screen.append(box);
    screen.render();
}

function showGoogleList(links, titles, callback) {
    var options = {
        parent: screen,
        width: '100%',
        height: '100%-1',
        top: 'center',
        left: 'center',
        padding: 1,
        title: 'Select Answer:',
        // mouse: true
    }
    _.extend(options, listStyle());
    googleList = blessed.list(options);

    googleList.setItems(titles);

    googleList.prepend(new blessed.Text({
        content: 'Select one code tip:'
    }));

    googleList.on('select', function(event) {
        callback(this.selected);
    });

    googleList.key(['space', 'o'], function() {
        googleList.enterSelected();
        screen.render();
    });

    googleList.key(['escape', 'q'], function() {
        exit();
    });

    googleList.key(['b'], function() {
        var link = links[this.selected]
        try {
            require('openurl').open(link.link);
        }
        catch(e) {}
    });

    googleList.select(0);
    googleList.focus();
    screen.render();
}

function makeTitleForAnswer(answer) {
    var withColors = utils.marked(answer.body_markdown);

    var lines = withColors.split('\n');

    var firstLine;
    for(var i=0; i < lines.length; i++) {
        firstLine = lines[i]
        if(firstLine !== '') break;
    }
    firstLine = htmlentities.decode(firstLine);
    var score = '('+answer.score+') ';
    return score + firstLine;
}

function showAnswers(answers, callback) {
    var listBox = blessed.box({
        top: 'center',
        left: 'center',
        width: '90%',
        height: '90%',
        border: {
            type: 'line',
        },
        tags: true,
    });

    var listOptions = {
        parent: listBox,
        border: {
            type: 'bg',
        },
    };
    _.extend(listOptions, listStyle());
    answersList = blessed.list(listOptions);

    answersList.setItems(answers.map(makeTitleForAnswer));

    answersList.on('select', function() {
        callback(this.selected);
    });

    answersList.key(['space', 'o'], function() {
        answersList.enterSelected();
        screen.render();
    });

    answersList.key(['b'], function(event) {
        var answer = answers[this.selected];
        require('openurl').open(answer.link);
    });

    answersList.key(['escape', 'q'], function() {
        screen.remove(listBox);
        googleList.focus();
        screen.render();
    });

    listBox.append(answersList);
    answersList.focus();
    screen.append(listBox);
    screen.render();
}

function showAnswer(answer) {
    var text = utils.toEscapedMarkdown(answer.body_markdown);

    var answerBox = blessed.box({
        top: 'center',
        left: 'center',
        width: '80%',
        height: '80%',
        border: {
            type: 'line',
        },
        padding : 1,
        scrollable: true,
        alwaysScroll: true,
        scrollbar: {
            border: {
                bg: 'yellow'
            },
            bg: 'yellow'
        },
        keys: true,
        vi: true,
        // mouse: true
    });

    answerBox.setContent(text);

    answerBox.key(['escape', 'q'], function() {
        screen.remove(answerBox);
        answersList.focus();
        screen.render();
    });

    screen.append(answerBox);
    answerBox.focus();
    screen.render();
}

function magicSelect(rows) {
    screen = blessed.screen({
        autoPadding: true
    });
    var list = blessed.list({
    });
    list.setItems(rows);
    screen.append(list);
    screen.render();
}

module.exports = {
    start: start,
    stop: function() {
        if(screen) {
            screen.destroy();
        }
    },
    showGoogling: showGoogling,
    showGoogleList: showGoogleList,
    showAnswers: showAnswers,
    showAnswer: showAnswer,
    magicSelect: magicSelect
};
<|endoftext|>


<commit_before>function getMousePos(evt, canvas)
{
	var rect = canvas.getBoundingClientRect();

	return	{
				x: (evt.clientX - rect.left),
				y: (evt.clientY - rect.top)
			};
}

// From http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function hexToRgb(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

function Slider(minVal, maxVal, initialVal, stepVal, callback)
{
	var currentValue = initialVal;
	var inputNode;
	var editBox;
	var textLabel;

	this.updateValue = function()
	{
		currentValue = inputNode.value * stepVal;

		textLabel.innerHTML = currentValue.toFixed(2);

		editBox.value = currentValue;
		//editBox.nodeValue = currentValue;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.showEditBox = function()
	{
		textLabel.style.display = "none";
		editBox.style.display = "inline";
	}

	this.hideEditBox = function()
	{
		textLabel.style.display = "inline";
		editBox.style.display = "none";

		currentValue = Math.max(minVal, Math.min(maxVal, editBox.valueAsNumber));
		inputNode.value = (currentValue / stepVal).toFixed(0);
		textLabel.innerHTML = currentValue.toFixed(2);

		this.updateValue();
	}

	this.editBoxKeyPress = function(evt)
	{
		if (evt.keyCode === 13)
		{
			evt.preventDefault();
			this.hideEditBox();
		}
	}

	this.addControls = function (parentElement)
	{
		var div = document.createElement('div');

		textLabel = document.createElement('text');
		textLabel.innerHTML = currentValue.toFixed(2);
		textLabel.style.display = "inline";
		textLabel.addEventListener('click', this.showEditBox.bind(this));

		editBox = document.createElement('input');
		editBox.type = "number";
		editBox.style.display = "none";
		editBox.style.width = 80;
		editBox.value = currentValue.toFixed(2);
		editBox.addEventListener('blur', this.hideEditBox.bind(this));
		editBox.addEventListener('keypress', this.editBoxKeyPress.bind(this));

		inputNode = document.createElement('input');
		inputNode.min = minVal/stepVal;
		inputNode.max = maxVal/stepVal;
		inputNode.step = 1;
		inputNode.type = "range";
		inputNode.value = currentValue/stepVal;
		inputNode.oninput = this.updateValue.bind(this);

		div.appendChild(document.createTextNode(minVal + " "));
		div.appendChild(inputNode);
		div.appendChild(document.createTextNode(" " + maxVal + " : "));
		div.appendChild(textLabel);
		div.appendChild(editBox);

		parentElement.appendChild(div);
	}
}

function LogSlider(minExponent, maxExponent, base, initialVal, stepVal, callback)
{
	var currentValue = initialVal;
	var currentExponent = Math.log10(initialVal) / Math.log10(base);
	var inputNode;
	var editBox;
	var textLabel;

	this.updateValue = function()
	{
		currentExponent = inputNode.value * stepVal;
		currentValue = Math.pow(base, currentExponent);
		textLabel.innerHTML = currentValue.toFixed(3);

		editBox.value = currentValue;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.showEditBox = function()
	{
		textLabel.style.display = "none";
		editBox.style.display = "inline";
	}

	this.hideEditBox = function()
	{
		textLabel.style.display = "inline";
		editBox.style.display = "none";

		currentExponent = Math.log10(editBox.valueAsNumber) / Math.log10(base);
		currentExponent = Math.max(minExponent, Math.min(maxExponent, editBox.valueAsNumber));
		currentValue = Math.pow(base, currentExponent);

		inputNode.value = (currentValue / stepVal).toFixed(0);
		textLabel.innerHTML = currentValue.toFixed(2);

		this.updateValue();
	}

	this.editBoxKeyPress = function(evt)
	{
		if (evt.keyCode === 13)
		{
			evt.preventDefault();
			this.hideEditBox();
		}
	}

	this.addControls = function (parentElement)
	{
		var div = document.createElement('div');

		textLabel = document.createElement('text');
		textLabel.innerHTML = currentValue.toFixed(2);
		textLabel.style.display = "inline";
		textLabel.addEventListener('click', this.showEditBox.bind(this));

		editBox = document.createElement('input');
		editBox.type = "number";
		editBox.style.display = "none";
		editBox.style.width = 80;
		editBox.value = currentValue.toFixed(2);
		editBox.addEventListener('blur', this.hideEditBox.bind(this));
		editBox.addEventListener('keypress', this.editBoxKeyPress.bind(this));

		inputNode = document.createElement('input');
		inputNode.min = minExponent/stepVal;
		inputNode.max = maxExponent/stepVal;
		inputNode.step = 1;
		inputNode.type = "range";
		inputNode.value = currentExponent/stepVal;
		inputNode.oninput = this.updateValue.bind(this);

		div.appendChild(document.createTextNode(Math.pow(base, minExponent) + " "));
		div.appendChild(inputNode);
		div.appendChild(document.createTextNode(" " + Math.pow(base, maxExponent) + " : "));
		div.appendChild(textLabel);
		div.appendChild(editBox);

		parentElement.appendChild(div);
	}
}

function Dropdown(values, initialVal, callback)
{
	var currentValue = initialVal;
	var dropdown;

	function onChange()
	{
		currentValue = dropdown.options[dropdown.selectedIndex].text;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.addControls = function (parentElement)
	{
		dropdown = document.createElement('select');

		for (var i=0; i!=values.length; ++i)
		{
			var option = document.createElement('option');
			option.text = values[i];
			dropdown.options.add(option);

			if (currentValue == values[i])
				dropdown.selectedIndex = i;
		}

		dropdown.onchange = onChange;

		parentElement.appendChild(dropdown);
	}
}

function Button(label, callback)
{
	this.addControls = function(parentElement)
	{
		var btn = document.createElement("BUTTON");
		btn.appendChild(document.createTextNode(label));
		btn.onclick = callback;
		btn.style.width = 165;
		btn.style.height = 27;
		parentElement.appendChild(btn);
	}
}

function TickBox(value, callback)
{
	var tickBox;
	var ticked = value;

	function onClick()
	{
		ticked = tickBox.checked;

		if (callback !== undefined)
		{
			callback(tickBox.checked);
		}
	}

	this.addControls = function(parentElement)
	{
		tickBox = document.createElement("INPUT");
		tickBox.setAttribute("type", "checkbox");
		tickBox.onclick = onClick;
		tickBox.checked = ticked;
		parentElement.appendChild(tickBox);
	}
}

function ColorPicker(value, callback)
{
	var picker;
	var color = value;

	function onchange()
	{
		color = picker.value;

		if (callback !== undefined)
		{
			callback(color);
		}
	}

	this.addControls = function(parentElement)
	{
		picker = document.createElement("INPUT");
		picker.setAttribute("type", "color");
		picker.onchange = onchange;
		picker.value = color;
		parentElement.appendChild(picker);
	}
}

function TextBox(value, singleLine, callback)
{
	var textArea;
	var textValue;
	var singleLine;

	function onchange()
	{
		textValue = textArea.value;

		if (callback !== undefined)
		{
			callback(textValue);
		}
	}

	this.addControls = function(parentElement)
	{
		if (singleLine)
		{
			textArea = document.createElement('input');
			textArea.type = "text";
			textArea.value = value;
			textArea.onchange = onchange;
			textArea.onkeypress = function(e)
				{
					var event = e || window.event;
					var charCode = event.which || event.keyCode;

					if ( charCode == '13' )
					{
						onchange();
					}
				}
		}
		else
		{
			textArea = document.createElement("textarea");
			textArea.style.border = "2px solid black";
			textArea.style.height = 25;
			textArea.style.width = 200;
			textArea.style.fontFamily = "Verdana,sans-serif";
			textArea.style.fontSize = "small";
			textArea.value = value;
			textArea.addEventListener('blur', onchange, false);
		}

		parentElement.appendChild(textArea);
	}
}

function Divider()
{
	this.addControls = function(parentElement)
	{
		var div = document.createElement("div");
		div.style.border = "1px solid black";
		div.style.height = 0;
		parentElement.appendChild(div);
	}
}

function PropertyGrid(parentElement)
{
	var controls = [];
	var tableElement;

	this.init = function()
	{
		tableElement = document.createElement("table");
		tableElement.className = "propertyGrid";
		tableElement.style.width = "100%";
		tableElement.style.border = 'none';//'1px solid black';
		tableElement.style.fontSize = "12px";

		parentElement.appendChild(tableElement);
	}

	this.setProperties = function(newProperties)
	{
		controls = [];

		while(tableElement.rows[0]) tableElement.deleteRow(0);

		for (var i=0; i!=newProperties.length; ++i)
		{
			this.addProperty(newProperties[i].name, newProperties[i].control);
		}

		this.show();
	}

	this.addProperty = function(name, control)
	{
		var row = tableElement.insertRow()
		var nameCell = row.insertCell();
		var valueCell = row.insertCell();
		nameCell.innerHTML = name === undefined? "" : name;
		control.addControls(valueCell);
	}

	this.getProperty = function(name)
	{
		for (var i=0; i!=controls.length; ++i)
		{
			if (controls[i].name == name)
			{
				return controls[i].control;
			}
		}

		return undefined;
	}

	this.show = function()
	{
		tableElement.style.display = "block";
	}

	this.hide = function()
	{
		tableElement.style.display = "none";
	}

	this.init();
};
<commit_msg>RGB to hex<commit_after>function getMousePos(evt, canvas)
{
	var rect = canvas.getBoundingClientRect();

	return	{
				x: (evt.clientX - rect.left),
				y: (evt.clientY - rect.top)
			};
}

// From http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function componentToHex(c)
{
	c = Math.floor(Math.max(0, Math.min(255, c)));
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b)
{
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

function hexToRgb(hex)
{
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ?
		{
			r: parseInt(result[1], 16),
			g: parseInt(result[2], 16),
			b: parseInt(result[3], 16)
		} : null;
}

function Slider(minVal, maxVal, initialVal, stepVal, callback)
{
	var currentValue = initialVal;
	var inputNode;
	var editBox;
	var textLabel;

	this.updateValue = function()
	{
		currentValue = inputNode.value * stepVal;

		textLabel.innerHTML = currentValue.toFixed(2);

		editBox.value = currentValue;
		//editBox.nodeValue = currentValue;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.showEditBox = function()
	{
		textLabel.style.display = "none";
		editBox.style.display = "inline";
	}

	this.hideEditBox = function()
	{
		textLabel.style.display = "inline";
		editBox.style.display = "none";

		currentValue = Math.max(minVal, Math.min(maxVal, editBox.valueAsNumber));
		inputNode.value = (currentValue / stepVal).toFixed(0);
		textLabel.innerHTML = currentValue.toFixed(2);

		this.updateValue();
	}

	this.editBoxKeyPress = function(evt)
	{
		if (evt.keyCode === 13)
		{
			evt.preventDefault();
			this.hideEditBox();
		}
	}

	this.addControls = function (parentElement)
	{
		var div = document.createElement('div');

		textLabel = document.createElement('text');
		textLabel.innerHTML = currentValue.toFixed(2);
		textLabel.style.display = "inline";
		textLabel.addEventListener('click', this.showEditBox.bind(this));

		editBox = document.createElement('input');
		editBox.type = "number";
		editBox.style.display = "none";
		editBox.style.width = 80;
		editBox.value = currentValue.toFixed(2);
		editBox.addEventListener('blur', this.hideEditBox.bind(this));
		editBox.addEventListener('keypress', this.editBoxKeyPress.bind(this));

		inputNode = document.createElement('input');
		inputNode.min = minVal/stepVal;
		inputNode.max = maxVal/stepVal;
		inputNode.step = 1;
		inputNode.type = "range";
		inputNode.value = currentValue/stepVal;
		inputNode.oninput = this.updateValue.bind(this);

		div.appendChild(document.createTextNode(minVal + " "));
		div.appendChild(inputNode);
		div.appendChild(document.createTextNode(" " + maxVal + " : "));
		div.appendChild(textLabel);
		div.appendChild(editBox);

		parentElement.appendChild(div);
	}
}

function LogSlider(minExponent, maxExponent, base, initialVal, stepVal, callback)
{
	var currentValue = initialVal;
	var currentExponent = Math.log10(initialVal) / Math.log10(base);
	var inputNode;
	var editBox;
	var textLabel;

	this.updateValue = function()
	{
		currentExponent = inputNode.value * stepVal;
		currentValue = Math.pow(base, currentExponent);
		textLabel.innerHTML = currentValue.toFixed(3);

		editBox.value = currentValue;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.showEditBox = function()
	{
		textLabel.style.display = "none";
		editBox.style.display = "inline";
	}

	this.hideEditBox = function()
	{
		textLabel.style.display = "inline";
		editBox.style.display = "none";

		currentExponent = Math.log10(editBox.valueAsNumber) / Math.log10(base);
		currentExponent = Math.max(minExponent, Math.min(maxExponent, editBox.valueAsNumber));
		currentValue = Math.pow(base, currentExponent);

		inputNode.value = (currentValue / stepVal).toFixed(0);
		textLabel.innerHTML = currentValue.toFixed(2);

		this.updateValue();
	}

	this.editBoxKeyPress = function(evt)
	{
		if (evt.keyCode === 13)
		{
			evt.preventDefault();
			this.hideEditBox();
		}
	}

	this.addControls = function (parentElement)
	{
		var div = document.createElement('div');

		textLabel = document.createElement('text');
		textLabel.innerHTML = currentValue.toFixed(2);
		textLabel.style.display = "inline";
		textLabel.addEventListener('click', this.showEditBox.bind(this));

		editBox = document.createElement('input');
		editBox.type = "number";
		editBox.style.display = "none";
		editBox.style.width = 80;
		editBox.value = currentValue.toFixed(2);
		editBox.addEventListener('blur', this.hideEditBox.bind(this));
		editBox.addEventListener('keypress', this.editBoxKeyPress.bind(this));

		inputNode = document.createElement('input');
		inputNode.min = minExponent/stepVal;
		inputNode.max = maxExponent/stepVal;
		inputNode.step = 1;
		inputNode.type = "range";
		inputNode.value = currentExponent/stepVal;
		inputNode.oninput = this.updateValue.bind(this);

		div.appendChild(document.createTextNode(Math.pow(base, minExponent) + " "));
		div.appendChild(inputNode);
		div.appendChild(document.createTextNode(" " + Math.pow(base, maxExponent) + " : "));
		div.appendChild(textLabel);
		div.appendChild(editBox);

		parentElement.appendChild(div);
	}
}

function Dropdown(values, initialVal, callback)
{
	var currentValue = initialVal;
	var dropdown;

	function onChange()
	{
		currentValue = dropdown.options[dropdown.selectedIndex].text;

		if (callback !== undefined)
			callback(currentValue);
	}

	this.addControls = function (parentElement)
	{
		dropdown = document.createElement('select');

		for (var i=0; i!=values.length; ++i)
		{
			var option = document.createElement('option');
			option.text = values[i];
			dropdown.options.add(option);

			if (currentValue == values[i])
				dropdown.selectedIndex = i;
		}

		dropdown.onchange = onChange;

		parentElement.appendChild(dropdown);
	}
}

function Button(label, callback)
{
	this.addControls = function(parentElement)
	{
		var btn = document.createElement("BUTTON");
		btn.appendChild(document.createTextNode(label));
		btn.onclick = callback;
		btn.style.width = 165;
		btn.style.height = 27;
		parentElement.appendChild(btn);
	}
}

function TickBox(value, callback)
{
	var tickBox;
	var ticked = value;

	function onClick()
	{
		ticked = tickBox.checked;

		if (callback !== undefined)
		{
			callback(tickBox.checked);
		}
	}

	this.addControls = function(parentElement)
	{
		tickBox = document.createElement("INPUT");
		tickBox.setAttribute("type", "checkbox");
		tickBox.onclick = onClick;
		tickBox.checked = ticked;
		parentElement.appendChild(tickBox);
	}
}

function ColorPicker(value, callback)
{
	var picker;
	var color = value;

	function onchange()
	{
		color = picker.value;

		if (callback !== undefined)
		{
			callback(color);
		}
	}

	this.addControls = function(parentElement)
	{
		picker = document.createElement("INPUT");
		picker.setAttribute("type", "color");
		picker.onchange = onchange;
		picker.value = color;
		parentElement.appendChild(picker);
	}
}

function TextBox(value, singleLine, callback)
{
	var textArea;
	var textValue;
	var singleLine;

	function onchange()
	{
		textValue = textArea.value;

		if (callback !== undefined)
		{
			callback(textValue);
		}
	}

	this.addControls = function(parentElement)
	{
		if (singleLine)
		{
			textArea = document.createElement('input');
			textArea.type = "text";
			textArea.value = value;
			textArea.onchange = onchange;
			textArea.onkeypress = function(e)
				{
					var event = e || window.event;
					var charCode = event.which || event.keyCode;

					if ( charCode == '13' )
					{
						onchange();
					}
				}
		}
		else
		{
			textArea = document.createElement("textarea");
			textArea.style.border = "2px solid black";
			textArea.style.height = 25;
			textArea.style.width = 200;
			textArea.style.fontFamily = "Verdana,sans-serif";
			textArea.style.fontSize = "small";
			textArea.value = value;
			textArea.addEventListener('blur', onchange, false);
		}

		parentElement.appendChild(textArea);
	}
}

function Divider()
{
	this.addControls = function(parentElement)
	{
		var div = document.createElement("div");
		div.style.border = "1px solid black";
		div.style.height = 0;
		parentElement.appendChild(div);
	}
}

function PropertyGrid(parentElement)
{
	var controls = [];
	var tableElement;

	this.init = function()
	{
		tableElement = document.createElement("table");
		tableElement.className = "propertyGrid";
		tableElement.style.width = "100%";
		tableElement.style.border = 'none';//'1px solid black';
		tableElement.style.fontSize = "12px";

		parentElement.appendChild(tableElement);
	}

	this.setProperties = function(newProperties)
	{
		controls = [];

		while(tableElement.rows[0]) tableElement.deleteRow(0);

		for (var i=0; i!=newProperties.length; ++i)
		{
			this.addProperty(newProperties[i].name, newProperties[i].control);
		}

		this.show();
	}

	this.addProperty = function(name, control)
	{
		var row = tableElement.insertRow()
		var nameCell = row.insertCell();
		var valueCell = row.insertCell();
		nameCell.innerHTML = name === undefined? "" : name;
		control.addControls(valueCell);
	}

	this.getProperty = function(name)
	{
		for (var i=0; i!=controls.length; ++i)
		{
			if (controls[i].name == name)
			{
				return controls[i].control;
			}
		}

		return undefined;
	}

	this.show = function()
	{
		tableElement.style.display = "block";
	}

	this.hide = function()
	{
		tableElement.style.display = "none";
	}

	this.init();
};
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  enable: enableV5
};

function enableV5(ajv) {
  ajv.addKeyword('constant', { macro: constantMacro });
  ajv.addKeyword('contains', { macro: containsMacro });
  ajv.addKeyword('formatMaximum', { type: 'string', inline: inlineFormatLimit('maximum') });
  ajv.addKeyword('formatMinimum', { type: 'string', inline: inlineFormatLimit('minimum') });
  ajv.addKeyword('exclusiveFormatMaximum');
  ajv.addKeyword('exclusiveFormatMinimum');
  ajv.addKeyword('patternGroups');
}

function constantMacro(schema) {
  return { enum: [schema] };
}

function containsMacro(schema) {
  return { not: { items: { not: schema } } };
}

function inlineFormatLimit(limit) {
  return function(it, schema, parentSchema) {
    var format = parentSchema.format;
    var compare = it.formats[format].compare;
    if (!compare) throw new Error('No format or no comparison for the format');
    var exclusive = parentSchema[limit == 'minimum' ? 'exclusiveFormatMinimum' : 'exclusiveFormatMaximum'];
    var data = 'data' + (it.dataLevel || '');
    var op = limit == 'minimum' ? '>' : '<';
    if (!exclusive) op += '=';
    return 'formats' + it.util.getProperty(format) + '.compare('
            + data + ', ' + it.util.toQuotedString(schema)
            + ') ' + op + ' 0';
  }
}
<commit_msg>semicolon<commit_after>'use strict';

module.exports = {
  enable: enableV5
};

function enableV5(ajv) {
  ajv.addKeyword('constant', { macro: constantMacro });
  ajv.addKeyword('contains', { macro: containsMacro });
  ajv.addKeyword('formatMaximum', { type: 'string', inline: inlineFormatLimit('maximum') });
  ajv.addKeyword('formatMinimum', { type: 'string', inline: inlineFormatLimit('minimum') });
  ajv.addKeyword('exclusiveFormatMaximum');
  ajv.addKeyword('exclusiveFormatMinimum');
  ajv.addKeyword('patternGroups');
}

function constantMacro(schema) {
  return { enum: [schema] };
}

function containsMacro(schema) {
  return { not: { items: { not: schema } } };
}

function inlineFormatLimit(limit) {
  return function(it, schema, parentSchema) {
    var format = parentSchema.format;
    var compare = it.formats[format].compare;
    if (!compare) throw new Error('No format or no comparison for the format');
    var exclusive = parentSchema[limit == 'minimum' ? 'exclusiveFormatMinimum' : 'exclusiveFormatMaximum'];
    var data = 'data' + (it.dataLevel || '');
    var op = limit == 'minimum' ? '>' : '<';
    if (!exclusive) op += '=';
    return 'formats' + it.util.getProperty(format) + '.compare('
            + data + ', ' + it.util.toQuotedString(schema)
            + ') ' + op + ' 0';
  };
}
<|endoftext|>


<commit_before>'use strict';

(function (e) {

    e.create = create;
    e.shasum = shasum;
    e.toXz = toXz;

}(module.exports));

////////

let execFileSync = require('child_process').execFileSync;
let debug = require('debug')('recompress');
let fs = require('fs');
let fsExtra = require('fs-extra');
let File = require('./file');
let Tar = require('./tar');
let Rar = require('./rar');
let Zip = require('./zip');
let Gzip = require('./gzip');

function create(file) {
    debug('create xz', file);
    execFileSync('/usr/local/bin/xz', ['-zk9', file]);

    return file + '.xz';
}

function decompress(file) {
    debug('decompress xz', file);
    execFileSync('/usr/local/bin/xz', ['-d', file]);

    return file.substr(0, file.length - 3);
}

function shasum(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';

    fsExtra.copySync(file, tmp);

    let uncompressed = decompress(tmp);

    let shasum = File.shasum(uncompressed);

    fs.unlinkSync(uncompressed);

    return shasum;
}

function repack(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';
    debug('copy xz', file, tmp);
    fsExtra.copySync(file, tmp);
    let uncompressed = decompress(tmp);
    let newCompressed = create(uncompressed);

    let shasumUn = File.shasum(uncompressed);
    let shasumN = shasum(newCompressed);
    let saved = 0;
    if(shasumN === shasumUn) {
        console.log('repack successful', file);
        saved = File.compare(file, newCompressed);
        fs.unlinkSync(file);
        fs.renameSync(newCompressed, file);
    } else {
        fs.unlinkSync(newCompressed);
    }
    fs.unlinkSync(uncompressed);
    return saved;
}

function toXz(file) {
    let dir;
    let tar;
    console.log('processing', file);
    if(file.endsWith('.rar')) {
        dir = Rar.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.zip')) {
        dir = Zip.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.gz')) {
        dir = Gzip.unpack(file);
        tar = file.substr(0, file.length - 3);
    }
    else if(file.endsWith('.tgz')) {
        dir = Gzip.unpack(file);
        if(!dir) {
            console.log('unprocessable file', file);
            return 0;
        }
        tar = file.substr(0, file.length - 4) + '.tar';
    }
    else if(file.endsWith('.xz')) {
        return repack(file);
    } else {
        console.log('unprocessable file', file);
        return 0;
    }

    let saved = 0;

    let xz = create(tar);

    let shasumTar = Tar.shasum(tar);
    let shasumXz = shasum(xz);

    debug('shasums:', shasumTar, shasumXz);
    if(shasumTar === shasumXz) {
        console.log('Transform successful', file, '->', xz);
        saved = File.compare(file, xz);
        debug('unlink original', file);
        fs.unlinkSync(file);
    } else {
        console.error('Transform failed for', file);
        debug('unlink xz', file);
        fs.unlinkSync(xz);
    }

    debug('cleanup tar and dir', tar, dir);
    fs.unlinkSync(tar);
    File.rmDir(dir);
    return saved;
}<commit_msg>Change log line<commit_after>'use strict';

(function (e) {

    e.create = create;
    e.shasum = shasum;
    e.toXz = toXz;

}(module.exports));

////////

let execFileSync = require('child_process').execFileSync;
let debug = require('debug')('recompress');
let fs = require('fs');
let fsExtra = require('fs-extra');
let File = require('./file');
let Tar = require('./tar');
let Rar = require('./rar');
let Zip = require('./zip');
let Gzip = require('./gzip');

function create(file) {
    debug('create xz', file);
    execFileSync('/usr/local/bin/xz', ['-zk9', file]);

    return file + '.xz';
}

function decompress(file) {
    debug('decompress xz', file);
    execFileSync('/usr/local/bin/xz', ['-d', file]);

    return file.substr(0, file.length - 3);
}

function shasum(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';

    fsExtra.copySync(file, tmp);

    let uncompressed = decompress(tmp);

    let shasum = File.shasum(uncompressed);

    fs.unlinkSync(uncompressed);

    return shasum;
}

function repack(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';
    debug('copy xz', file, tmp);
    fsExtra.copySync(file, tmp);
    let uncompressed = decompress(tmp);
    let newCompressed = create(uncompressed);

    let shasumUn = File.shasum(uncompressed);
    let shasumN = shasum(newCompressed);
    let saved = 0;
    if(shasumN === shasumUn) {
        console.log('repack successful', file);
        saved = File.compare(file, newCompressed);
        fs.unlinkSync(file);
        fs.renameSync(newCompressed, file);
    } else {
        fs.unlinkSync(newCompressed);
    }
    fs.unlinkSync(uncompressed);
    return saved;
}

function toXz(file) {
    let dir;
    let tar;
    console.log('processing', file);
    if(file.endsWith('.rar')) {
        dir = Rar.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.zip')) {
        dir = Zip.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.gz')) {
        dir = Gzip.unpack(file);
        tar = file.substr(0, file.length - 3);
    }
    else if(file.endsWith('.tgz')) {
        dir = Gzip.unpack(file);
        if(!dir) {
            console.log('unprocessable file - nodir', file);
            return 0;
        }
        tar = file.substr(0, file.length - 4) + '.tar';
    }
    else if(file.endsWith('.xz')) {
        return repack(file);
    } else {
        console.log('unprocessable file', file);
        return 0;
    }

    let saved = 0;

    let xz = create(tar);

    let shasumTar = Tar.shasum(tar);
    let shasumXz = shasum(xz);

    debug('shasums:', shasumTar, shasumXz);
    if(shasumTar === shasumXz) {
        console.log('Transform successful', file, '->', xz);
        saved = File.compare(file, xz);
        debug('unlink original', file);
        fs.unlinkSync(file);
    } else {
        console.error('Transform failed for', file);
        debug('unlink xz', file);
        fs.unlinkSync(xz);
    }

    debug('cleanup tar and dir', tar, dir);
    fs.unlinkSync(tar);
    File.rmDir(dir);
    return saved;
}<|endoftext|>


<commit_before>'use strict';

(function (e) {

    e.create = create;
    e.shasum = shasum;
    e.toXz = toXz;

}(module.exports));

////////

let execFileSync = require('child_process').execFileSync;
let debug = require('debug')('recompress');
let fs = require('fs');
let fsExtra = require('fs-extra');
let File = require('./file');
let Tar = require('./tar');
let Rar = require('./rar');
let Zip = require('./zip');
let Gzip = require('./gzip');

function create(file) {
    debug('create xz', file);
    execFileSync('/usr/local/bin/xz', ['-zk9', file]);

    return file + '.xz';
}

function decompress(file) {
    debug('decompress xz', file);
    execFileSync('/usr/local/bin/xz', ['-d', file]);

    return file.substr(0, file.length - 3);
}

function shasum(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';

    fsExtra.copySync(file, tmp);

    let uncompressed = decompress(tmp);

    let shasum = File.shasum(uncompressed);

    fs.unlinkSync(uncompressed);

    return shasum;
}

function repack(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';
    debug('copy xz', file, tmp);
    fsExtra.copySync(file, tmp);
    let uncompressed = decompress(tmp);
    let newCompressed = create(uncompressed);

    let shasumUn = File.shasum(uncompressed);
    let shasumN = shasum(newCompressed);
    let saved = 0;
    if(shasumN === shasumUn) {
        console.log('repack successful', file);
        saved = File.compare(file, newCompressed);
        fs.unlinkSync(file);
        fs.renameSync(newCompressed, file);
    } else {
        fs.unlinkSync(newCompressed);
    }
    fs.unlinkSync(uncompressed);
    return saved;
}

function toXz(file) {
    let dir;
    let tar;
    console.log('processing', file);
    if(file.endsWith('.rar')) {
        dir = Rar.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.zip')) {
        dir = Zip.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.gz')) {
        dir = Gzip.unpack(file);
        tar = file.substr(0, file.length - 3);
    }
    else if(file.endsWith('.tgz')) {
        dir = Gzip.unpack(file);
        if(!dir) {
            console.log('unprocessable file', file);
            return 0;
        }
        tar = file.substr(0, file.length - 4) + '.tar';
    }
    else if(file.endsWith('.xz')) {
        return repack(file);
    } else {
        console.log('unprocessable file', file);
        return 0;
    }

    let saved = 0;

    let xz = create(tar);

    let shasumTar = Tar.shasum(tar);
    let shasumXz = shasum(xz);

    debug('shasums:', shasumTar, shasumXz);
    if(shasumTar === shasumXz) {
        console.log('Transform successful', file, '->', xz);
        saved = File.compare(file, xz);
        debug('unlink original', file);
        fs.unlinkSync(file);
    } else {
        console.error('Transform failed for', file);
        debug('unlink xz', file);
        fs.unlinkSync(xz);
    }

    debug('cleanup tar and dir', tar, dir);
    fs.unlinkSync(tar);
    File.rmDir(dir);
    return saved;
}<commit_msg>Ignore .json.gz files atm<commit_after>'use strict';

(function (e) {

    e.create = create;
    e.shasum = shasum;
    e.toXz = toXz;

}(module.exports));

////////

let execFileSync = require('child_process').execFileSync;
let debug = require('debug')('recompress');
let fs = require('fs');
let fsExtra = require('fs-extra');
let File = require('./file');
let Tar = require('./tar');
let Rar = require('./rar');
let Zip = require('./zip');
let Gzip = require('./gzip');

function create(file) {
    debug('create xz', file);
    execFileSync('/usr/local/bin/xz', ['-zk9', file]);

    return file + '.xz';
}

function decompress(file) {
    debug('decompress xz', file);
    execFileSync('/usr/local/bin/xz', ['-d', file]);

    return file.substr(0, file.length - 3);
}

function shasum(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';

    fsExtra.copySync(file, tmp);

    let uncompressed = decompress(tmp);

    let shasum = File.shasum(uncompressed);

    fs.unlinkSync(uncompressed);

    return shasum;
}

function repack(file) {
    let tmp = '/tmp/' + Math.random().toString(36).substr(2) + '.xz';
    debug('copy xz', file, tmp);
    fsExtra.copySync(file, tmp);
    let uncompressed = decompress(tmp);
    let newCompressed = create(uncompressed);

    let shasumUn = File.shasum(uncompressed);
    let shasumN = shasum(newCompressed);
    let saved = 0;
    if(shasumN === shasumUn) {
        console.log('repack successful', file);
        saved = File.compare(file, newCompressed);
        fs.unlinkSync(file);
        fs.renameSync(newCompressed, file);
    } else {
        fs.unlinkSync(newCompressed);
    }
    fs.unlinkSync(uncompressed);
    return saved;
}

function toXz(file) {
    let dir;
    let tar;
    console.log('processing', file);
    if(file.endsWith('.rar')) {
        dir = Rar.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.zip')) {
        dir = Zip.unpack(file);
        tar = Tar.create(dir, file);
    }
    else if(file.endsWith('.gz')) {
        if(file.endsWith('.json.gz')) {
            console.log('unprocessable file', file);
            return 0;
        }
        dir = Gzip.unpack(file);
        tar = file.substr(0, file.length - 3);
    }
    else if(file.endsWith('.tgz')) {
        dir = Gzip.unpack(file);
        if(!dir) {
            console.log('unprocessable file', file);
            return 0;
        }
        tar = file.substr(0, file.length - 4) + '.tar';
    }
    else if(file.endsWith('.xz')) {
        return repack(file);
    } else {
        console.log('unprocessable file', file);
        return 0;
    }

    let saved = 0;

    let xz = create(tar);

    let shasumTar = Tar.shasum(tar);
    let shasumXz = shasum(xz);

    debug('shasums:', shasumTar, shasumXz);
    if(shasumTar === shasumXz) {
        console.log('Transform successful', file, '->', xz);
        saved = File.compare(file, xz);
        debug('unlink original', file);
        fs.unlinkSync(file);
    } else {
        console.error('Transform failed for', file);
        debug('unlink xz', file);
        fs.unlinkSync(xz);
    }

    debug('cleanup tar and dir', tar, dir);
    fs.unlinkSync(tar);
    File.rmDir(dir);
    return saved;
}<|endoftext|>


<commit_before>export default {
  haha: 'haha'
}
<commit_msg>- delete production config<commit_after><|endoftext|>


<commit_before>import React from 'react';

const Dropdown = (props) => {
    const {
        meta,
        refFn,
        children,
        source,
        valueField,
        textField,
        optionsLabel,
        ...sourceProps
    } = props;

    // this object will have all props for input html element
    let targetProps = Object.assign({}, sourceProps);
    if (typeof (sourceProps.className) === 'undefined') {
        // by default, add 'form-control' class to select tag
        targetProps.className = 'form-control';
    }

    // first get values from meta if it exists
    if (meta) {
        targetProps.name = meta.name;
        targetProps.id = meta.name;
        targetProps.value = meta.value;
    }
    // other props can overwrite meta values
    targetProps.name = sourceProps.name ? sourceProps.name : targetProps.name;
    targetProps.id = sourceProps.id ? sourceProps.id : targetProps.id;
    targetProps.value = sourceProps.value ? sourceProps.value : targetProps.value;

    if (children) {
        return (<select ref={refFn} {...targetProps}>{children}</select>);
    } else if(meta && meta.dropdownValues) {
        let options = [];
        meta.dropdownValues.forEach(item => {
            options.push(<option value={item.value} key={item.value}>{item.text}</option>);
        });
        return (<select ref={refFn} {...targetProps}>{options}</select>);
    } else if (source && valueField && textField) {
        let options = [];
        if (optionsLabel) {
            // WARNING: value of 'set-null' will be processed in base-component.js
            options.push(<option value='set-null' key={-99999}>{optionsLabel}</option>);
        }
        source.forEach(item => {
            options.push(<option value={item[valueField]} key={item[valueField]}>{item[textField]}</option>);
        });

        return (<select ref={refFn} {...targetProps}>{options}</select>);
    }
    else
        return null;
}

Dropdown.propTypes = {
    meta: React.PropTypes.object,
    refFn: React.PropTypes.func,
    source: React.PropTypes.array,
    valueField: React.PropTypes.string,
    textField: React.PropTypes.string,
    optionsLabel: React.PropTypes.string,
};

export default Dropdown;<commit_msg>Fixed bug in Dropdown component<commit_after>import React from 'react';

const Dropdown = (props) => {
    const {
        meta,
        refFn,
        children,
        source,
        valueField,
        textField,
        optionsLabel,
        ...sourceProps
    } = props;

    // this object will have all props for input html element
    let targetProps = Object.assign({}, sourceProps);
    if (typeof (sourceProps.className) === 'undefined') {
        // by default, add 'form-control' class to select tag
        targetProps.className = 'form-control';
    }

    // first get values from meta if it exists
    if (meta) {
        targetProps.name = meta.name;
        targetProps.id = meta.name;
        targetProps.value = meta.value;
    }
    // other props can overwrite meta values
    targetProps.name = sourceProps.name ? sourceProps.name : targetProps.name;
    targetProps.id = sourceProps.id ? sourceProps.id : targetProps.id;
    targetProps.value = sourceProps.value ? sourceProps.value : targetProps.value;

    // value cannot be null
    targetProps.value = targetProps.value ? targetProps.value : '';

    if (children) {
        return (<select ref={refFn} {...targetProps}>{children}</select>);
    } else if(meta && meta.dropdownValues) {
        let options = [];
        meta.dropdownValues.forEach(item => {
            options.push(<option value={item.value} key={item.value}>{item.text}</option>);
        });
        return (<select ref={refFn} {...targetProps}>{options}</select>);
    } else if (source && valueField && textField) {
        let options = [];
        if (optionsLabel) {
            // WARNING: value of 'set-null' will be processed in base-component.js
            options.push(<option value='set-null' key={-99999}>{optionsLabel}</option>);
        }
        source.forEach(item => {
            options.push(<option value={item[valueField]} key={item[valueField]}>{item[textField]}</option>);
        });

        return (<select ref={refFn} {...targetProps}>{options}</select>);
    }
    else
        return null;
}

Dropdown.propTypes = {
    meta: React.PropTypes.object,
    refFn: React.PropTypes.func,
    source: React.PropTypes.array,
    valueField: React.PropTypes.string,
    textField: React.PropTypes.string,
    optionsLabel: React.PropTypes.string,
};

export default Dropdown;<|endoftext|>


<commit_before>; // jshint ignore:line
(function (root, factory, undefined) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory();
  } else {
    // root is window
    root.CookiesEuBanner = factory();
  }
}(window, function () {
  'use strict';

  var CookiesEuBanner,
    document = window.document;

  CookiesEuBanner = function (launchFunction, waitAccept, useLocalStorage, undefined) {
    if (!(this instanceof CookiesEuBanner)) {
      return new CookiesEuBanner(launchFunction);
    }

    this.cookieTimeout = 31104000000; // 12 months in milliseconds
    this.bots = /bot|crawler|spider|crawling/i;
    this.cookieName = 'hasConsent';
    this.trackingCookiesNames = ['__utma', '__utmb', '__utmc', '__utmt', '__utmv', '__utmz', '_ga', '_gat', '_gid'];
    this.launchFunction = launchFunction;
    this.waitAccept = waitAccept || false;
    this.useLocalStorage = useLocalStorage || false;
    this.init();
  };

  CookiesEuBanner.prototype = {
    init: function () {
      // Detect if the visitor is a bot or not
      // Prevent for search engine take the cookie alert message as main content of the page
      var isBot = this.bots.test(navigator.userAgent);

      // Check if DoNotTrack is activated
      var dnt = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
      var isToTrack = (dnt !== null && dnt !== undefined) ? (dnt && dnt !== 'yes' && dnt !== 1 && dnt !== '1') : true;

      // Do nothing if it is a bot
      // If DoNotTrack is activated, do nothing too
      if (isBot || !isToTrack || this.hasConsent() === false) {
        this.removeBanner(0);
        return false;
      }

      // User has already consent to use cookies to tracking
      if (this.hasConsent() === true) {
        // Launch user custom function
        this.launchFunction();
        return true;
      }

      // If it's not a bot, no DoNotTrack and not already accept, so show banner
      this.showBanner();

      if (!this.waitAccept) {
        // Accept cookies by default for the next page
        this.setConsent(true);
      }
    },

    /*
     * Show banner at the top of the page
     */
    showBanner: function () {
      var _this = this,
        getElementById = document.getElementById.bind(document),
        banner = getElementById('cookies-eu-banner'),
        rejectButton = getElementById('cookies-eu-reject'),
        acceptButton = getElementById('cookies-eu-accept'),
        moreLink = getElementById('cookies-eu-more'),
        waitRemove = (banner.dataset.waitRemove === undefined) ? 0 : parseInt(banner.dataset.waitRemove),
        // Variables for minification optimization
        addClickListener = this.addClickListener,
        removeBanner = _this.removeBanner.bind(_this, waitRemove);

      banner.style.display = 'block';

      if (moreLink) {
        addClickListener(moreLink, function () {
          _this.deleteCookie(_this.cookieName);
        });
      }

      if (acceptButton) {
        addClickListener(acceptButton, function () {
          removeBanner();
          _this.setConsent(true);
          _this.launchFunction();
        });
      }

      if (rejectButton) {
        addClickListener(rejectButton, function () {
          removeBanner();
          _this.setConsent(false);

          // Delete existing tracking cookies
          _this.trackingCookiesNames.map(_this.deleteCookie);
        });
      }
    },

    /*
     * Set consent cookie or localStorage
     */
    setConsent: function (consent) {
      if (this.useLocalStorage) {
        return localStorage.setItem(this.cookieName, consent);
      }

      this.setCookie(this.cookieName, consent);
    },

    /*
     * Check if user already consent
     */
    hasConsent: function () {
      var cookieName = this.cookieName;
      var isCookieSetTo = function (value) {
        return document.cookie.indexOf(cookieName + '=' + value) > -1 || localStorage.getItem(cookieName) === value;
      };

      if (isCookieSetTo('true')) {
        return true;
      } else if (isCookieSetTo('false')) {
        return false;
      }

      return null;
    },

    /*
     * Create/update cookie
     */
    setCookie: function (name, value) {
      var date = new Date();
      date.setTime(date.getTime() + this.cookieTimeout);

      document.cookie = name + '=' + value + ';expires=' + date.toGMTString() + ';path=/';
    },

    /*
     * Delete cookie by changing expire
     */
    deleteCookie: function (name) {
      var hostname = document.location.hostname.replace(/^www\./, ''),
          commonSuffix = '; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';

      document.cookie = name + '=; domain=.' + hostname + commonSuffix;
      document.cookie = name + '=' + commonSuffix;
    },

    addClickListener: function (DOMElement, callback) {
      if (DOMElement.attachEvent) { // For IE 8 and earlier versions
        return DOMElement.attachEvent('onclick', callback);
      }

      // For all major browsers, except IE 8 and earlier
      DOMElement.addEventListener('click', callback);
    },

    /*
     * Delays removal of banner allowing developers
     * to specify their own transition effects
     */
    removeBanner: function (wait) {
      var banner = document.getElementById('cookies-eu-banner');
      banner.classList.add('cookies-eu-banner--before-remove');
      setTimeout (function() {
        if (banner && banner.parentNode) {
          banner.parentNode.removeChild(banner);
        }
      }, wait);
    }
  };

  return CookiesEuBanner;
}));
<commit_msg>fix SameSite attribute to ensure the cookie is not rejected by more secure browsers #60<commit_after>; // jshint ignore:line
(function (root, factory, undefined) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory();
  } else {
    // root is window
    root.CookiesEuBanner = factory();
  }
}(window, function () {
  'use strict';

  var CookiesEuBanner,
    document = window.document;

  CookiesEuBanner = function (launchFunction, waitAccept, useLocalStorage, undefined) {
    if (!(this instanceof CookiesEuBanner)) {
      return new CookiesEuBanner(launchFunction);
    }

    this.cookieTimeout = 31104000000; // 12 months in milliseconds
    this.bots = /bot|crawler|spider|crawling/i;
    this.cookieName = 'hasConsent';
    this.trackingCookiesNames = ['__utma', '__utmb', '__utmc', '__utmt', '__utmv', '__utmz', '_ga', '_gat', '_gid'];
    this.launchFunction = launchFunction;
    this.waitAccept = waitAccept || false;
    this.useLocalStorage = useLocalStorage || false;
    this.init();
  };

  CookiesEuBanner.prototype = {
    init: function () {
      // Detect if the visitor is a bot or not
      // Prevent for search engine take the cookie alert message as main content of the page
      var isBot = this.bots.test(navigator.userAgent);

      // Check if DoNotTrack is activated
      var dnt = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
      var isToTrack = (dnt !== null && dnt !== undefined) ? (dnt && dnt !== 'yes' && dnt !== 1 && dnt !== '1') : true;

      // Do nothing if it is a bot
      // If DoNotTrack is activated, do nothing too
      if (isBot || !isToTrack || this.hasConsent() === false) {
        this.removeBanner(0);
        return false;
      }

      // User has already consent to use cookies to tracking
      if (this.hasConsent() === true) {
        // Launch user custom function
        this.launchFunction();
        return true;
      }

      // If it's not a bot, no DoNotTrack and not already accept, so show banner
      this.showBanner();

      if (!this.waitAccept) {
        // Accept cookies by default for the next page
        this.setConsent(true);
      }
    },

    /*
     * Show banner at the top of the page
     */
    showBanner: function () {
      var _this = this,
        getElementById = document.getElementById.bind(document),
        banner = getElementById('cookies-eu-banner'),
        rejectButton = getElementById('cookies-eu-reject'),
        acceptButton = getElementById('cookies-eu-accept'),
        moreLink = getElementById('cookies-eu-more'),
        waitRemove = (banner.dataset.waitRemove === undefined) ? 0 : parseInt(banner.dataset.waitRemove),
        // Variables for minification optimization
        addClickListener = this.addClickListener,
        removeBanner = _this.removeBanner.bind(_this, waitRemove);

      banner.style.display = 'block';

      if (moreLink) {
        addClickListener(moreLink, function () {
          _this.deleteCookie(_this.cookieName);
        });
      }

      if (acceptButton) {
        addClickListener(acceptButton, function () {
          removeBanner();
          _this.setConsent(true);
          _this.launchFunction();
        });
      }

      if (rejectButton) {
        addClickListener(rejectButton, function () {
          removeBanner();
          _this.setConsent(false);

          // Delete existing tracking cookies
          _this.trackingCookiesNames.map(_this.deleteCookie);
        });
      }
    },

    /*
     * Set consent cookie or localStorage
     */
    setConsent: function (consent) {
      if (this.useLocalStorage) {
        return localStorage.setItem(this.cookieName, consent);
      }

      this.setCookie(this.cookieName, consent);
    },

    /*
     * Check if user already consent
     */
    hasConsent: function () {
      var cookieName = this.cookieName;
      var isCookieSetTo = function (value) {
        return document.cookie.indexOf(cookieName + '=' + value) > -1 || localStorage.getItem(cookieName) === value;
      };

      if (isCookieSetTo('true')) {
        return true;
      } else if (isCookieSetTo('false')) {
        return false;
      }

      return null;
    },

    /*
     * Create/update cookie
     */
    setCookie: function (name, value) {
      var date = new Date();
      date.setTime(date.getTime() + this.cookieTimeout);

      document.cookie = name + '=' + value + ';expires=' + date.toGMTString() + ';path=/' + ';secure;SameSite=Lax';
    },

    /*
     * Delete cookie by changing expire
     */
    deleteCookie: function (name) {
      var hostname = document.location.hostname.replace(/^www\./, ''),
          commonSuffix = '; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';

      document.cookie = name + '=; domain=.' + hostname + commonSuffix;
      document.cookie = name + '=' + commonSuffix;
    },

    addClickListener: function (DOMElement, callback) {
      if (DOMElement.attachEvent) { // For IE 8 and earlier versions
        return DOMElement.attachEvent('onclick', callback);
      }

      // For all major browsers, except IE 8 and earlier
      DOMElement.addEventListener('click', callback);
    },

    /*
     * Delays removal of banner allowing developers
     * to specify their own transition effects
     */
    removeBanner: function (wait) {
      var banner = document.getElementById('cookies-eu-banner');
      banner.classList.add('cookies-eu-banner--before-remove');
      setTimeout (function() {
        if (banner && banner.parentNode) {
          banner.parentNode.removeChild(banner);
        }
      }, wait);
    }
  };

  return CookiesEuBanner;
}));
<|endoftext|>


<commit_before>function setup(options, imports, register) {
    // Import
    var server = imports.server.http;
    var port = imports.server.port;
    var watch = imports.watch;
    var workspace = imports.workspace;
    var logger = imports.logger.namespace("codebox");

    // Start server
    server.listen(port);

    server.on('listening', function() {
        logger.log("Server is listening on ", port);
        watch.init(workspace.root)
        .then(function() {
            logger.log("Started Watch");
        })
        .fail(function(err) {
            logger.error("Failed to start Watch because of:");
            logger.exception(err, false);
        }).fin(function() {
            // Register
            register(null, {});
        });
    })
}

// Exports
module.exports = setup;
<commit_msg>Change init of watch and server<commit_after>function setup(options, imports, register) {
    // Import
    var server = imports.server.http;
    var port = imports.server.port;
    var watch = imports.watch;
    var workspace = imports.workspace;
    var logger = imports.logger.namespace("codebox");

    // Start server
    server.listen(port);

    server.on('listening', function() {
        logger.log("Server is listening on ", port);
    });

    watch.init(workspace.root)
    .then(function() {
        logger.log("Started Watch");
    })
    .fail(function(err) {
        logger.error("Failed to start Watch because of:");
        logger.exception(err, false);
    }).fin(function() {
        // Register
        register(null, {});
    });
}

// Exports
module.exports = setup;
<|endoftext|>


<commit_before>'use strict';

const request = require('requestretry').defaults({timeout: 10000, maxAttempts: 3, retryDelay: 500})
const parser = require('cheerio')
const utils = require('./utils')
const sprintf = require('sprintf')
const moment = require('moment-timezone')
const zone = "Europe/Madrid" // +1h

const URL = 'https://www.correosexpress.com/web/correosexpress/envios4?param=%s;%s'

const correos = {}

/**
 * Get correos info
 * Scraps the Correos Express website
 * Async
 *
 * Design changes may break this code!!
 * @param id
 * @param postalcode
 * @param cb(Error, CorreosInfo)
 */
correos.getInfo = function (id, cb) {
    request(sprintf(URL, utils.getPostalCode(id), id), function (error, response, body) {
        if (error || response.statusCode != 200) {
            cb(utils.getError('DOWN'))
            return
        }

        // Not found
        if (body.indexOf('portlet-msg-error') != -1) {
            cb(utils.getError('NO_DATA'))
            return
        }

        let entity = null
        try {
            entity = createCorreosEntity(body, id)
            entity.retries = response.attempts
        } catch (error) {
            console.log(error);
            return cb(utils.getError('PARSER'))
        }

        cb(null, entity)
    })
}

/**
 * Create correos entity from html
 * @param html
 */
function createCorreosEntity(html, id) {
    let $ = parser.load(html)

    let states = []
    const fields = ['date', 'info', 'department']
    $('.results-row').each(function (i, elem) {
        if (i == 0) return

        let state = {}
        $(this).children().each(function (s, e) {
            let text = $(this).text().trim()

            if(s == 0)
                text = moment.tz(text, "DD/MM/YY HH:mm", zone).format()

            state[fields[s]] = text
        })

        states.push(state)
    })

    return new CorreosInfo({
        'nenvio': $('#nenvio').val(),
        'estado': $('#estado').val(),
        'fecha': $('#fecha').val(),
        'fechaEstado': $('#fechaEstado').val(),
        'sendername': $('#sendername').val(),
        'sendercity': $('#sendercity').val(),
        'senderaddress': $('#senderaddress').val(),
        'receivername': $('#receivername').val(),
        'receivercity': $('#receivercity').val(),
        'receiveraddress': $('#receiveraddress').val(),
        'weight': $('#weight').val(),
        'parcels': $('#parcels').val(),
        'ref': $('#reference').val(),
        'observations': $('#observations').val(),
        'states': states,
        'id': id
    })
}

/*
 |--------------------------------------------------------------------------
 | Entity
 |--------------------------------------------------------------------------
 */
function CorreosInfo(obj) {
    // Sent details
    this.id = obj.nenvio
    this.state = obj.estado
    this.received = moment.tz(obj.fecha, "DD/MM/YY", zone).format()
    this.lastUpdate = moment.tz(obj.fechaEstado, "DD/MM/YY HH:mm", zone).format()

    // Sender Details
    this.sender = {
        name: obj.sendername.replace('¿', ''),
        city: obj.sendercity,
        address: obj.senderaddress
    }

    // Receiver Details
    this.receiver = {
        name: obj.receivername,
        city: obj.receivercity,
        address: obj.receiveraddress
    }

    // Product Details
    this.product = {
        weight: obj.weight,
        parcels: obj.parcels,
        ref: obj.ref,
        observations: obj.observations
    }

    //States
    this.states = obj.states.reverse()

    this.trackerWebsite = sprintf(URL, obj.postalcode, obj.id)
}

module.exports = correos<commit_msg>Fixed correos old link<commit_after>'use strict';

const request = require('requestretry').defaults({timeout: 10000, maxAttempts: 3, retryDelay: 500})
const parser = require('cheerio')
const utils = require('./utils')
const sprintf = require('sprintf')
const moment = require('moment-timezone')
const zone = "Europe/Madrid" // +1h

const URL = 'https://www.correosexpress.com/web/correosexpress/envios4?param=%s;%s'

const correos = {}

/**
 * Get correos info
 * Scraps the Correos Express website
 * Async
 *
 * Design changes may break this code!!
 * @param id
 * @param postalcode
 * @param cb(Error, CorreosInfo)
 */
correos.getInfo = function (id, cb) {
    request(sprintf(URL, utils.getPostalCode(id), id), function (error, response, body) {
        if (error || response.statusCode != 200) {
            cb(utils.getError('DOWN'))
            return
        }

        // Not found
        if (body.indexOf('portlet-msg-error') != -1) {
            cb(utils.getError('NO_DATA'))
            return
        }

        let entity = null
        try {
            entity = createCorreosEntity(body, id)
            entity.retries = response.attempts
        } catch (error) {
            console.log(error);
            return cb(utils.getError('PARSER'))
        }

        cb(null, entity)
    })
}

/**
 * Create correos entity from html
 * @param html
 */
function createCorreosEntity(html, id) {
    let $ = parser.load(html)

    let states = []
    const fields = ['date', 'info', 'department']
    $('.results-row').each(function (i, elem) {
        if (i == 0) return

        let state = {}
        $(this).children().each(function (s, e) {
            let text = $(this).text().trim()

            if(s == 0)
                text = moment.tz(text, "DD/MM/YY HH:mm", zone).format()

            state[fields[s]] = text
        })

        states.push(state)
    })

    return new CorreosInfo({
        'nenvio': $('#nenvio').val(),
        'estado': $('#estado').val(),
        'fecha': $('#fecha').val(),
        'fechaEstado': $('#fechaEstado').val(),
        'sendername': $('#sendername').val(),
        'sendercity': $('#sendercity').val(),
        'senderaddress': $('#senderaddress').val(),
        'receivername': $('#receivername').val(),
        'receivercity': $('#receivercity').val(),
        'receiveraddress': $('#receiveraddress').val(),
        'weight': $('#weight').val(),
        'parcels': $('#parcels').val(),
        'ref': $('#reference').val(),
        'observations': $('#observations').val(),
        'states': states,
        'id': id
    })
}

/*
 |--------------------------------------------------------------------------
 | Entity
 |--------------------------------------------------------------------------
 */
function CorreosInfo(obj) {
    // Sent details
    this.id = obj.nenvio
    this.state = obj.estado
    this.received = moment.tz(obj.fecha, "DD/MM/YY", zone).format()
    this.lastUpdate = moment.tz(obj.fechaEstado, "DD/MM/YY HH:mm", zone).format()

    // Sender Details
    this.sender = {
        name: obj.sendername.replace('¿', ''),
        city: obj.sendercity,
        address: obj.senderaddress
    }

    // Receiver Details
    this.receiver = {
        name: obj.receivername,
        city: obj.receivercity,
        address: obj.receiveraddress
    }

    // Product Details
    this.product = {
        weight: obj.weight,
        parcels: obj.parcels,
        ref: obj.ref,
        observations: obj.observations
    }

    //States
    this.states = obj.states.reverse()

    this.trackerWebsite = sprintf(URL, utils.getPostalCode(obj.id), obj.id)
}

module.exports = correos<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
var filters = require('./filters'),
    assert = require('../utilities/assert').argument,
    queries = require('../query');

module.exports = function (provider, table, context) {
    var tableAccess = provider(table);

    context = context || {};

    return {
        read: function (query) {
            return tableAccess.read(applyFilters(query, 'read'));
        },
        update: function (item, query) {
            assert(item, 'An item to update was not provided');
            return tableAccess.update(applyTransforms(item, 'update'), applyFilters(query, 'update'));
        },
        insert: function (item) {
            assert(item, 'An item to insert was not provided');
            return tableAccess.insert(applyTransforms(item, 'create'));
        },
        delete: function (query, version) {
            assert(query, 'The delete query was not provided');
            return tableAccess.delete(applyFilters(query, 'delete'), version);
        },
        undelete: function (query, version) {
            assert(query, 'The undelete query was not provided');
            return tableAccess.undelete(applyFilters(query, 'undelete'), version);
        },
        truncate: tableAccess.truncate,
        initialize: tableAccess.initialize,
        schema: tableAccess.schema
    };

    function applyFilters(query, operation) {
        var context = createContext(operation);

        if(table.perUser) query = filters.apply('perUser', query, context);
        if(table.recordsExpire) query = filters.apply('recordsExpire', query, context);
        if(table.webhook) query = filters.apply('webhook', query, context);

        if(!table.filters)
            return query;

        return table.filters.reduce(function (query, filter) {
            // this is a bit of trickery to allow filters to either
            // modify the existing query or return a different query
            // see the test in data/integration/filters for an example
            return filter(query, context) || query;
        }, query || queries.create(table.name));
    }

    function applyTransforms(item, operation) {
        var context = createContext(operation);

        if(table.perUser) item = filters.applyTransform('perUser', item, context);
        if(table.webhook) query = filters.apply('webhook', item, context);

        if(!table.transforms)
            return item;

        return table.transforms.reduce(function (item, transform) {
            return transform(item, context) || item;
        }, item);
    }

    function createContext(operation) {
        // shallow clone the context operation and assign the correct operation
        var result = Object.keys(context).reduce(function (target, key) {
            target[key] = context[key];
            return target;
        }, {});
        result.operation = operation;
        return result;
    }
};<commit_msg>Fix transform<commit_after>// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
var filters = require('./filters'),
    assert = require('../utilities/assert').argument,
    queries = require('../query');

module.exports = function (provider, table, context) {
    var tableAccess = provider(table);

    context = context || {};

    return {
        read: function (query) {
            return tableAccess.read(applyFilters(query, 'read'));
        },
        update: function (item, query) {
            assert(item, 'An item to update was not provided');
            return tableAccess.update(applyTransforms(item, 'update'), applyFilters(query, 'update'));
        },
        insert: function (item) {
            assert(item, 'An item to insert was not provided');
            return tableAccess.insert(applyTransforms(item, 'create'));
        },
        delete: function (query, version) {
            assert(query, 'The delete query was not provided');
            return tableAccess.delete(applyFilters(query, 'delete'), version);
        },
        undelete: function (query, version) {
            assert(query, 'The undelete query was not provided');
            return tableAccess.undelete(applyFilters(query, 'undelete'), version);
        },
        truncate: tableAccess.truncate,
        initialize: tableAccess.initialize,
        schema: tableAccess.schema
    };

    function applyFilters(query, operation) {
        var context = createContext(operation);

        if(table.perUser) query = filters.apply('perUser', query, context);
        if(table.recordsExpire) query = filters.apply('recordsExpire', query, context);
        if(table.webhook) query = filters.apply('webhook', query, context);

        if(!table.filters)
            return query;

        return table.filters.reduce(function (query, filter) {
            // this is a bit of trickery to allow filters to either
            // modify the existing query or return a different query
            // see the test in data/integration/filters for an example
            return filter(query, context) || query;
        }, query || queries.create(table.name));
    }

    function applyTransforms(item, operation) {
        var context = createContext(operation);

        if(table.perUser) item = filters.applyTransform('perUser', item, context);
        if(table.webhook) query = filters.applyTransform('webhook', item, context);

        if(!table.transforms)
            return item;

        return table.transforms.reduce(function (item, transform) {
            return transform(item, context) || item;
        }, item);
    }

    function createContext(operation) {
        // shallow clone the context operation and assign the correct operation
        var result = Object.keys(context).reduce(function (target, key) {
            target[key] = context[key];
            return target;
        }, {});
        result.operation = operation;
        return result;
    }
};<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Document = this.Document = Base.extend({
	beans: true,

	initialize: function(canvas) {
		if (canvas && canvas instanceof HTMLCanvasElement) {
			this.canvas = canvas;
			if (canvas.attributes.resize) {
				// If the canvas has a fullscreen attribute,
				// resize the canvas to fill the window and resize it again
				// whenever the user resizes the window.
				// TODO: set the following styles on the body tag:
				// body {
				//	background: black;
				//	margin: 0;
				//	overflow: hidden;
				// }
				this._size = DomElement.getWindowSize()
						.subtract(DomElement.getOffset(this.canvas));
				this.canvas.width = this._size.width;
				this.canvas.height = this._size.height;
				var that = this;
				DomEvent.add(window, {
					resize: function(event) {
						that.setSize(DomElement.getWindowSize()
								.subtract(DomElement.getOffset(that.canvas)));
						that.redraw();
					}
				});
			} else {
				this._size = Size.create(canvas.offsetWidth,
						canvas.offsetHeight);
			}
		} else {
			this._size = Size.read(arguments) || new Size(1024, 768);
			this.canvas = CanvasProvider.getCanvas(this._size);
		}
		// TODO: Currently we don't do anything with Document#bounds.
		// What does it mean to change the bounds of the document? (JP)
		this.bounds = Rectangle.create(0, 0, this._size.width,
				this._size.height);
		this.context = this.canvas.getContext('2d');
		// Push it onto paper.documents and adjust index in one:
		Base.splice(paper.documents, [this]);
		this.activate();
		this.layers = [];
		this.activeLayer = new Layer();
		this.setCurrentStyle({ strokeColor: 'black' });
		this.symbols = [];
		this.activeView = new DocumentView(this);
		this.views = [this.activeView];
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// TODO: Test this on IE:
		if (this.canvas.attributes.stats) {
			this.stats = new Stats();
			// Align top-left to the canvas
			var element = this.stats.domElement,
				style = element.style,
				offset = DomElement.getOffset(this.canvas);
			style.position = 'absolute';
			style.left = offset.x + 'px';
			style.top = offset.y + 'px';
			document.body.appendChild(element);
		}
	},

	getSize: function() {
		return this._size;
	},

	setSize: function(size) {
		size = Size.read(arguments);
		if (this.canvas) {
			this.canvas.width = size.width;
			this.canvas.height = size.height;
		}
		this._size = size;
		this.bounds.setSize(size);
	},

	getCurrentStyle: function() {
		return this._currentStyle;
	},

	setCurrentStyle: function(style) {
		this._currentStyle = PathStyle.create(null, style);
	},

	activate: function() {
		// TODO: Remove indexOf()
		var index = paper.documents.indexOf(this);
		if (index != -1) {
			paper.document = this;
			return true;
		}
		return false;
	},

	getSelectedItems: function() {
		// TODO: return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: the order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: implement setSelectedItems?

	_selectItem: function(item, select) {
		if (select) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the document.
	 */
	selectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the document.
	 */
	deselectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	draw: function() {
		if (this.canvas) {
			if (this.stats)
				this.stats.update();
			var ctx = this.context;
			ctx.save();

			// TODO: Remove dirty rectangle test code once it's actually
			// implemented.
			var testDirtyRects = false;
			if (testDirtyRects) {
				var left = this.size.width / 8,
					top = this.size.height / 8;

				function clear(rect) {
					ctx.clearRect(rect.x, rect.y, rect.width, rect.height);

					if (true) {
						ctx.moveTo(rect.x, rect.y);
						ctx.lineTo(rect.x + rect.width, rect.y);
						ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
						ctx.lineTo(rect.x, rect.y + rect.height);
					}
				}

				ctx.beginPath();

				clear(Rectangle.create(left, top, 2 * left, 2 * top));
				clear(Rectangle.create(3 * left, 3 * top, 2 * left, 2 * top));

//				clear(Rectangle.create(left, top, 4 * left, 4 * top));

				ctx.closePath();
				ctx.clip();
			} else {
				// Initial tests conclude that clearing the canvas using clearRect
				// is always faster than setting canvas.width = canvas.width
				// http://jsperf.com/clearrect-vs-setting-width/7
				ctx.clearRect(0, 0, this.size.width + 1, this.size.height + 1);
			}

			var param = { offset: new Point(0, 0) };
			for (var i = 0, l = this.layers.length; i < l; i++)
				Item.draw(this.layers[i], ctx, param);
			ctx.restore();

			// Draw the selection of the selected items in the document:
			if (this._selectedItemCount > 0) {
				ctx.save();
				ctx.strokeWidth = 1;
				// TODO: use Layer#color
				ctx.strokeStyle = ctx.fillStyle = '#009dec';
				param = { selection: true };
				Base.each(this._selectedItems, function(item) {
					item.draw(ctx, param);
				});
				ctx.restore();
			}
		}
	},

	redraw: function() {
		this.draw();
	}
});
<commit_msg>Undo last commit.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Document = this.Document = Base.extend({
	beans: true,

	initialize: function(canvas) {
		if (canvas && canvas instanceof HTMLCanvasElement) {
			this.canvas = canvas;
			if (canvas.attributes.resize) {
				// If the canvas has a fullscreen attribute,
				// resize the canvas to fill the window and resize it again
				// whenever the user resizes the window.
				// TODO: set the following styles on the body tag:
				// body {
				//	background: black;
				//	margin: 0;
				//	overflow: hidden;
				// }
				this._size = DomElement.getWindowSize()
						.subtract(DomElement.getOffset(this.canvas));
				this.canvas.width = this._size.width;
				this.canvas.height = this._size.height;
				var that = this;
				DomEvent.add(window, {
					resize: function(event) {
						that.setSize(DomElement.getWindowSize()
								.subtract(DomElement.getOffset(that.canvas)));
						that.redraw();
					}
				});
			} else {
				this._size = Size.create(canvas.offsetWidth,
						canvas.offsetHeight);
			}
		} else {
			this._size = Size.read(arguments) || new Size(1024, 768);
			this.canvas = CanvasProvider.getCanvas(this._size);
		}
		// TODO: Currently we don't do anything with Document#bounds.
		// What does it mean to change the bounds of the document? (JP)
		this.bounds = Rectangle.create(0, 0, this._size.width,
				this._size.height);
		this.context = this.canvas.getContext('2d');
		// Push it onto paper.documents and adjust index in one:
		Base.splice(paper.documents, [this]);
		this.activate();
		this.layers = [];
		this.activeLayer = new Layer();
		this.setCurrentStyle(null);
		this.symbols = [];
		this.activeView = new DocumentView(this);
		this.views = [this.activeView];
		this._selectedItems = {};
		this._selectedItemCount = 0;
		// TODO: Test this on IE:
		if (this.canvas.attributes.stats) {
			this.stats = new Stats();
			// Align top-left to the canvas
			var element = this.stats.domElement,
				style = element.style,
				offset = DomElement.getOffset(this.canvas);
			style.position = 'absolute';
			style.left = offset.x + 'px';
			style.top = offset.y + 'px';
			document.body.appendChild(element);
		}
	},

	getSize: function() {
		return this._size;
	},

	setSize: function(size) {
		size = Size.read(arguments);
		if (this.canvas) {
			this.canvas.width = size.width;
			this.canvas.height = size.height;
		}
		this._size = size;
		this.bounds.setSize(size);
	},

	getCurrentStyle: function() {
		return this._currentStyle;
	},

	setCurrentStyle: function(style) {
		this._currentStyle = PathStyle.create(null, style);
	},

	activate: function() {
		// TODO: Remove indexOf()
		var index = paper.documents.indexOf(this);
		if (index != -1) {
			paper.document = this;
			return true;
		}
		return false;
	},

	getSelectedItems: function() {
		// TODO: return groups if their children are all selected,
		// and filter out their children from the list.
		// TODO: the order of these items should be that of their
		// drawing order.
		var items = [];
		Base.each(this._selectedItems, function(item) {
			items.push(item);
		});
		return items;
	},

	// TODO: implement setSelectedItems?

	_selectItem: function(item, select) {
		if (select) {
			this._selectedItemCount++;
			this._selectedItems[item.getId()] = item;
		} else {
			this._selectedItemCount--;
			delete this._selectedItems[item.getId()];
		}
	},

	/**
	 * Selects all items in the document.
	 */
	selectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i = 0, l = this.layers.length; i < l; i++)
			this.layers[i].setSelected(true);
	},

	/**
	 * Deselects all selected items in the document.
	 */
	deselectAll: function() {
		// TODO: is using for var i in good practice?
		// or should we use Base.each? (JP)
		for (var i in this._selectedItems)
			this._selectedItems[i].setSelected(false);
	},

	draw: function() {
		if (this.canvas) {
			if (this.stats)
				this.stats.update();
			var ctx = this.context;
			ctx.save();

			// TODO: Remove dirty rectangle test code once it's actually
			// implemented.
			var testDirtyRects = false;
			if (testDirtyRects) {
				var left = this.size.width / 8,
					top = this.size.height / 8;

				function clear(rect) {
					ctx.clearRect(rect.x, rect.y, rect.width, rect.height);

					if (true) {
						ctx.moveTo(rect.x, rect.y);
						ctx.lineTo(rect.x + rect.width, rect.y);
						ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
						ctx.lineTo(rect.x, rect.y + rect.height);
					}
				}

				ctx.beginPath();

				clear(Rectangle.create(left, top, 2 * left, 2 * top));
				clear(Rectangle.create(3 * left, 3 * top, 2 * left, 2 * top));

//				clear(Rectangle.create(left, top, 4 * left, 4 * top));

				ctx.closePath();
				ctx.clip();
			} else {
				// Initial tests conclude that clearing the canvas using clearRect
				// is always faster than setting canvas.width = canvas.width
				// http://jsperf.com/clearrect-vs-setting-width/7
				ctx.clearRect(0, 0, this.size.width + 1, this.size.height + 1);
			}

			var param = { offset: new Point(0, 0) };
			for (var i = 0, l = this.layers.length; i < l; i++)
				Item.draw(this.layers[i], ctx, param);
			ctx.restore();

			// Draw the selection of the selected items in the document:
			if (this._selectedItemCount > 0) {
				ctx.save();
				ctx.strokeWidth = 1;
				// TODO: use Layer#color
				ctx.strokeStyle = ctx.fillStyle = '#009dec';
				param = { selection: true };
				Base.each(this._selectedItems, function(item) {
					item.draw(ctx, param);
				});
				ctx.restore();
			}
		}
	},

	redraw: function() {
		this.draw();
	}
});
<|endoftext|>


<commit_before>import Entity from "./Entity"
import Engine from "../Engine"
import Mesh from "../mesh/Mesh"
import Resources from "../resources/Resources"
import Material from "../resources/Material"
import Stage from "../renderer/Stage"
import DrawCommand from "../renderer/DrawCommand"

class Renderable extends Entity
{
	constructor(mesh) {
		super()
		if(!mesh) {
			mesh = new Mesh(null, null)
		}
		this.needUpdateMesh = true
		this.hidden = false
		this.drawCommand = new DrawCommand(this._transform, mesh, null, null)
	}

	draw() {
		if(this.hidden) {
			return
		}
		if(this.needUpdateMesh) {
			this.updateMesh()
		}
		if(this.needUpdateTransform) {
			this.updateTransform()
		}
		Engine.renderer.draw(this.drawCommand)
		if(this.debug) {
			Engine.renderer.drawDebug(this.transform, this.volume, this._pivot)
		}
	}

	updateMesh() {
		this.needUpdateMesh = false
	}

	updateUniforms() {
		this.drawCommand.uniforms = Object.assign({}, this.drawCommand.material.uniforms)
	}

	set material(material) {
		if(typeof material === "string") {
			const newMaterial = Resources.get(material)
			if(!newMaterial) {
				console.warn(`(Sprite.material) Could not find resource with id: ${material}`)
			}
			else {
				this.drawCommand.material = material
			}
		}
		else {
			this.drawCommand.material = material
		}

		this.updateUniforms()
	}

	get material() {
		return this.drawCommand.material
	}

	set z(z) {
		this.drawCommand.key = z
	}

	get z() {
		return this.drawCommand.key
	}

	setLayer(layerId, recursive = true) {
		this.drawCommand.layer = layerId
		if(recursive && this.children) {
			for(let n = 0; n < this.children.length; n++) {
				this.children[n].setLayer(layerId, true)
			}
		}
	}

	getLayer() {
		return this.drawCommand.layer
	}

	onEnable() {
		Stage.add(this)
		super.onEnable()
	}

	onDisable() {
		Stage.remove(this)
		super.onDisable()
	}
}

export default Renderable<commit_msg>fix: do not render empty renderable entity<commit_after>import Entity from "./Entity"
import Engine from "../Engine"
import Mesh from "../mesh/Mesh"
import Resources from "../resources/Resources"
import Stage from "../renderer/Stage"
import DrawCommand from "../renderer/DrawCommand"

class Renderable extends Entity
{
	constructor(mesh) {
		super()
		if(!mesh) {
			mesh = new Mesh(null, null)
		}
		this.needUpdateMesh = true
		this.hidden = false
		this.drawCommand = new DrawCommand(this._transform, mesh, null, null)
	}

	draw() {
		if(this.hidden || !this.drawCommand.material) {
			return
		}
		if(this.needUpdateMesh) {
			this.updateMesh()
		}
		if(this.needUpdateTransform) {
			this.updateTransform()
		}
		Engine.renderer.draw(this.drawCommand)
		if(this.debug) {
			Engine.renderer.drawDebug(this.transform, this.volume, this._pivot)
		}
	}

	updateMesh() {
		this.needUpdateMesh = false
	}

	updateUniforms() {
		this.drawCommand.uniforms = Object.assign({}, this.drawCommand.material.uniforms)
	}

	set material(material) {
		if(typeof material === "string") {
			const newMaterial = Resources.get(material)
			if(!newMaterial) {
				console.warn(`(Sprite.material) Could not find resource with id: ${material}`)
			}
			else {
				this.drawCommand.material = material
			}
		}
		else {
			this.drawCommand.material = material
		}

		this.updateUniforms()
	}

	get material() {
		return this.drawCommand.material
	}

	set z(z) {
		this.drawCommand.key = z
	}

	get z() {
		return this.drawCommand.key
	}

	setLayer(layerId, recursive = true) {
		this.drawCommand.layer = layerId
        if(recursive && this.children) {
            for(let n = 0; n < this.children.length; n++) {
                this.children[n].setLayer(layerId, true)
            }
        }
	}

	getLayer() {
		return this.drawCommand.layer
	}

	onEnable() {
		Stage.add(this)
		super.onEnable()
	}

	onDisable() {
		Stage.remove(this)
		super.onDisable()
	}
}

export default Renderable<|endoftext|>