<commit_before>var csweep;

function td_id(name, i, j) {
	return [name, 'row', i, 'col', j].join('_');
}

function remove_children(node) {
	while (node.firstChild) {
		node.removeChild(node.firstChild);
	}
}

function sweep_to_table(swp, table, cellFunc, probs) {
	remove_children(table);
	for (var i = 0; i < swp.field.height; ++i) {
		var newTr = document.createElement('tr');
		for (var j = 0; j < swp.field.width; ++j) {
			newTr.appendChild(cellFunc(swp, i, j, probs));
		}
		table.appendChild(newTr);
	}
	return table;
}

function update_field(probs) {
	sweep_to_table(csweep, document.getElementById('sweep_field'),
			create_cell, probs);
}

function update_popup (e) {
	var popup = document.getElementById('popup');
	if (!popup) {
		return
	}
	popup.style.left = (e.clientX) + 'px';
	popup.style.top  = (e.clientY) + 'px';
}

function create_cell(swp, i, j, probs) {
	var callbacks = {};
	if (probs) {
		callbacks.mouseover = function (e) {
			var prob = probs[i][j];
			if (prob === -1) {
				return;
			}
			var popup = document.createElement('div');
			popup.id  = 'popup';
			var text = (prob * 100).toPrecision(3) + '%';
			var textNode = document.createTextNode(text);
			popup.appendChild(textNode);
			document.getElementsByTagName('body'
					)[0].appendChild(popup);
			update_popup (e);
		}
		callbacks.mouseout = function (e) {
			var popup = document.getElementById('popup');
			if (popup) {
				popup.remove();
			}
		}
	}
	var newCell = cell_to_dom(swp.field[i][j], callbacks);
	newCell.id = td_id('sweep_field', i, j);
	if (probs) {
		var color = get_color(probs[i][j]);
		newCell.style.backgroundColor = color;
	}
	pos = new Position2D (i, j);
	newCell.addEventListener("click", get_dialog(pos));
	return newCell;
}

function cell_to_dom (cell, callbacks) {
	var type = cell.type;
	var res = document.createElement ('td');
	res.className += ['cell', type].join('_');
	var text;
	if (cell.isBomb()) {
		text = '⚑';
	} else if (cell.isUnknown() || cell.isEmpty()) {
		text = '';
	} else {
		text = type;
	}
	var textNode = document.createTextNode(text);
	var boldText = document.createElement("b");
	boldText.appendChild(textNode);
	res.appendChild(boldText);

	for (var name in callbacks) {
		if (callbacks.hasOwnProperty(name)) {
			res.addEventListener(name, callbacks[name]);
		}
	}

	return res;
}

function close_dialog() {
	var old_dialog = document.getElementById('dialog');
	if (old_dialog) {
		old_dialog.remove();
	}
}

function get_dialog(pos) {
	return function (e) {
		close_dialog();
		var dialog = document.createElement('table');
		dialog.className = 'dialog';
		dialog.id = 'dialog';
		dialog.style['position'] = 'absolute';
		dialog.style['left'] = e.clientX + 'px';
		dialog.style['top']  = e.clientY + 'px';
		var types = [ '1', '2', '3', '4', '5', '6', '7', '8',
		'q', 'b', '0' ];
		function get_click_callback(type) {
			return function () {
				csweep.field[pos.row][pos.col].type = type;
				close_dialog();
				update_field();
			}
		}
		var width = 4;
		for (var i = 0; i < Math.ceil(types.length / width); ++i) {
			var row = document.createElement ('tr');
			for (var j = 0; j < width; ++j) {
				var type = types[i * width + j];
				if (!type) {
					break;
				}
				var callbacks = {
					click : get_click_callback(type)
				};
				var cell = cell_to_dom(new Cell(type),
						callbacks);
				row.appendChild(cell);
			}
			dialog.appendChild(row);
		}
		var body = document.getElementsByTagName('body')[0];
		body.appendChild(dialog);
	}
}

function apply_form() {
	var width = document.getElementById('field_width').value;
	var height = document.getElementById('field_height').value;
	var mines = document.getElementById('mines_count').value;
	csweep = new Sweep(width, height, mines);
	update_field();
	return false;
}

function restore_form() {
	document.getElementById('field_width' ).value = csweep.field.width;
	document.getElementById('field_height').value = csweep.field.height;
	document.getElementById('mines_count' ).value = csweep.mines;
}

function set_initial_page() {
	csweep = new Sweep(4, 4, 6);
	restore_form();
	apply_form();
	document.addEventListener('mousemove', update_popup);
	document.addEventListener('click', function(e) {
		var target = e.target;
		while (target !== null) {
			if (/sweep_field_/.test(target.id)) {
				return;
			}
			target = target.parentElement;
		}
		close_dialog();
	});
}

function solve() {
	var number_idxs = [];
	var bomb_idxs = [];
	var free_idxs = [];
	csweep.field.forEach(function (c, i, j) {
		var idx = i * csweep.field.width + j
			if (c.isNumber() || c.isEmpty()) {
				number_idxs.push(idx)
			} else if (c.isUnknown()) {
				free_idxs.push(idx)
			} else if (c.isBomb()) {
				bomb_idxs.push(idx);
			}
	});

	var w = Number(csweep.field.width);
	var d = [0, 1, 2, w, w + 2, 2 * w, 2 * w + 1, 2 * w + 2];

	var A = create_matrix(number_idxs.length, free_idxs.length,
			function () { return false; });
	var B = create_map(number_idxs.length, function (idx) {
		var nidx = number_idxs[idx];
		return Number(csweep.field[
				Math.floor(nidx / w)][nidx % w].type); });

	for (var i = 0; i < number_idxs.length; ++i) {
		var nidx = number_idxs[i];
		for (var j = 0; j < free_idxs.length; ++j) {
			if (d.indexOf(nidx + w + 1 - free_idxs[j]) !== -1) {
				A[i][j] = true;
			}
		}
		for (var j = 0; j < bomb_idxs.length; ++j) {
			if (d.indexOf(nidx + w + 1 - bomb_idxs[j]) !== -1) {
				--B[i];
			}
		}
	}

	var mines = csweep.mines - bomb_idxs.length;
	var res = solve_for_rules(A, B, mines, mines);

	if (res) {
		var probs = create_matrix(csweep.field.height, w,
				function() { return 0; });

		for (var i = 0; i < bomb_idxs.length; ++i) {
			var bidx = bomb_idxs[i];
			probs[Math.floor(bidx / w)][bidx % w] = -1;
		}

		for (var i = 0; i < number_idxs.length; ++i) {
			var nidx = number_idxs[i];
			probs[Math.floor(nidx / w)][nidx % w] = -1;
		}

		for (var i = 0; i < free_idxs.length; ++i) {
			var fidx = free_idxs[i];
			for (var j = 0; j < res.length; ++j) {
				probs[Math.floor(fidx / w)][fidx % w]
					+= res[j][i];
			}
			probs[Math.floor(fidx / w)][fidx % w] /= res.length;
		}
		update_field(probs);
	}
}

function to_hex(c) {
	var hex = Math.floor(c).toString(16);
	return hex.length == 1 ? "0" + hex : hex;
}

function get_color(prob) {
	var red, green, blue;
	switch (prob) {
		case 100 :
			red = 255;
			green = 0;
			break;
		case 0   :
			red = 0;
			green = 255;
			break;
		case -1  :
			return undefined
		default  :
				red = 255 * prob;
				green = 255 * (1 - prob);
	}
	var red   = to_hex(red);
	var green = to_hex(green);
	var blue  = to_hex(0);
	return "#" + red + green + blue;
}
<commit_msg>Fix operation that determines if cells are near<commit_after>var csweep;

function td_id(name, i, j) {
	return [name, 'row', i, 'col', j].join('_');
}

function remove_children(node) {
	while (node.firstChild) {
		node.removeChild(node.firstChild);
	}
}

function sweep_to_table(swp, table, cellFunc, probs) {
	remove_children(table);
	for (var i = 0; i < swp.field.height; ++i) {
		var newTr = document.createElement('tr');
		for (var j = 0; j < swp.field.width; ++j) {
			newTr.appendChild(cellFunc(swp, i, j, probs));
		}
		table.appendChild(newTr);
	}
	return table;
}

function update_field(probs) {
	sweep_to_table(csweep, document.getElementById('sweep_field'),
			create_cell, probs);
}

function update_popup (e) {
	var popup = document.getElementById('popup');
	if (!popup) {
		return
	}
	popup.style.left = (e.clientX) + 'px';
	popup.style.top  = (e.clientY) + 'px';
}

function create_cell(swp, i, j, probs) {
	var callbacks = {};
	if (probs) {
		callbacks.mouseover = function (e) {
			var prob = probs[i][j];
			if (prob === -1) {
				return;
			}
			var popup = document.createElement('div');
			popup.id  = 'popup';
			var text = (prob * 100).toPrecision(3) + '%';
			var textNode = document.createTextNode(text);
			popup.appendChild(textNode);
			document.getElementsByTagName('body'
					)[0].appendChild(popup);
			update_popup (e);
		}
		callbacks.mouseout = function (e) {
			var popup = document.getElementById('popup');
			if (popup) {
				popup.remove();
			}
		}
	}
	var newCell = cell_to_dom(swp.field[i][j], callbacks);
	newCell.id = td_id('sweep_field', i, j);
	if (probs) {
		var color = get_color(probs[i][j]);
		newCell.style.backgroundColor = color;
	}
	pos = new Position2D (i, j);
	newCell.addEventListener("click", get_dialog(pos));
	return newCell;
}

function cell_to_dom (cell, callbacks) {
	var type = cell.type;
	var res = document.createElement ('td');
	res.className += ['cell', type].join('_');
	var text;
	if (cell.isBomb()) {
		text = '⚑';
	} else if (cell.isUnknown() || cell.isEmpty()) {
		text = '';
	} else {
		text = type;
	}
	var textNode = document.createTextNode(text);
	var boldText = document.createElement("b");
	boldText.appendChild(textNode);
	res.appendChild(boldText);

	for (var name in callbacks) {
		if (callbacks.hasOwnProperty(name)) {
			res.addEventListener(name, callbacks[name]);
		}
	}

	return res;
}

function close_dialog() {
	var old_dialog = document.getElementById('dialog');
	if (old_dialog) {
		old_dialog.remove();
	}
}

function get_dialog(pos) {
	return function (e) {
		close_dialog();
		var dialog = document.createElement('table');
		dialog.className = 'dialog';
		dialog.id = 'dialog';
		dialog.style['position'] = 'absolute';
		dialog.style['left'] = e.clientX + 'px';
		dialog.style['top']  = e.clientY + 'px';
		var types = [ '1', '2', '3', '4', '5', '6', '7', '8',
		'q', 'b', '0' ];
		function get_click_callback(type) {
			return function () {
				csweep.field[pos.row][pos.col].type = type;
				close_dialog();
				update_field();
			}
		}
		var width = 4;
		for (var i = 0; i < Math.ceil(types.length / width); ++i) {
			var row = document.createElement ('tr');
			for (var j = 0; j < width; ++j) {
				var type = types[i * width + j];
				if (!type) {
					break;
				}
				var callbacks = {
					click : get_click_callback(type)
				};
				var cell = cell_to_dom(new Cell(type),
						callbacks);
				row.appendChild(cell);
			}
			dialog.appendChild(row);
		}
		var body = document.getElementsByTagName('body')[0];
		body.appendChild(dialog);
	}
}

function apply_form() {
	var width = document.getElementById('field_width').value;
	var height = document.getElementById('field_height').value;
	var mines = document.getElementById('mines_count').value;
	csweep = new Sweep(width, height, mines);
	update_field();
	return false;
}

function restore_form() {
	document.getElementById('field_width' ).value = csweep.field.width;
	document.getElementById('field_height').value = csweep.field.height;
	document.getElementById('mines_count' ).value = csweep.mines;
}

function set_initial_page() {
	csweep = new Sweep(4, 4, 6);
	restore_form();
	apply_form();
	document.addEventListener('mousemove', update_popup);
	document.addEventListener('click', function(e) {
		var target = e.target;
		while (target !== null) {
			if (/sweep_field_/.test(target.id)) {
				return;
			}
			target = target.parentElement;
		}
		close_dialog();
	});
}

function solve() {
	var number_idxs = [];
	var bomb_idxs = [];
	var free_idxs = [];
	csweep.field.forEach(function (c, i, j) {
		var idx = i * csweep.field.width + j
			if (c.isNumber() || c.isEmpty()) {
				number_idxs.push(idx)
			} else if (c.isUnknown()) {
				free_idxs.push(idx)
			} else if (c.isBomb()) {
				bomb_idxs.push(idx);
			}
	});

	var w = Number(csweep.field.width);

	var A = create_matrix(number_idxs.length, free_idxs.length,
			function () { return false; });
	var B = create_map(number_idxs.length, function (idx) {
		var nidx = number_idxs[idx];
		return Number(csweep.field[
				Math.floor(nidx / w)][nidx % w].type); });

        var near = function (i, j) {
                return Math.abs(Math.floor(i / w) - Math.floor(j / w)) <= 1 &&
                        Math.abs((i % w) - (j % w)) <= 1
        };

	for (var i = 0; i < number_idxs.length; ++i) {
		var nidx = number_idxs[i];
		for (var j = 0; j < free_idxs.length; ++j) {
			if (near(nidx, free_idxs[j])) {
				A[i][j] = true;
			}
		}
		for (var j = 0; j < bomb_idxs.length; ++j) {
			if (near(nidx, bomb_idxs[j])) {
				--B[i];
			}
		}
	}

	var mines = csweep.mines - bomb_idxs.length;
	var res = solve_for_rules(A, B, mines, mines);

	if (res) {
		var probs = create_matrix(csweep.field.height, w,
				function() { return 0; });

		for (var i = 0; i < bomb_idxs.length; ++i) {
			var bidx = bomb_idxs[i];
			probs[Math.floor(bidx / w)][bidx % w] = -1;
		}

		for (var i = 0; i < number_idxs.length; ++i) {
			var nidx = number_idxs[i];
			probs[Math.floor(nidx / w)][nidx % w] = -1;
		}

		for (var i = 0; i < free_idxs.length; ++i) {
			var fidx = free_idxs[i];
			for (var j = 0; j < res.length; ++j) {
				probs[Math.floor(fidx / w)][fidx % w]
					+= res[j][i];
			}
			probs[Math.floor(fidx / w)][fidx % w] /= res.length;
		}
		update_field(probs);
	}
}

function to_hex(c) {
	var hex = Math.floor(c).toString(16);
	return hex.length == 1 ? "0" + hex : hex;
}

function get_color(prob) {
	var red, green, blue;
	switch (prob) {
		case 100 :
			red = 255;
			green = 0;
			break;
		case 0   :
			red = 0;
			green = 255;
			break;
		case -1  :
			return undefined
		default  :
				red = 255 * prob;
				green = 255 * (1 - prob);
	}
	var red   = to_hex(red);
	var green = to_hex(green);
	var blue  = to_hex(0);
	return "#" + red + green + blue;
}
<|endoftext|>


<commit_before>M.wrap('github/jillix/table/v0.0.1/table.js', function (require, module, exports) {

var View = require('github/jillix/view/v0.0.1/view');

function createTemplates (schema) {

    // create headers and rows
    var columns = {
        headers: '
',
        rows: '
'
    };

    for (var field in schema) {
        columns.headers += '' + field + '	';
        columns.rows += '{' + field + '}	';
    }
    columns.headers += '
';
    columns.rows += '
';

    return columns;
}

function clickRowHander (state, id) {
    return function () {
        state.emit(location.pathname + id + '/');
    };
}

function load (state, modelData) {
    var self = this;

    // state can't be emitted before the view is ready
    if (!self.item || !self.head) {
        return;
    }

    // render items
    if (modelData) {
        modelData = {model: modelData};
    } else {
        modelData = getDataFromUrl(self.pattern, self.map);
    }

    if (!modelData) {
        return;
    }

    // reset headers
    if (self.head.template.dom) {
        self.head.template.dom.innerHTML = '';
    }

    // reset items
    if (self.item.template.dom) {
        self.item.template.dom.innerHTML = '';
    }

    self.item.model(modelData, function (err, model) {

        if (err || !model) {
            return console.error('[table: ' + (err ? err.toString() : 'No model found.') + ']');
        }

        self.model = model;

        // render title
        if (self.title) {
            self.title.template.render([{title: model.name}]);
        }

        var templates = createTemplates(model.fields);

        // render header
        self.head.template.set(templates.headers);
        self.head.template.render();

        // render items
        self.item.template.set(templates.rows);
        model.read({q: {}, o: {}}, function (err, data) {

            if (err || !data) {
                data = [err] || ['no data'];
            }

            self.item.template.render(data);

            // add clicks to rows
            var rows = self.item.template.dom.getElementsByTagName('tr');
            for (var i = 0; i < rows.length; ++i) {
                rows[i].addEventListener('click', clickRowHander(self.item.state, data[i]._id), false);
            }
        });
    });
}

function getDataFromUrl (pattern, map) {
    var match = location.pathname.match(pattern);
    var output = {};

    if (!match) {
        return;
    }

    // create output
    for (var key in map) {
        if (map[key] instanceof Array) {
            output[key] = map[key][0] + match[map[key][1]] + (map[key][2] || '');
        } else {
            output[key] = match[map[key]];
        }
    }

    return output;
}

function init () {
    var self = this;
    var config = self.mono.config.data;

    // state handler
    self.load = load;

    // create regexp pattern
    if (config.pattern) {
        self.pattern = new RegExp(config.pattern);
    }

    // define map for regexp match
    if (config.map) {
        self.map = config.map;
    }

    // init view
    if (config && config.layout) {
        var V = View(self);

        V.load(config.layout, function (err, layout) {

            if (err) {
                return;
            }

            // save view instance
            self.layout = layout;

            if (self.layout.template) {

                // render layout view
                self.layout.template.render();

                // load controller
                var count = 0;
                var handler = function (err) {
                    if (++count === 3) {

                        var urlData = getDataFromUrl(config.pattern, config.map);
                        if (!urlData || !urlData.model) {
                            return self.emit('ready');
                        }

                        self.layout.model(urlData, function (err, model) {

                            if (!err) {

                                //add click to create button
                                var create = config.create;
                                $(create).on('click', clickRowHander(self.item.state, 'new'));

                                layout.state.emit();
                            }

                            self.emit('ready');
                        });
                    }
                };

                // load title
                if (config.title) {
                    V.load(config.title, function (err, title) {
                        self.title = title;
                        handler(err);
                    });
                } else {
                    handler();
                }

                // load headers
                if (config.head) {
                    V.load(config.head, function (err, head) {
                        self.head = head;
                        handler(err);
                    });
                } else {
                    self.head = {
                        model: V.model,
                        template: V.template({
                            to: 'thead',
                            in: self.layout.template.dom
                        })
                    };
                    handler();
                }

                // load items
                if (config.item) {
                    V.load(config.item, function (err, item) {
                        self.item = item;
                        handler(err);
                    });
                } else {
                    self.item = {
                        model: V.model,
                        state: V.state(),
                        template: V.template({
                            to: 'tbody',
                            in: self.layout.template.dom
                        })
                    };
                    handler();
                }
            }
        });
    }
}

module.exports = init;

return module;

});
<commit_msg>renamed model name prop to "name"<commit_after>M.wrap('github/jillix/table/v0.0.1/table.js', function (require, module, exports) {

var View = require('github/jillix/view/v0.0.1/view');

function createTemplates (schema) {

    // create headers and rows
    var columns = {
        headers: '
',
        rows: '
'
    };

    for (var field in schema) {
        columns.headers += '' + field + '	';
        columns.rows += '{' + field + '}	';
    }
    columns.headers += '
';
    columns.rows += '
';

    return columns;
}

function clickRowHander (state, id) {
    return function () {
        state.emit(location.pathname + id + '/');
    };
}

function load (state, modelData) {
    var self = this;

    // state can't be emitted before the view is ready
    if (!self.item || !self.head) {
        return;
    }

    // render items
    if (modelData) {
        modelData = {name: modelData};
    } else {
        modelData = getDataFromUrl(self.pattern, self.map);
    }

    if (!modelData) {
        return console.error('[table: ' + 'No info to fetch model.]');
    }

    // reset headers
    if (self.head.template.dom) {
        self.head.template.dom.innerHTML = '';
    }

    // reset items
    if (self.item.template.dom) {
        self.item.template.dom.innerHTML = '';
    }

    self.item.model(modelData, function (err, model) {

        if (err || !model) {
            return console.error('[table: ' + (err ? err.toString() : 'No model found.') + ']');
        }

        self.model = model;

        // render title
        if (self.title) {
            self.title.template.render([{title: model.name}]);
        }

        var templates = createTemplates(model.fields);

        // render header
        self.head.template.set(templates.headers);
        self.head.template.render();

        // render items
        self.item.template.set(templates.rows);
        model.read({q: {}, o: {}}, function (err, data) {

            if (err || !data) {
                data = [err] || ['no data'];
            }

            self.item.template.render(data);

            // add clicks to rows
            var rows = self.item.template.dom.getElementsByTagName('tr');
            for (var i = 0; i < rows.length; ++i) {
                rows[i].addEventListener('click', clickRowHander(self.item.state, data[i]._id), false);
            }
        });
    });
}

function getDataFromUrl (pattern, map) {
    var match = location.pathname.match(pattern);
    var output = {};

    if (!match) {
        return;
    }

    // create output
    for (var key in map) {
        if (map[key] instanceof Array) {
            output[key] = map[key][0] + match[map[key][1]] + (map[key][2] || '');
        } else {
            output[key] = match[map[key]];
        }
    }

    return output;
}

function init () {
    var self = this;
    var config = self.mono.config.data;

    // state handler
    self.load = load;

    // create regexp pattern
    if (config.pattern) {
        self.pattern = new RegExp(config.pattern);
    }

    // define map for regexp match
    if (config.map) {
        self.map = config.map;
    }

    // init view
    if (config && config.layout) {
        var V = View(self);

        V.load(config.layout, function (err, layout) {

            if (err) {
                return console.error(err);
            }

            // save view instance
            self.layout = layout;

            if (self.layout.template) {

                // render layout view
                self.layout.template.render();

                // load controller
                var count = 0;
                var handler = function (err) {
                    if (++count === 3) {

                        var urlData = getDataFromUrl(config.pattern, config.map);
                        if (!urlData || !urlData.model) {
                            return self.emit('ready');
                        }

                        self.layout.model(urlData, function (err, model) {

                            if (!err) {

                                //add click to create button
                                var create = config.create;
                                $(create).on('click', clickRowHander(self.item.state, 'new'));

                                layout.state.emit();
                            }

                            self.emit('ready');
                        });
                    }
                };

                // load title
                if (config.title) {
                    V.load(config.title, function (err, title) {
                        self.title = title;
                        handler(err);
                    });
                } else {
                    handler();
                }

                // load headers
                if (config.head) {
                    V.load(config.head, function (err, head) {
                        self.head = head;
                        handler(err);
                    });
                } else {
                    self.head = {
                        model: V.model,
                        template: V.template({
                            to: 'thead',
                            in: self.layout.template.dom
                        })
                    };
                    handler();
                }

                // load items
                if (config.item) {
                    V.load(config.item, function (err, item) {
                        self.item = item;
                        handler(err);
                    });
                } else {
                    self.item = {
                        model: V.model,
                        state: V.state(),
                        template: V.template({
                            to: 'tbody',
                            in: self.layout.template.dom
                        })
                    };
                    handler();
                }
            }
        });
    }
}

module.exports = init;

return module;

});
<|endoftext|>


<commit_before>const spreadsheetUrl = (k) =>
  `https://spreadsheets.google.com/feeds/list/${k}/1/public/basic?alt=json`;

export default {
  t201706: {
    id: "t201706",
    title: "Le performance come esperienza religiosa",
    speaker: "Andrea De Carolis",
    twitter: "@decarola",
    date: "27 Giugno",
    form: "https://goo.gl/pOigK2",
    spreadsheet: spreadsheetUrl("1j3-BnbqDxv1czcfVFr4d0fyMrHMjT3EZz_j8uMBfni0"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201709: {
    id: "t201709",
    title: "Inspecting, debugging and profiling con Chrome Developer Tools",
    speaker: "Giacomo Zinetti",
    twitter: "@gcmznt",
    date: "26 Settembre",
    form: "https://goo.gl/2QfCqd",
    spreadsheet: spreadsheetUrl("1IqfOkj1TfGrrEB3pJfudlW6BkzuJduGynosQ2gDtqtI"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201710: {
    id: "t201710",
    title: "Refactoring CSS",
    speaker: "Mattia Tommasone",
    twitter: "@raibaz",
    date: "31 Ottobre",
    form: "https://goo.gl/abhUzx",
    spreadsheet: spreadsheetUrl("1yNfKX3eZcPdW3o5xWiZKRRdGw2Uqo4IjMGD0s6qFg90"),
    prices: [
      "jetbrain license",
      "jetbrain license",
      "codemotion ticket",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt"
    ]
  },
  t201711: {
    id: "t201711",
    title: "Scrum Wars: Manuale di sopravvivenza agilep er frontenders",
    speaker: "Simone Lelli",
    twitter: "@simonelelli",
    date: "28 Novembre",
    form: "https://goo.gl/1EpvDV",
    spreadsheet: spreadsheetUrl("1ClpVr_TBdCgVAwUv4uYm68_obeyr4N8gw84bRHFhpik"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201712: {
    id: "t201712",
    title: "What Service Workers can do",
    speaker: "Maurizio Mangione",
    twitter: "@granze",
    date: "19 Dicembre",
    form: "https://goo.gl/2Kgpxx",
    spreadsheet: spreadsheetUrl("1iJpYSsRDlXKLcCDbHyxnALwi7JDhrDzZuYSUN_wqhRs"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201801: {
    id: "t201801",
    title: "Let's make frontend fun again!",
    speaker: "Salvatore Laisa",
    twitter: "@moebiusmania",
    date: "30 Gennaio",
    form: "https://goo.gl/g2AFBH",
    spreadsheet: spreadsheetUrl("1FUdcbYTzJqs2_i6qKHwmPBLyPlJX4VbJTjP9QQjIKBM"),
    prices: ["jetbrain license", "jetbrain license", "React Amsterdam"]
  },
  t201802: {
    id: "t201802",
    title: "Atomic Design: Pensare a Componenti Modulari",
    speaker: "Paul Jesus Benites Romero",
    twitter: "@pjbenitesromero",
    date: "27 Febbraio",
    form: "https://goo.gl/9ZfhxL",
    spreadsheet: spreadsheetUrl("1gV9N7pFQvHIL3pDWm8w7Wjcrh9nZe4nACU82xPRiFGo"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201803: {
    id: "t201803",
    title: "Incapsulamento e theming: le nuove frontiere dell'ultima sfida CSS",
    speaker: "Massimo Artizzu",
    twitter: "@MaxArt2501",
    date: "27 Marzo",
    form: "https://goo.gl/X7pjW2",
    spreadsheet: spreadsheetUrl("1gWUvVEP54v6q-AOOBjCwfXoZShgm98WiRcfhWrshYYo"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201804: {
    id: "t201804",
    title: "Super fast transitions",
    speaker: "Giacomo Zinetti",
    twitter: "@gcmznt",
    date: "24 Aprile",
    form: "https://goo.gl/p8uDC5",
    spreadsheet: spreadsheetUrl("1IiQsmeiLVSPX0tGFnoO_C-IHwSLJmpiI3IQZsdR0fqg"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201805: {
    id: "t201805",
    title: "Mystery Box",
    speaker: "Davide Di Pumpo",
    twitter: "@MakhBeth",
    date: "29 Maggio",
    form: "https://goo.gl/u7ghDn",
    spreadsheet: spreadsheetUrl("14naqcmlkQtiVsl8cx4nn5rAolifQMLWWfAw5O-eLSAI"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201806: {
    id: "t201806",
    title: "Deep dive into oceanic javascript animations with a greensock",
    speaker: "Alessandro Rigobello",
    twitter: "@sndrgb",
    date: "26 Giugno",
    form: "https://goo.gl/2yZG6N",
    spreadsheet: spreadsheetUrl("1r4cE2vWHvIwq_tRZ_VjCveUZe6RSgwPduJWsoAT8CSk"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201809: {
    id: "t201809",
    title: "Awesome Vue Vol.1",
    speaker: "Claudio Bisconti",
    twitter: "@claudiobisconti",
    date: "24 Settembre",
    form: "https://goo.gl/ddHv3t",
    spreadsheet: spreadsheetUrl("1ZUtBZpLjE1fqZidLMF9yCaa3ChD6hSt0r9mzHSfmX_4"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  current: {
    id: "t201810",
    title: "Awesome Vue Vol.2",
    speaker: "Claudio Bisconti",
    twitter: "@claudiobisconti",
    date: "23 Ottobre",
    form: "https://goo.gl/GiAMsh",
    spreadsheet: spreadsheetUrl("1_-7gfq2xFOxJsWiG2obmym-9PBp31Io57N7Y3O1PlZg"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  next: {
    id: "next",
    title: "Custom Properties",
    speaker: "Jiayi Hu",
    twitter: "",
    date: "27 Novembre",
    form: "",
    spreadsheet: "",
    prices: []
  // },
  // next: {
  //   id: "next",
  //   title: "??!!!?",
  //   speaker: "Forse tu?",
  //   twitter: "",
  //   date: "Ultimo martedi del mese",
  //   form: "",
  //   spreadsheet: "",
  //   prices: []
  }
};
<commit_msg>codemotion prices<commit_after>const spreadsheetUrl = (k) =>
  `https://spreadsheets.google.com/feeds/list/${k}/1/public/basic?alt=json`;

export default {
  t201706: {
    id: "t201706",
    title: "Le performance come esperienza religiosa",
    speaker: "Andrea De Carolis",
    twitter: "@decarola",
    date: "27 Giugno",
    form: "https://goo.gl/pOigK2",
    spreadsheet: spreadsheetUrl("1j3-BnbqDxv1czcfVFr4d0fyMrHMjT3EZz_j8uMBfni0"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201709: {
    id: "t201709",
    title: "Inspecting, debugging and profiling con Chrome Developer Tools",
    speaker: "Giacomo Zinetti",
    twitter: "@gcmznt",
    date: "26 Settembre",
    form: "https://goo.gl/2QfCqd",
    spreadsheet: spreadsheetUrl("1IqfOkj1TfGrrEB3pJfudlW6BkzuJduGynosQ2gDtqtI"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201710: {
    id: "t201710",
    title: "Refactoring CSS",
    speaker: "Mattia Tommasone",
    twitter: "@raibaz",
    date: "31 Ottobre",
    form: "https://goo.gl/abhUzx",
    spreadsheet: spreadsheetUrl("1yNfKX3eZcPdW3o5xWiZKRRdGw2Uqo4IjMGD0s6qFg90"),
    prices: [
      "jetbrain license",
      "jetbrain license",
      "codemotion ticket",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt"
    ]
  },
  t201711: {
    id: "t201711",
    title: "Scrum Wars: Manuale di sopravvivenza agilep er frontenders",
    speaker: "Simone Lelli",
    twitter: "@simonelelli",
    date: "28 Novembre",
    form: "https://goo.gl/1EpvDV",
    spreadsheet: spreadsheetUrl("1ClpVr_TBdCgVAwUv4uYm68_obeyr4N8gw84bRHFhpik"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201712: {
    id: "t201712",
    title: "What Service Workers can do",
    speaker: "Maurizio Mangione",
    twitter: "@granze",
    date: "19 Dicembre",
    form: "https://goo.gl/2Kgpxx",
    spreadsheet: spreadsheetUrl("1iJpYSsRDlXKLcCDbHyxnALwi7JDhrDzZuYSUN_wqhRs"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201801: {
    id: "t201801",
    title: "Let's make frontend fun again!",
    speaker: "Salvatore Laisa",
    twitter: "@moebiusmania",
    date: "30 Gennaio",
    form: "https://goo.gl/g2AFBH",
    spreadsheet: spreadsheetUrl("1FUdcbYTzJqs2_i6qKHwmPBLyPlJX4VbJTjP9QQjIKBM"),
    prices: ["jetbrain license", "jetbrain license", "React Amsterdam"]
  },
  t201802: {
    id: "t201802",
    title: "Atomic Design: Pensare a Componenti Modulari",
    speaker: "Paul Jesus Benites Romero",
    twitter: "@pjbenitesromero",
    date: "27 Febbraio",
    form: "https://goo.gl/9ZfhxL",
    spreadsheet: spreadsheetUrl("1gV9N7pFQvHIL3pDWm8w7Wjcrh9nZe4nACU82xPRiFGo"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201803: {
    id: "t201803",
    title: "Incapsulamento e theming: le nuove frontiere dell'ultima sfida CSS",
    speaker: "Massimo Artizzu",
    twitter: "@MaxArt2501",
    date: "27 Marzo",
    form: "https://goo.gl/X7pjW2",
    spreadsheet: spreadsheetUrl("1gWUvVEP54v6q-AOOBjCwfXoZShgm98WiRcfhWrshYYo"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201804: {
    id: "t201804",
    title: "Super fast transitions",
    speaker: "Giacomo Zinetti",
    twitter: "@gcmznt",
    date: "24 Aprile",
    form: "https://goo.gl/p8uDC5",
    spreadsheet: spreadsheetUrl("1IiQsmeiLVSPX0tGFnoO_C-IHwSLJmpiI3IQZsdR0fqg"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201805: {
    id: "t201805",
    title: "Mystery Box",
    speaker: "Davide Di Pumpo",
    twitter: "@MakhBeth",
    date: "29 Maggio",
    form: "https://goo.gl/u7ghDn",
    spreadsheet: spreadsheetUrl("14naqcmlkQtiVsl8cx4nn5rAolifQMLWWfAw5O-eLSAI"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201806: {
    id: "t201806",
    title: "Deep dive into oceanic javascript animations with a greensock",
    speaker: "Alessandro Rigobello",
    twitter: "@sndrgb",
    date: "26 Giugno",
    form: "https://goo.gl/2yZG6N",
    spreadsheet: spreadsheetUrl("1r4cE2vWHvIwq_tRZ_VjCveUZe6RSgwPduJWsoAT8CSk"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  t201809: {
    id: "t201809",
    title: "Awesome Vue Vol.1",
    speaker: "Claudio Bisconti",
    twitter: "@claudiobisconti",
    date: "24 Settembre",
    form: "https://goo.gl/ddHv3t",
    spreadsheet: spreadsheetUrl("1ZUtBZpLjE1fqZidLMF9yCaa3ChD6hSt0r9mzHSfmX_4"),
    prices: ["jetbrain license", "jetbrain license"]
  },
  current: {
    id: "t201810",
    title: "Awesome Vue Vol.2",
    speaker: "Claudio Bisconti",
    twitter: "@claudiobisconti",
    date: "23 Ottobre",
    form: "https://goo.gl/GiAMsh",
    spreadsheet: spreadsheetUrl("1_-7gfq2xFOxJsWiG2obmym-9PBp31Io57N7Y3O1PlZg"),
    prices: [
      "jetbrain license",
      "jetbrain license",
      "codemotion ticket",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt",
      "tshirt"
    ]
  },
  next: {
    id: "next",
    title: "Custom Properties",
    speaker: "Jiayi Hu",
    twitter: "",
    date: "27 Novembre",
    form: "",
    spreadsheet: "",
    prices: []
    // },
    // next: {
    //   id: "next",
    //   title: "??!!!?",
    //   speaker: "Forse tu?",
    //   twitter: "",
    //   date: "Ultimo martedi del mese",
    //   form: "",
    //   spreadsheet: "",
    //   prices: []
  }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

var pkg    = require("./package.json");

process.name = pkg.name;

var cmd    = require("commander"),
    chalk  = require("chalk"),
    net    = require("net"),
    dns    = require("dns"),
    stdev  = require("compute-stdev"),
    tcpie  = require("./");

var DIGITS_LINE  = 1,
    DIGITS_STATS = 3,
    DIGITS_PERC  = 0,
    DEFAULT_PORT = 80;

cmd
    .usage("[options] host [port]")
    .option("-v, --version", "output the version number", function () {
        writeLine(pkg.version);
        process.exit(0);
    })
    .option("-c, --count <n>", "number of connects (default: infinite)", parseInt)
    .option("-i, --interval <n>", "wait n seconds between connects (default: 1)", parseFloat)
    .option("-t, --timeout <n>", "connection timeout in seconds (default: 3)", parseFloat)
    .option("-f, --flood", "flood mode, connect as fast as possible")
    .option("--color", "enable color output")
    .on("--help", function () {
        writeLine("  Notes:");
        writeLine("    -  host:port syntax is supported");
        writeLine("    -  port defaults to 80");
        writeLine();
        writeLine("  Examples:");
        writeLine();
        writeLine("    $", pkg.name, "-c 5 google.com");
        writeLine("    $", pkg.name, "-c 10 aspmx.l.google.com 25");
        writeLine();
    })
    .parse(process.argv);

if (!cmd.args.length || cmd.args.length > 2 || (cmd.args[1] && isNaN(parseInt(cmd.args[1], 10)))) {
    cmd.outputHelp();
    process.exit(1);
}

var host    = cmd.args[0],
    opts    = {},
    port    = parseInt(cmd.args[1], 10),
    printed = false,
    rtts    = [],
    stats;

// host:port syntax
var matches = host.match(/^(.+):(.+)$/);
if (matches && matches.length === 3 && !port) {
    host = matches[1];
    port = matches[2];
}

if (!port) port = DEFAULT_PORT;
if (cmd.count) opts.count = parseInt(cmd.count, 10);
if (cmd.interval) opts.interval = secondsToMs(cmd.interval);
if (cmd.timeout) opts.timeout = secondsToMs(cmd.timeout);
if (cmd.flood) opts.interval = 0;
if (!cmd.color) chalk.enabled = false;

// Do a DNS lookup and start the connects
if (!net.isIP(host)) {
    dns.lookup(host, function (err, address) {
        if (!err) {
            printStart(host, address, port);
            run(host, port, opts);
        } else {
            if (err.code === "ENOTFOUND")
                writeLine(chalk.red("ERROR:"), "Domain", host, "not found.");
            else
                writeLine(chalk.red("ERROR:"), err.code, err.syscall || "");
            process.exit(1);
        }
    });
} else {
    printStart(host, host, port);
    run(host, port, opts);
}

function run(host, port, opts) {
    var pie = tcpie(host, port, opts);

    pie.on("error", function (data, err) {
        stats = data;
        writeLine(
            chalk.red("error connecting to"),
            chalk.red(data.target.host + ":" + data.target.port),
            chalk.yellow("seq=") + chalk.green(data.sent),
            chalk.yellow("error=") + chalk.red(err.code)
        );
    });

    pie.on("connect", function (data) {
        stats = data;
        rtts.push(data.rtt);
        writeLine(
            chalk.green("connected to"),
            chalk.green(data.target.host + ":" + data.target.port),
            chalk.yellow("seq=") + chalk.green(data.sent),
            chalk.yellow("srcport=") + chalk.green(data.socket.localPort),
            chalk.yellow("time=") + colorRTT(data.rtt.toFixed(DIGITS_LINE))
        );
    });

    pie.on("timeout", function (data) {
        stats = data;
        writeLine(
              chalk.red("timeout connecting to"),
              chalk.red(data.target.host + ":" + data.target.port),
              chalk.yellow("seq=") + chalk.green(data.sent),
              data.socket.localPort && chalk.yellow("srcport=") + chalk.green(data.socket.localPort)
        );
    });

    process.on("exit", printEnd);
    process.on("SIGINT", process.exit);
    process.on("SIGQUIT", process.exit);
    process.on("SIGTERM", process.exit);
    pie.on("end", printEnd).start();
}

function printStart(host, address, port) {
    writeLine(pkg.name.toUpperCase(), host, "(" + address + ")", "port", String(port));
}

function printEnd() {
    var sum = 0, min = Infinity, max = 0, avg, dev;

    if (printed)
        process.exit(0);

    if (stats && stats.sent > 0) {
        rtts.forEach(function (rtt) {
            if (rtt <= min) min = rtt.toFixed(DIGITS_STATS);
            if (rtt >= max) max = rtt.toFixed(DIGITS_STATS);
            sum += rtt;
        });

        avg = (sum / rtts.length).toFixed(DIGITS_STATS);
        dev = stdev(rtts).toFixed(DIGITS_STATS);

        if (min === Infinity) min = "0";
        if (isNaN(avg)) avg = "0";

        printed = true;

        writeLine("\n---", host, pkg.name + " statistics", "---",
                  "\n" + stats.sent, "handshakes attempted,", stats.success || "0", "succeeded,",
                  ((stats.failed / stats.sent) * 100).toFixed(DIGITS_PERC) + "% failed",
                  "\nrtt min/avg/max/stdev =", min + "/" + avg + "/" + max + "/" + dev, "ms");
    }
    process.exit(0);
}

function colorRTT(rtt) {
    if (rtt >= 150)
        return chalk.red(rtt + " ms");
    else if (rtt >= 75)
        return chalk.yellow(rtt + " ms");
    else
        return chalk.green(rtt + " ms");
}

function writeLine() {
    var args = Array.prototype.slice.call(arguments), stream;
    args = args.filter(function (string) { return Boolean(string); });
    args.push("\n");
    stream = (process.stdout._type === "pipe" && printed) ? process.stderr : process.stdout;
    stream.write(args.join(" "));
}

// convert seconds to milliseconds
function secondsToMs(s) {
    return (parseFloat(s) * 1000);
}
<commit_msg>Fix process title and format cli help<commit_after>#!/usr/bin/env node
"use strict";

var pkg    = require("./package.json");

process.title = pkg.name;

var cmd    = require("commander"),
    chalk  = require("chalk"),
    net    = require("net"),
    dns    = require("dns"),
    stdev  = require("compute-stdev"),
    tcpie  = require("./");

var DIGITS_LINE  = 1,
    DIGITS_STATS = 3,
    DIGITS_PERC  = 0,
    DEFAULT_PORT = 80;

cmd
    .usage("[options] host [port]")
    .option("-v, --version", "output the version number", function () {
        writeLine(pkg.version);
        process.exit(0);
    })
    .option("-c, --count <n>", "number of connects (default: infinite)", parseInt)
    .option("-i, --interval <n>", "wait n seconds between connects (default: 1)", parseFloat)
    .option("-t, --timeout <n>", "connection timeout in seconds (default: 3)", parseFloat)
    .option("-f, --flood", "flood mode, connect as fast as possible")
    .option("--color", "enable color output")
    .on("--help", function () {
        writeLine("  Notes:");
        writeLine("");
        writeLine("    -  host:port syntax is supported");
        writeLine("    -  port defaults to 80");
        writeLine();
        writeLine("  Examples:");
        writeLine();
        writeLine("    $", pkg.name, "-c 5 google.com");
        writeLine("    $", pkg.name, "-c 10 aspmx.l.google.com 25");
        writeLine();
    })
    .parse(process.argv);

if (!cmd.args.length || cmd.args.length > 2 || (cmd.args[1] && isNaN(parseInt(cmd.args[1], 10)))) {
    cmd.outputHelp();
    process.exit(1);
}

var host    = cmd.args[0],
    opts    = {},
    port    = parseInt(cmd.args[1], 10),
    printed = false,
    rtts    = [],
    stats;

// host:port syntax
var matches = host.match(/^(.+):(.+)$/);
if (matches && matches.length === 3 && !port) {
    host = matches[1];
    port = matches[2];
}

if (!port) port = DEFAULT_PORT;
if (cmd.count) opts.count = parseInt(cmd.count, 10);
if (cmd.interval) opts.interval = secondsToMs(cmd.interval);
if (cmd.timeout) opts.timeout = secondsToMs(cmd.timeout);
if (cmd.flood) opts.interval = 0;
if (!cmd.color) chalk.enabled = false;

// Do a DNS lookup and start the connects
if (!net.isIP(host)) {
    dns.lookup(host, function (err, address) {
        if (!err) {
            printStart(host, address, port);
            run(host, port, opts);
        } else {
            if (err.code === "ENOTFOUND")
                writeLine(chalk.red("ERROR:"), "Domain", host, "not found.");
            else
                writeLine(chalk.red("ERROR:"), err.code, err.syscall || "");
            process.exit(1);
        }
    });
} else {
    printStart(host, host, port);
    run(host, port, opts);
}

function run(host, port, opts) {
    var pie = tcpie(host, port, opts);

    pie.on("error", function (data, err) {
        stats = data;
        writeLine(
            chalk.red("error connecting to"),
            chalk.red(data.target.host + ":" + data.target.port),
            chalk.yellow("seq=") + chalk.green(data.sent),
            chalk.yellow("error=") + chalk.red(err.code)
        );
    });

    pie.on("connect", function (data) {
        stats = data;
        rtts.push(data.rtt);
        writeLine(
            chalk.green("connected to"),
            chalk.green(data.target.host + ":" + data.target.port),
            chalk.yellow("seq=") + chalk.green(data.sent),
            chalk.yellow("srcport=") + chalk.green(data.socket.localPort),
            chalk.yellow("time=") + colorRTT(data.rtt.toFixed(DIGITS_LINE))
        );
    });

    pie.on("timeout", function (data) {
        stats = data;
        writeLine(
              chalk.red("timeout connecting to"),
              chalk.red(data.target.host + ":" + data.target.port),
              chalk.yellow("seq=") + chalk.green(data.sent),
              data.socket.localPort && chalk.yellow("srcport=") + chalk.green(data.socket.localPort)
        );
    });

    process.on("exit", printEnd);
    process.on("SIGINT", process.exit);
    process.on("SIGQUIT", process.exit);
    process.on("SIGTERM", process.exit);
    pie.on("end", printEnd).start();
}

function printStart(host, address, port) {
    writeLine(pkg.name.toUpperCase(), host, "(" + address + ")", "port", String(port));
}

function printEnd() {
    var sum = 0, min = Infinity, max = 0, avg, dev;

    if (printed)
        process.exit(0);

    if (stats && stats.sent > 0) {
        rtts.forEach(function (rtt) {
            if (rtt <= min) min = rtt.toFixed(DIGITS_STATS);
            if (rtt >= max) max = rtt.toFixed(DIGITS_STATS);
            sum += rtt;
        });

        avg = (sum / rtts.length).toFixed(DIGITS_STATS);
        dev = stdev(rtts).toFixed(DIGITS_STATS);

        if (min === Infinity) min = "0";
        if (isNaN(avg)) avg = "0";

        printed = true;

        writeLine("\n---", host, pkg.name + " statistics", "---",
                  "\n" + stats.sent, "handshakes attempted,", stats.success || "0", "succeeded,",
                  ((stats.failed / stats.sent) * 100).toFixed(DIGITS_PERC) + "% failed",
                  "\nrtt min/avg/max/stdev =", min + "/" + avg + "/" + max + "/" + dev, "ms");
    }
    process.exit(0);
}

function colorRTT(rtt) {
    if (rtt >= 150)
        return chalk.red(rtt + " ms");
    else if (rtt >= 75)
        return chalk.yellow(rtt + " ms");
    else
        return chalk.green(rtt + " ms");
}

function writeLine() {
    var args = Array.prototype.slice.call(arguments), stream;
    args = args.filter(function (string) { return Boolean(string); });
    args.push("\n");
    stream = (process.stdout._type === "pipe" && printed) ? process.stderr : process.stdout;
    stream.write(args.join(" "));
}

// convert seconds to milliseconds
function secondsToMs(s) {
    return (parseFloat(s) * 1000);
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

var pkg = require("./package.json");

// set process title
process.title = pkg.name;

// avoid EPIPE on partially consumed streams
require("epipebomb")();

var args   = require("minimist")(process.argv.slice(2), {boolean: ["color"]});
var chalk  = require("chalk");
var net    = require("net");
var dns    = require("dns");
var stdev  = require("compute-stdev");
var tcpie  = require("./");

var DIGITS_LINE  = 1;
var DIGITS_STATS = 3;
var DIGITS_PERC  = 0;
var DEFAULT_PORT = 80;

var usage = [
  "",
  "    Usage: tcpie [options] host[:port]|url [port|80]",
  "",
  "    Options:",
  "",
  "      -v, --version       output version",
  "      -c, --count <n>     number of connects (default: infinite)",
  "      -i, --interval <n>  wait n seconds between connects (default: 1)",
  "      -t, --timeout <n>   connection timeout in seconds (default: 3)",
  "      -T, --timestamp     add timestamps to output",
  "      -f, --flood         flood mode, connect as fast as possible",
  "      -C, --no-color      disable color output",
  "",
  "    Examples:",
  "",
  "      $ tcpie google.com",
  "      $ tcpie -i .1 8.8.8.8:53",
  "      $ tcpie -c5 -t.05 aspmx.l.google.com 25",
  "      $ tcpie -i.2 https://google.com",
  "",
  ""
].join("\n");

if (args.v) {
  process.stdout.write(pkg.version + "\n");
  process.exit(0);
}

if (!args._.length || args._.length > 2 || (args._[1] && isNaN(parseInt(args._[1], 10)))) {
  help();
}

var host    = args._[0];
var opts    = {};
var port    = parseInt(args._[1], 10);
var printed = false;
var rtts    = [];
var stats;

if (typeof host !== "string") {
  help();
}

// host:port syntax
var matches = /^(.+):(\d+)$/.exec(host);
if (matches && matches.length === 3 && !port) {
  host = matches[1];
  port = matches[2];
}

// url syntax
if (/.+:\/\/.+/.test(host)) {
  var url = require("url").parse(host);
  var proto = url.protocol.replace(":", "");
  host = url.host;
  port = url.port || require("port-numbers").getPort(proto).port;
  if (!port) {
    writeLine(chalk.red("ERROR:"), "Unknown protocol '" + proto + "'");
    process.exit(1);
  }
  if (!host) {
    writeLine(chalk.red("ERROR:"), "Missing host in '" + host + "'");
  }
}

if (!port) port = DEFAULT_PORT;
if (args.count || args.c) opts.count = parseInt(args.count || args.c, 10);
if (args.interval || args.i) opts.interval = secondsToMs(args.interval || args.i);
if (args.timeout || args.t) opts.timeout = secondsToMs(args.timeout || args.t);
if (args.flood || args.f) opts.interval = 0;
if (args.C) chalk.enabled = false;

// Do a DNS lookup and start the connects
if (!net.isIP(host)) {
  dns.lookup(host, function(err, address) {
    if (!err) {
      printStart(host, address, port);
      run(host, port, opts);
    } else {
      if (err.code === "ENOTFOUND")
        writeLine(chalk.red("ERROR:"), "Host '" + host + "' not found");
      else
        writeLine(chalk.red("ERROR:"), err.code, err.syscall || "");
      process.exit(1);
    }
  });
} else {
  printStart(host, host, port);
  run(host, port, opts);
}

function run(host, port, opts) {
  var pie = tcpie(host, port, opts);

  pie.on("error", function(err, data) {
    stats = data;
    writeLine(
      chalk.red("error connecting to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      "error=" + chalk.red(err.code)
    );
  });

  pie.on("connect", function(data) {
    stats = data;
    rtts.push(data.rtt);
    writeLine(
      chalk.green("connected to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      "srcport=" + data.socket.localPort,
      "time=" + colorRTT(data.rtt.toFixed(DIGITS_LINE))
    );
  });

  pie.on("timeout", function(data) {
    stats = data;
    writeLine(
      chalk.red("timeout connecting to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      data.socket.localPort && "srcport=" + data.socket.localPort
    );
  });

  if (process.stdin.isTTY) {
    process.stdin.setRawMode(true);
    process.stdin.on("data", function(bytes) {
      // http://nemesis.lonestar.org/reference/telecom/codes/ascii.html
      var exitCodes = [
        3,  // SIGINT
        4,  // EOF
        26, // SIGTSTP
        28, // SIGQUIT
      ];
      for (var i = 0; i < bytes.length; i++) {
        if (exitCodes.indexOf(bytes[i]) !== -1)
          process.exit(0);
      }
    });
  } else {
    process.on("SIGINT", process.exit);
    process.on("SIGQUIT", process.exit);
    process.on("SIGTERM", process.exit);
    process.on("SIGTSTP", process.exit);
  }

  process.on("exit", printEnd);
  pie.on("end", printEnd).start();
}

function printStart(host, address, port) {
  writeLine(pkg.name.toUpperCase(), host, "(" + address + ")", "port", String(port));
}

function printEnd() {
  var sum = 0, min = Infinity, max = 0, avg, dev;

  if (printed)
    process.exit(0);

  if (stats && stats.sent > 0) {
    rtts.forEach(function(rtt) {
      if (rtt <= min) min = rtt.toFixed(DIGITS_STATS);
      if (rtt >= max) max = rtt.toFixed(DIGITS_STATS);
      sum += rtt;
    });

    avg = (sum / rtts.length).toFixed(DIGITS_STATS);
    dev = stdev(rtts).toFixed(DIGITS_STATS);

    if (min === Infinity) min = "0";
    if (isNaN(avg)) avg = "0";

    printed = true;

    writeLine("\n---", host, pkg.name + " statistics", "---",
          "\n" + stats.sent, "handshakes attempted,", stats.success || "0", "succeeded,",
          ((stats.failed / stats.sent) * 100).toFixed(DIGITS_PERC) + "% failed",
          "\nrtt min/avg/max/stdev =", min + "/" + avg + "/" + max + "/" + dev, "ms");

    process.exit(stats.success && 1 || 0);
  } else {
    process.exit(1);
  }
}

function colorRTT(rtt) {
  return chalk[rtt >= 150 ? "red" : rtt >= 75 ? "yellow" : "green"](rtt) + " ms";
}

function writeLine() {
  var arg = [].slice.call(arguments), stream;
  arg = arg.filter(function(string) { return Boolean(string); });
  if ((args.timeout || args.T) && arg[0][0] !== "\n") arg.unshift(timestamp());
  arg.push("\n");
  stream = (process.stdout._type === "pipe" && printed) ? process.stderr : process.stdout;
  stream.write(arg.join(" "));
}

function help() {
  process.stdout.write(usage);
  process.exit(1);
}

function secondsToMs(s) {
  return (parseFloat(s) * 1000);
}

function timestamp() {
  var now = new Date(), day = now.getDate(), month = now.getMonth() + 1;
  var year = now.getFullYear(), hrs = now.getHours(), mins = now.getMinutes();
  var secs = now.getSeconds();

  if (month < 10) month = "0" + month;
  if (day   < 10) day   = "0" + day;
  if (hrs   < 10) hrs   = "0" + hrs;
  if (mins  < 10) mins  = "0" + mins;
  if (secs  < 10) secs  = "0" + secs;
  return year + "-"  + month + "-" + day + " " + hrs + ":" + mins + ":" + secs;
}
<commit_msg>chain some event emitters<commit_after>#!/usr/bin/env node
"use strict";

var pkg = require("./package.json");

// set process title
process.title = pkg.name;

// avoid EPIPE on partially consumed streams
require("epipebomb")();

var args   = require("minimist")(process.argv.slice(2), {boolean: ["color"]});
var chalk  = require("chalk");
var net    = require("net");
var dns    = require("dns");
var stdev  = require("compute-stdev");
var tcpie  = require("./");

var DIGITS_LINE  = 1;
var DIGITS_STATS = 3;
var DIGITS_PERC  = 0;
var DEFAULT_PORT = 80;

var usage = [
  "",
  "    Usage: tcpie [options] host[:port]|url [port|80]",
  "",
  "    Options:",
  "",
  "      -v, --version       output version",
  "      -c, --count <n>     number of connects (default: infinite)",
  "      -i, --interval <n>  wait n seconds between connects (default: 1)",
  "      -t, --timeout <n>   connection timeout in seconds (default: 3)",
  "      -T, --timestamp     add timestamps to output",
  "      -f, --flood         flood mode, connect as fast as possible",
  "      -C, --no-color      disable color output",
  "",
  "    Examples:",
  "",
  "      $ tcpie google.com",
  "      $ tcpie -i .1 8.8.8.8:53",
  "      $ tcpie -c5 -t.05 aspmx.l.google.com 25",
  "      $ tcpie -i.2 https://google.com",
  "",
  ""
].join("\n");

if (args.v) {
  process.stdout.write(pkg.version + "\n");
  process.exit(0);
}

if (!args._.length || args._.length > 2 || (args._[1] && isNaN(parseInt(args._[1], 10)))) {
  help();
}

var host    = args._[0];
var opts    = {};
var port    = parseInt(args._[1], 10);
var printed = false;
var rtts    = [];
var stats;

if (typeof host !== "string") {
  help();
}

// host:port syntax
var matches = /^(.+):(\d+)$/.exec(host);
if (matches && matches.length === 3 && !port) {
  host = matches[1];
  port = matches[2];
}

// url syntax
if (/.+:\/\/.+/.test(host)) {
  var url = require("url").parse(host);
  var proto = url.protocol.replace(":", "");
  host = url.host;
  port = url.port || require("port-numbers").getPort(proto).port;
  if (!port) {
    writeLine(chalk.red("ERROR:"), "Unknown protocol '" + proto + "'");
    process.exit(1);
  }
  if (!host) {
    writeLine(chalk.red("ERROR:"), "Missing host in '" + host + "'");
  }
}

if (!port) port = DEFAULT_PORT;
if (args.count || args.c) opts.count = parseInt(args.count || args.c, 10);
if (args.interval || args.i) opts.interval = secondsToMs(args.interval || args.i);
if (args.timeout || args.t) opts.timeout = secondsToMs(args.timeout || args.t);
if (args.flood || args.f) opts.interval = 0;
if (args.C) chalk.enabled = false;

// Do a DNS lookup and start the connects
if (!net.isIP(host)) {
  dns.lookup(host, function(err, address) {
    if (!err) {
      printStart(host, address, port);
      run(host, port, opts);
    } else {
      if (err.code === "ENOTFOUND")
        writeLine(chalk.red("ERROR:"), "Host '" + host + "' not found");
      else
        writeLine(chalk.red("ERROR:"), err.code, err.syscall || "");
      process.exit(1);
    }
  });
} else {
  printStart(host, host, port);
  run(host, port, opts);
}

function run(host, port, opts) {
  var pie = tcpie(host, port, opts);

  pie.on("error", function(err, data) {
    stats = data;
    writeLine(
      chalk.red("error connecting to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      "error=" + chalk.red(err.code)
    );
  }).on("connect", function(data) {
    stats = data;
    rtts.push(data.rtt);
    writeLine(
      chalk.green("connected to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      "srcport=" + data.socket.localPort,
      "time=" + colorRTT(data.rtt.toFixed(DIGITS_LINE))
    );
  }).on("timeout", function(data) {
    stats = data;
    writeLine(
      chalk.red("timeout connecting to", data.target.host + ":" + data.target.port),
      "seq=" + data.sent,
      data.socket.localPort && "srcport=" + data.socket.localPort
    );
  });

  if (process.stdin.isTTY) {
    process.stdin.setRawMode(true);
    process.stdin.on("data", function(bytes) {
      // http://nemesis.lonestar.org/reference/telecom/codes/ascii.html
      var exitCodes = [
        3,  // SIGINT
        4,  // EOF
        26, // SIGTSTP
        28, // SIGQUIT
      ];
      for (var i = 0; i < bytes.length; i++) {
        if (exitCodes.indexOf(bytes[i]) !== -1)
          process.exit(0);
      }
    });
  } else {
    process.on("SIGINT", process.exit);
    process.on("SIGQUIT", process.exit);
    process.on("SIGTERM", process.exit);
    process.on("SIGTSTP", process.exit);
  }

  process.on("exit", printEnd);
  pie.on("end", printEnd).start();
}

function printStart(host, address, port) {
  writeLine(pkg.name.toUpperCase(), host, "(" + address + ")", "port", String(port));
}

function printEnd() {
  var sum = 0, min = Infinity, max = 0, avg, dev;

  if (printed)
    process.exit(0);

  if (stats && stats.sent > 0) {
    rtts.forEach(function(rtt) {
      if (rtt <= min) min = rtt.toFixed(DIGITS_STATS);
      if (rtt >= max) max = rtt.toFixed(DIGITS_STATS);
      sum += rtt;
    });

    avg = (sum / rtts.length).toFixed(DIGITS_STATS);
    dev = stdev(rtts).toFixed(DIGITS_STATS);

    if (min === Infinity) min = "0";
    if (isNaN(avg)) avg = "0";

    printed = true;

    writeLine("\n---", host, pkg.name + " statistics", "---",
          "\n" + stats.sent, "handshakes attempted,", stats.success || "0", "succeeded,",
          ((stats.failed / stats.sent) * 100).toFixed(DIGITS_PERC) + "% failed",
          "\nrtt min/avg/max/stdev =", min + "/" + avg + "/" + max + "/" + dev, "ms");

    process.exit(stats.success && 1 || 0);
  } else {
    process.exit(1);
  }
}

function colorRTT(rtt) {
  return chalk[rtt >= 150 ? "red" : rtt >= 75 ? "yellow" : "green"](rtt) + " ms";
}

function writeLine() {
  var arg = [].slice.call(arguments), stream;
  arg = arg.filter(function(string) { return Boolean(string); });
  if ((args.timeout || args.T) && arg[0][0] !== "\n") arg.unshift(timestamp());
  arg.push("\n");
  stream = (process.stdout._type === "pipe" && printed) ? process.stderr : process.stdout;
  stream.write(arg.join(" "));
}

function help() {
  process.stdout.write(usage);
  process.exit(1);
}

function secondsToMs(s) {
  return (parseFloat(s) * 1000);
}

function timestamp() {
  var now = new Date(), day = now.getDate(), month = now.getMonth() + 1;
  var year = now.getFullYear(), hrs = now.getHours(), mins = now.getMinutes();
  var secs = now.getSeconds();

  if (month < 10) month = "0" + month;
  if (day   < 10) day   = "0" + day;
  if (hrs   < 10) hrs   = "0" + hrs;
  if (mins  < 10) mins  = "0" + mins;
  if (secs  < 10) secs  = "0" + secs;
  return year + "-"  + month + "-" + day + " " + hrs + ":" + mins + ":" + secs;
}
<|endoftext|>


<commit_before>var logger = require('winston'),
    request = require("request"),
    usedDate = '',
    d = new Date(),
/* Returns a string representing a date in 'ddMMyy'
	string format. */
    helpers = require('./lib/helpers'),
    dateString = helpers.dateString,
    parseBody = helpers.parseBody,
/* Callback function called on request.
	Checks if any 'checked' error has occured,
	and if so, displays proper message. If request
	was successful, parse method is called.
	Ambiguous error message is displayed when
	something wrong happened. */
    callback = function (error, response, body) {
        if (error) {
            logger.log(error);
        } else if (response.statusCode == 404) {
            logger.log('error','No document found under provided date. Trying day before');
            d = new Date();
            d.setDate(d.getDate() - 1);
            usedDate = dateString(d);
            var link = "http://www.hnb.hr/tecajn/f" + usedDate + ".dat";
            request(link, callback);
        } else if (!error && response.statusCode == 200) {
            logger.log('info', body);
            logger.log('info',JSON.stringify(parseBody(body)));
        } else {
            logger.log('error',"Error has occured");
        }
    }

usedDate = dateString(d);
var link = "http://www.hnb.hr/tecajn/f" + usedDate + ".dat";

request(link, callback);
<commit_msg>Fixed infinite date loop<commit_after>var logger = require('winston'),
    request = require("request"),
    usedDate = '',
    d = new Date(),
/* Returns a string representing a date in 'ddMMyy'
	string format. */
    helpers = require('./lib/helpers'),
    dateString = helpers.dateString,
    parseBody = helpers.parseBody,
/* Callback function called on request.
	Checks if any 'checked' error has occured,
	and if so, displays proper message. If request
	was successful, parse method is called.
	Ambiguous error message is displayed when
	something wrong happened. */
    d = new Date(),
    callback = function (error, response, body) {
        if (error) {
            logger.log(error);
        } else if (response.statusCode == 404) {
            logger.log('error','No document found under provided date. Trying day before');
            d.setDate(d.getDate() - 1);
            usedDate = dateString(d);
            var link = "http://www.hnb.hr/tecajn/f" + usedDate + ".dat";
            request(link, callback);
        } else if (!error && response.statusCode == 200) {
            logger.log('info', body);
            logger.log('info',JSON.stringify(parseBody(body)));
        } else {
            logger.log('error',"Error has occured");
        }
    }

usedDate = dateString(d);
var link = "http://www.hnb.hr/tecajn/f" + usedDate + ".dat";

request(link, callback);
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var hopsRoot = require('hops-root');
var hopsConfig = require('.');

var manifestData = null;
var manifestScript = '';

function getRawManifestData () {
  if (!manifestData) {
    manifestData = hopsRoot.require(
      hopsConfig.buildDir,
      'manifest.json'
    );
  }
  return Object.assign({}, manifestData);
}

exports.getManifestScript = function () {
  if (!manifestScript) {
    var filename = getRawManifestData()['manifest.js'];
    if (filename) {
      var filepath = hopsRoot.resolve(
        hopsConfig.buildDir,
        filename.replace(/^\/*/, '')
      );
      if (fs.existsSync(filepath)) {
        manifestScript = fs.readFileSync(filepath, 'utf8');
      }
    }
  }
  return manifestScript;
};

exports.getAssetLinks = function () {
  var vjs = 'vendor.js';
  var manifest = getRawManifestData();
  return Object.keys(manifest).sort(function (a, b) {
    return a === vjs ? -1 : b === vjs ? 1 : a < b ? -1 : a > b ? 1 : 0;
  }).reduce(function (assets, key) {
    if (!/^(chunk|manifest).*\.js/.test(key)) {
      if (/\.js$/.test(key)) {
        assets.js.push(manifest[key]);
      }
      if (/\.css$/.test(key)) {
        assets.css.push(manifest[key]);
      }
    }
    return assets;
  }, { js: [], css: [] });
};
<commit_msg>make manifest utils more robust<commit_after>'use strict';

var fs = require('fs');
var hopsRoot = require('hops-root');
var hopsConfig = require('.');

var manifestData = null;
var manifestScript = '';

function getRawManifestData () {
  if (!manifestData) {
    var filepath = hopsRoot.resolve(
      hopsConfig.buildDir,
      'manifest.json'
    );
    if (fs.existsSync(filepath)) {
      manifestData = require(filepath);
    }
  }
  return manifestData || {};
}

exports.getManifestScript = function () {
  if (!manifestScript) {
    var filename = getRawManifestData()['manifest.js'];
    if (filename) {
      var filepath = hopsRoot.resolve(
        hopsConfig.buildDir,
        filename.replace(/^\/*/, '')
      );
      if (fs.existsSync(filepath)) {
        manifestScript = fs.readFileSync(filepath, 'utf8');
      }
    }
  }
  return manifestScript;
};

exports.getAssetLinks = function () {
  var vjs = 'vendor.js';
  var manifest = getRawManifestData() || {};
  return Object.keys(manifest).sort(function (a, b) {
    return a === vjs ? -1 : b === vjs ? 1 : a < b ? -1 : a > b ? 1 : 0;
  }).reduce(function (assets, key) {
    if (!/^(chunk|manifest).*\.js/.test(key)) {
      if (/\.js$/.test(key)) {
        assets.js.push(manifest[key]);
      }
      if (/\.css$/.test(key)) {
        assets.css.push(manifest[key]);
      }
    }
    return assets;
  }, { js: [], css: [] });
};
<|endoftext|>


<commit_before>const each = require('./each')
const ipset = require('./ipset')
const md5 = require('./md5')
const pick = require('./pick')

module.exports = {
  each,
  ipset,
  md5,
  pick,
}
<commit_msg>export utils<commit_after>exports.ipset = require('./ipset')
exports.pick = require('./pick')
exports.md5 = require('./md5')
exports.arr2keys = require('./arr2keys')
exports.each = require('./each')
exports.ensureUniqueFilename = require('./ensure-unique-filename')
exports.eventReplaceable = require('./event-replaceable')
exports.EventObservable = require('./EventObservable')
exports.getNewAddress = require('./get-new-address')
exports.getPort = require('./get-port')
exports.ipset = require('./ipset')
exports.isIPLarger = require('./is-ip-larger')
<|endoftext|>


<commit_before>var exports = module.exports;

exports.views = {
	iso: {
		map: function(iso) {
			objGet = function(obj, propName, defVal) {
				propParts = propName.split(".");
				if (!obj || propParts.length == 0) { return defVal; }
				for (var i = 0; i < propParts.length; i++) {
					thisProp = propParts[i];
					if (obj.hasOwnProperty(thisProp)) {
						obj = obj[thisProp];
						if (i == propParts.length -1) { return obj; }
					} else {
						return defVal;
					}
				}
			};

			doc = {
				setProperty: function(propName, value) {
					obj = this;
					propParts = propName.split(".");
					for (var i = 0; i < propParts.length; i++) {
						thisProp = propParts[i];
						if (obj.hasOwnProperty(thisProp)) {
							obj = obj[thisProp];
						} else {
							if (i == propParts.length - 1) { obj[thisProp] = value; }
							else {
								obj[thisProp] = {};
								obj = obj[thisProp];
							}
						}
					}
				}
			};

			// Find the appropriate identification info -- if there are multiple, the first is used.
			ident = objGet(iso, "gmd:MD_Metadata.gmd:identificationInfo", {});
			ident = objGet(ident, "0", ident);
			ident = objGet(ident, "gmd:MD_DataIdentification", objGet(ident, "gmd:SV_ServiceIdentification", {}));

			// Find title/description
			doc.setProperty("Title", objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:title.gco:CharacterString.$t", "No Title Was Given"));
			doc.setProperty("Description", objGet(ident, "gmd:abstract.gco:CharacterString.$t", "No Description Was Given"));

			// Publication Date
			doc.setProperty("PublicationDate", objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:date.gmd:CI_Date.gmd:date.gco:DateTime.$t", "Publication Date Not Given"));

			// Find Authors
			respParties = objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:citedResponsibleParty", []);
			authors = [];
			for (var p in respParties) {
				thisParty = respParties[p];
				role = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:role.gmd:CI_RoleCode.codeListValue", "");
				if (["originator", "pointOfContact"].indexOf(role) != -1) {
					var author = {};
					author["Name"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:individualName.gco:CharacterString.$t", objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:organisationName.gco:CharacterString.$t", "No Name Was Given"));
					author["ContactInformation"] = {};
					author["ContactInformation"]["Phone"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:phone.gmd:CI_Telephone.gmd:voice.gco:CharacterString.$t", "No Phone Number Was Given");
					author["ContactInformation"]["email"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:Address.gmd:electronicMailAddress.gco:CharacterString.$t", "No email Was Given");
					author["ContactInformation"]["Address"] = {};
					author["ContactInformation"]["Address"]["Street"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:deliveryPoint.gco:CharacterString.$t", "No Street Address Was Given");
					author["ContactInformation"]["Address"]["City"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:city.gco:CharacterString.$t", "No City Was Given");
					author["ContactInformation"]["Address"]["State"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:administrativeArea.gco:CharacterString.$t", "No State Was Given");
					author["ContactInformation"]["Address"]["Zip"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:postalCode.gco:CharacterString.$t", "No Zip Was Given");

					if (author["ContactInformation"]["Phone"] == "No Phone Number Was Given" &&
						author["ContactInformation"]["email"] == "No email Was Given" &&
						author["ContactInformation"]["Address"]["Street"] == "No Street Address Was Given" &&
						author["ContactInformation"]["Address"]["City"] == "No City Was Given" &&
						author["ContactInformation"]["Address"]["State"] == "No State Was Given" &&
						author["ContactInformation"]["Address"]["Zip"] == "No Zip Was Given") { delete author.ContactInformation; }

					authors.push(author);
				}
			}
			doc.setProperty("Authors", authors);

			// Find Keywords
			keywords = [];
			descKeywords = objGet(ident, "gmd:descriptiveKeywords", []);
			for (var d in descKeywords) {
				theseKeywords = descKeywords[d];
				actualKeywords = objGet(theseKeywords, "gmd:MD_Keywords.gmd:keyword", []);
				for (var k in actualKeywords) {
					thisKeyword = objGet(actualKeywords[k], "gco:CharacterString.$t", null);
					if (thisKeyword) { keywords.push(thisKeyword); }
				}
			}
			doc.Keywords = keywords;

			// Extent Information
			doc.setProperty("GeographicExtent.NorthBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:northBoundLatitude.gco:Decimal.$t", 89));
			doc.setProperty("GeographicExtent.SouthBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:southBoundLatitude.gco:Decimal.$t", -89));
			doc.setProperty("GeographicExtent.EastBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:eastBoundLongitude.gco:Decimal.$t", 179));
			doc.setProperty("GeographicExtent.WestBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:westBoundLongitude.gco:Decimal.$t", -179));

			// Distribution -- Get distributors as a list
			isoDistributors = objGet(iso, "gmd:MD_Metadata.gmd:distributionInfo.gmd:MD_Distribution.gmd:distributor", []);
			if (isoDistributors.hasOwnProperty("gmd:MD_Distributor")) { isoDistributors = [ isoDistributors ]; }
			distributors = [], links = {};
			for (var iDist in isoDistributors) {
				thisDist = objGet(isoDistributors[iDist], "gmd:MD_Distributor.gmd:distributorContact", {}); newDist = {};
				newDist["Name"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:individualName.gco:CharacterString.$t", objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:organisationName.gco:CharacterString.$t", "No Name Was Given"));
				newDist["ContactInformation"] = {};
				newDist["ContactInformation"]["Phone"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:phone.gmd:CI_Telephone.gmd:voice.gco:CharacterString.$t", "No Phone Number Was Given");
				newDist["ContactInformation"]["email"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:Address.gmd:electronicMailAddress.gco:CharacterString.$t", "No email Was Given");
				newDist["ContactInformation"]["Address"] = {};
				newDist["ContactInformation"]["Address"]["Street"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:deliveryPoint.gco:CharacterString.$t", "No Street Address Was Given");
				newDist["ContactInformation"]["Address"]["City"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:city.gco:CharacterString.$t", "No City Was Given");
				newDist["ContactInformation"]["Address"]["State"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:administrativeArea.gco:CharacterString.$t", "No State Was Given");
				newDist["ContactInformation"]["Address"]["Zip"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:postalCode.gco:CharacterString.$t", "No Zip Was Given");

				if (newDist["ContactInformation"]["Phone"] == "No Phone Number Was Given" &&
					newDist["ContactInformation"]["email"] == "No email Was Given" &&
					newDist["ContactInformation"]["Address"]["Street"] == "No Street Address Was Given" &&
					newDist["ContactInformation"]["Address"]["City"] == "No City Was Given" &&
					newDist["ContactInformation"]["Address"]["State"] == "No State Was Given" &&
					newDist["ContactInformation"]["Address"]["Zip"] == "No Zip Was Given") { delete newDist.ContactInformation; }

				distributors.push(newDist);

				distOption = objGet(isoDistributors[iDist], "gmd:MD_Distributor.gmd:distributorTransferOptions.gmd:MD_DigitalTransferOptions.gmd:onLine.gmd:CI_OnlineResource", null);
				if (distOption) {
					thisLink = {};
					thisLink["Type"] = objGet(distOption, "gmd:description.gco:CharacterString.$t", "Unknown");
					thisLink["URL"] = objGet(distOption, "gmd:linkage.gmd:URL.$t", "No URL Was Given");
					thisLink["Distributor"] = newDist.Name;
					links[thisLink["URL"]] = thisLink;
				}
			}
			doc.Distributors = distributors;

			// Other Distribution Information
			distributions = objGet(iso, "gmd:MD_Metadata.gmd:distributionInfo.gmd:MD_Distribution.gmd:transferOptions", []);
			if (distributions.hasOwnProperty("gmd:MD_DigitalTransferOptions")) { distributions = [ distributions ]; }
			for (var d in distributions) {
				thisDist = objGet(distributions[d], "gmd:MD_DigitalTransferOptions.gmd:onLine.gmd:CI_OnlineResource", {}); thisLink = {};
				thisLink["Type"] = objGet(thisDist, "gmd:description.gco:CharacterString.$t", "Unknown");
				thisLink["URL"] = objGet(thisDist, "gmd:linkage.gmd:URL.$t", "No URL Was Given");
				if (!(thisLink.URL in links)) {
					links[thisLink.URL] = thisLink;
				}
			}

			linksList = [];
			for (l in links) { linksList.push(links[l]); }
			doc.setProperty("Links", linksList);

			// Extra stuff in ISO that should probably be collected:
			doc.setProperty("ResourceIds", []);
			dataSetUri = objGet(iso, "gmd:MD_Metadata.gmd:dataSetURI.gco:CharacterString.$t", null);
			if (dataSetUri) { doc.setProperty("ResourceIds.0", dataSetUri); }

			// Harvest Information
			doc.setProperty("HarvestInformation.OriginalFileIdentifier", objGet(iso, "gmd:MD_Metadata.gmd:fileIdentifier.gco:CharacterString.$t"));
			doc.setProperty("HarvestInformation.OriginalFormat", "iso");

			emit(iso._id, doc);
			//return doc;
		}
	}
};<commit_msg>Adjusments to look for an organization name if personName is 'Missing' and also to deal with keywords where there is only one in a descriptiveKeywords set<commit_after>var exports = module.exports;

exports.views = {
	iso: {
		map: function(iso) {
			objGet = function(obj, propName, defVal) {
				propParts = propName.split(".");
				if (!obj || propParts.length == 0) { return defVal; }
				for (var i = 0; i < propParts.length; i++) {
					thisProp = propParts[i];
					if (obj.hasOwnProperty(thisProp)) {
						obj = obj[thisProp];
						if (i == propParts.length -1) { return obj; }
					} else {
						return defVal;
					}
				}
			};

			doc = {
				setProperty: function(propName, value) {
					obj = this;
					propParts = propName.split(".");
					for (var i = 0; i < propParts.length; i++) {
						thisProp = propParts[i];
						if (obj.hasOwnProperty(thisProp)) {
							obj = obj[thisProp];
						} else {
							if (i == propParts.length - 1) { obj[thisProp] = value; }
							else {
								obj[thisProp] = {};
								obj = obj[thisProp];
							}
						}
					}
				}
			};

			// Find the appropriate identification info -- if there are multiple, the first is used.
			ident = objGet(iso, "gmd:MD_Metadata.gmd:identificationInfo", {});
			ident = objGet(ident, "0", ident);
			ident = objGet(ident, "gmd:MD_DataIdentification", objGet(ident, "gmd:SV_ServiceIdentification", {}));

			// Find title/description
			doc.setProperty("Title", objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:title.gco:CharacterString.$t", "No Title Was Given"));
			doc.setProperty("Description", objGet(ident, "gmd:abstract.gco:CharacterString.$t", "No Description Was Given"));

			// Publication Date
			doc.setProperty("PublicationDate", objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:date.gmd:CI_Date.gmd:date.gco:DateTime.$t", "Publication Date Not Given"));

			// Find Authors
			respParties = objGet(ident, "gmd:citation.gmd:CI_Citation.gmd:citedResponsibleParty", []);
			authors = [];
			for (var p in respParties) {
				thisParty = respParties[p];
				role = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:role.gmd:CI_RoleCode.codeListValue", "");
				if (["originator", "pointOfContact"].indexOf(role) != -1) {
					var author = {};
					author["Name"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:individualName.gco:CharacterString.$t", "");
					if (author["Name"] == "Missing" || author["Name"] == "missing") { author["Name"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:organisationName.gco:CharacterString.$t", "No Name Was Given"); }
					author["ContactInformation"] = {};
					author["ContactInformation"]["Phone"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:phone.gmd:CI_Telephone.gmd:voice.gco:CharacterString.$t", "No Phone Number Was Given");
					author["ContactInformation"]["email"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:Address.gmd:electronicMailAddress.gco:CharacterString.$t", "No email Was Given");
					author["ContactInformation"]["Address"] = {};
					author["ContactInformation"]["Address"]["Street"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:deliveryPoint.gco:CharacterString.$t", "No Street Address Was Given");
					author["ContactInformation"]["Address"]["City"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:city.gco:CharacterString.$t", "No City Was Given");
					author["ContactInformation"]["Address"]["State"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:administrativeArea.gco:CharacterString.$t", "No State Was Given");
					author["ContactInformation"]["Address"]["Zip"] = objGet(thisParty, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:postalCode.gco:CharacterString.$t", "No Zip Was Given");

					if (author["ContactInformation"]["Phone"] == "No Phone Number Was Given" &&
						author["ContactInformation"]["email"] == "No email Was Given" &&
						author["ContactInformation"]["Address"]["Street"] == "No Street Address Was Given" &&
						author["ContactInformation"]["Address"]["City"] == "No City Was Given" &&
						author["ContactInformation"]["Address"]["State"] == "No State Was Given" &&
						author["ContactInformation"]["Address"]["Zip"] == "No Zip Was Given") { delete author.ContactInformation; }

					authors.push(author);
				}
			}
			doc.setProperty("Authors", authors);

			// Find Keywords
			keywords = [];
			descKeywords = objGet(ident, "gmd:descriptiveKeywords", []);
			for (var d in descKeywords) {
				theseKeywords = descKeywords[d];
				actualKeywords = objGet(theseKeywords, "gmd:MD_Keywords.gmd:keyword", []);
				if (actualKeywords.hasOwnProperty("gco:CharacterString")) { actualKeywords = [ actualKeywords ]; }
				for (var k in actualKeywords) {
					thisKeyword = objGet(actualKeywords[k], "gco:CharacterString.$t", null);
					if (thisKeyword) { keywords.push(thisKeyword); }
				}
			}
			doc.Keywords = keywords;

			// Extent Information
			doc.setProperty("GeographicExtent.NorthBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:northBoundLatitude.gco:Decimal.$t", 89));
			doc.setProperty("GeographicExtent.SouthBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:southBoundLatitude.gco:Decimal.$t", -89));
			doc.setProperty("GeographicExtent.EastBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:eastBoundLongitude.gco:Decimal.$t", 179));
			doc.setProperty("GeographicExtent.WestBound", objGet(ident, "gmd:extent.gmd:EX_Extent.gmd:geographicElement.gmd:EX_GeographicBoundingBox.gmd:westBoundLongitude.gco:Decimal.$t", -179));

			// Distribution -- Get distributors as a list
			isoDistributors = objGet(iso, "gmd:MD_Metadata.gmd:distributionInfo.gmd:MD_Distribution.gmd:distributor", []);
			if (isoDistributors.hasOwnProperty("gmd:MD_Distributor")) { isoDistributors = [ isoDistributors ]; }
			distributors = [], links = {};
			for (var iDist in isoDistributors) {
				thisDist = objGet(isoDistributors[iDist], "gmd:MD_Distributor.gmd:distributorContact", {}); newDist = {};
				newDist["Name"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:individualName.gco:CharacterString.$t", "");
				if (newDist["Name"] == "Missing" || newDist["Name"] == "missing") { newDist["Name"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:organisationName.gco:CharacterString.$t", "No Name Was Given"); }
				newDist["ContactInformation"] = {};
				newDist["ContactInformation"]["Phone"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:phone.gmd:CI_Telephone.gmd:voice.gco:CharacterString.$t", "No Phone Number Was Given");
				newDist["ContactInformation"]["email"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:Address.gmd:electronicMailAddress.gco:CharacterString.$t", "No email Was Given");
				newDist["ContactInformation"]["Address"] = {};
				newDist["ContactInformation"]["Address"]["Street"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:deliveryPoint.gco:CharacterString.$t", "No Street Address Was Given");
				newDist["ContactInformation"]["Address"]["City"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:city.gco:CharacterString.$t", "No City Was Given");
				newDist["ContactInformation"]["Address"]["State"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:administrativeArea.gco:CharacterString.$t", "No State Was Given");
				newDist["ContactInformation"]["Address"]["Zip"] = objGet(thisDist, "gmd:CI_ResponsibleParty.gmd:contactInfo.gmd:CI_Contact.gmd:address.gmd:CI_Address.gmd:postalCode.gco:CharacterString.$t", "No Zip Was Given");

				if (newDist["ContactInformation"]["Phone"] == "No Phone Number Was Given" &&
					newDist["ContactInformation"]["email"] == "No email Was Given" &&
					newDist["ContactInformation"]["Address"]["Street"] == "No Street Address Was Given" &&
					newDist["ContactInformation"]["Address"]["City"] == "No City Was Given" &&
					newDist["ContactInformation"]["Address"]["State"] == "No State Was Given" &&
					newDist["ContactInformation"]["Address"]["Zip"] == "No Zip Was Given") { delete newDist.ContactInformation; }

				distributors.push(newDist);

				distOption = objGet(isoDistributors[iDist], "gmd:MD_Distributor.gmd:distributorTransferOptions.gmd:MD_DigitalTransferOptions.gmd:onLine.gmd:CI_OnlineResource", null);
				if (distOption) {
					thisLink = {};
					thisLink["Type"] = objGet(distOption, "gmd:description.gco:CharacterString.$t", "Unknown");
					thisLink["URL"] = objGet(distOption, "gmd:linkage.gmd:URL.$t", "No URL Was Given");
					thisLink["Distributor"] = newDist.Name;
					links[thisLink["URL"]] = thisLink;
				}
			}
			doc.Distributors = distributors;

			// Other Distribution Information
			distributions = objGet(iso, "gmd:MD_Metadata.gmd:distributionInfo.gmd:MD_Distribution.gmd:transferOptions", []);
			if (distributions.hasOwnProperty("gmd:MD_DigitalTransferOptions")) { distributions = [ distributions ]; }
			for (var d in distributions) {
				thisDist = objGet(distributions[d], "gmd:MD_DigitalTransferOptions.gmd:onLine.gmd:CI_OnlineResource", {}); thisLink = {};
				thisLink["Type"] = objGet(thisDist, "gmd:description.gco:CharacterString.$t", "Unknown");
				thisLink["URL"] = objGet(thisDist, "gmd:linkage.gmd:URL.$t", "No URL Was Given");
				if (!(thisLink.URL in links)) {
					links[thisLink.URL] = thisLink;
				}
			}

			linksList = [];
			for (l in links) { linksList.push(links[l]); }
			doc.setProperty("Links", linksList);

			// Extra stuff in ISO that should probably be collected:
			doc.setProperty("ResourceIds", []);
			dataSetUri = objGet(iso, "gmd:MD_Metadata.gmd:dataSetURI.gco:CharacterString.$t", null);
			if (dataSetUri) { doc.setProperty("ResourceIds.0", dataSetUri); }

			// Harvest Information
			doc.setProperty("HarvestInformation.OriginalFileIdentifier", objGet(iso, "gmd:MD_Metadata.gmd:fileIdentifier.gco:CharacterString.$t"));
			doc.setProperty("HarvestInformation.OriginalFormat", "iso");

			emit(iso._id, doc);
			//return doc;
		}
	}
};<|endoftext|>