<commit_before>function escapeHTML(unsafe) {
  if(unsafe == null) return "";
  return unsafe.toString()
   .replace(/&/g, "&")
   .replace(/</g, "<")
   .replace(/>/g, ">")
   .replace(/"/g, """)
   .replace(/'/g, "'");
}

var renderCount = 0;
var elementCount = 0;
var arrayCount = 0;
var objectCount = 0;
var nestingLevel = 0;

function doStats() {
  var out = "<input type='button' id='statst' onclick='showStats();' value='Show Statistics' style='float: right;' />\n"
   + "

\n"
    + "
\n
\n
\nNumber of Arrays:	\n" + arrayCount + "	\n
\n"
    + "
\nNumber of Objects:	\n" + objectCount + "	\n
\n"
     + "
\nTotal number of all elements:	\n" + elementCount + "	\n
\n"
      + "
\nNesting depth:	\n" + nestingLevel + "	\n
\n"
      + "
\n
\n
\n";
  return out;
}

function parse(str) {
  try {
    return JSON.parse(str);
  }
  catch(e) {
    if(e instanceof SyntaxError) {
      alert("There was a syntax error in your JSON string.\n" + e.message + "\nPlease check your syntax and try again.");
    }
    else {
      alert("There was an unknown error. Perhaps the JSON string contained a deep level of nesting.");
    }

    $("#text").focus();
    return;
  }
}

function transform(val, parent, level) {
  if(level > nestingLevel) nestingLevel = level;

  var type = typeof(val);

  if(val == null) return { type: "void", typeLabel: "Void", value: "(null)" };
  if(type == "string") return { type: "string", typeLabel: "String", value: val };
  if(type == "number") return { type: "number", typeLabel: "Number", value: val.toString() };
  if(type == "boolean") return { type: "boolean", typeLabel: "Boolean", value: val.toString() };
  return transformObject(val, parent, level);
}

function transformObject(val, parent, level) {
  var type = (val instanceof Array) ? "array" : "object";

  var props = Object.keys(val);

  var parent = parent + (parent != "" ? " > " : "") + (type == "array" ? "Array" : "Object") + " (" + props.length + " item" + (props.length != 1 ? "s)" : ")");

  var tuples = props.map(function(prop) {
    var tuple = transform(val[prop], parent, level + 1);
    tuple.name = prop;
    return tuple;
  });

  return {
    type: type,
    breadcrumbs: parent,
    tuples: tuples
  };
}

function render(val) {
  elementCount = 0;
  arrayCount = 0;
  objectCount = 0;
  renderCount = 0;

  if(val.type == "array") return renderArray(val);
  if(val.type == "object") return renderObject(val);
  elementCount++;
  return "" + escapeHTML(val.value) + "";
}

function isSimpleTuple(tuple) {
  return tuple.type == "string" || tuple.type == "number" || tuple.type == "boolean" || tuple.type == "void";
}

function renderArray(array) {
  elementCount++;
  arrayCount++;
  renderCount++;
  if(!array.tuples.length) return "(empty Array)";

  var out = "
= 1000 ? " minimised" : "") + "' onmouseover='doFocus(event, this);'>

Array
";
  out += "

Index	Value
";

  for(var i = 0; i < array.tuples.length; i++) {
    var tuple = array.tuples[i];
    out += "

" + escapeHTML(tuple.name) + "
	";
    out += "";

    if(isSimpleTuple(tuple)) {
      elementCount++;
      out += escapeHTML(tuple.value);
    }
    else if(tuple.type == "array") {
      out += renderArray(tuple);
    }
    else if(tuple.type == "object") {
      out += renderObject(tuple);
    }
    out += "
";
  }

  out += "

";
  return out;
}

function renderObject(object) {
  elementCount++;
  objectCount++;
  renderCount++;
  if(!object.tuples.length) return "(empty Object)";

  var out = "
= 1000 ? " minimised" : "") + "' onmouseover='doFocus(event, this);'>

Object
";
  out += "

Name	Value
";

  for(var i = 0; i < object.tuples.length; i++) {
    var tuple = object.tuples[i];
    out += "

" + escapeHTML(tuple.name) + "
	";
    out += "";

    if(isSimpleTuple(tuple)) {
      elementCount++;
      out += escapeHTML(tuple.value);
    }
    else if(tuple.type == "array") {
      out += renderArray(tuple);
    }
    else if(tuple.type == "object") {
      out += renderObject(tuple);
    }
    out += "
";
  }

  out += "

";
  return out;
}

function json2html(str) {
  var tree = parse(str);
  if(!tree) return;
  nestingLevel = 0;
  var transformedTree = transform(tree, "", 1);
  var result = render(transformedTree);
  $("#output").innerHTML = result;

  $("#stats").innerHTML = doStats();
  $("#stats").className = "";

  //doTooltips();

  $("#submit").value = "json 2 html";
  $("#submit").disabled = null;

  $("#output").scrollIntoView();
}

function doParse() {
  $("#submit").value = "processing...";
  $("#submit").disabled = "disabled";

  setTimeout(doParse2, 50);
}

function doParse2() {
  var value = $("#text").value;
  if(value.substr(0, 4) == "http" || value.substr(0, 4) == "file" || value.substr(0, 3) == "ftp") {
    getURL(value);
  }
  else {
    json2html(value);
  }
}

function getURL(str) {
  var http = new XMLHttpRequest();
  http.open("get", "get.php?url=" + str);
  http.onreadystatechange = function() {
    if(http.readyState == 4) json2html(http.responseText);
  };
  http.send(null);
}

function showStats() {
  if($("#statscon").style.display != "block") {
    $("#statscon").style.display = "block";
    $("#stats").className = "statson";
    $("#statst").value = "Hide Statistics";
  }
  else {
    $("#statscon").style.display = "none";
    $("#stats").className = "";
    $("#statst").value = "Show Statistics";
  }
}

var currentlyFocused = null;
function doFocus(event, ele) {
  //if(currentlyFocused != null) currentlyFocused.style.border = "1px solid #000000";
  //ele.style.border = "1px solid #ffa000";

  currentlyFocused = ele;

  if(!event) event = window.event;
  event.cancelBubble = true;
  if(event.stopPropagation) event.stopPropagation();
}

function stopFocus() {
  //if(currentlyFocused != null) currentlyFocused.style.border = "1px solid #000000";
}

//code from Painfully Obvious.
//based on code from quirksmode.org
var Client = {
  viewportWidth: function() {
  return self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth);
  },

  viewportHeight: function() {
   return self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight);
  },

  viewportSize: function() {
   return { width: this.viewportWidth(), height: this.viewportHeight() };
  }
};

function doHelp() {
  $("#help-content").style.display = "block";
  bodySize = Client.viewportSize();

  $("#backdrop").style.display = "block";

  $("#help-content").style.left = ((bodySize.width / 2) - ($("#help-content").offsetWidth / 2)) + "px";
  $("#help-content").style.top = ((bodySize.height / 2) - ($("#help-content").offsetHeight / 2)) + "px";
  $("body").scrollIntoView();
}

function hideHelp() {
  $("#help-content").style.display = "none";
  $("#backdrop").style.display = "none";
  $("#text").focus();
}

function clearPage() {
  $("#stats").innerHTML = "";
  $("#output").innerHTML = "";
}

function load() {
  window.$ = document.querySelector.bind(document);

  document.body.addEventListener("click", function(event) {
    if(event.target.matches(".widget")) {
      event.preventDefault();
      event.target.parentNode.classList.toggle("minimised");
    }
  });

  enableTooltips();

  bodySize = Client.viewportSize();

  if($("#text").focus) $("#text").focus();
}

window.onload = load;<commit_msg>Refactor<commit_after>function escapeHTML(unsafe) {
  if(unsafe == null) return "";
  return unsafe.toString()
   .replace(/&/g, "&")
   .replace(/</g, "<")
   .replace(/>/g, ">")
   .replace(/"/g, """)
   .replace(/'/g, "'");
}

var renderCount = 0;
var elementCount = 0;
var arrayCount = 0;
var objectCount = 0;
var nestingLevel = 0;

function doStats() {
  var out = "<input type='button' id='statst' onclick='showStats();' value='Show Statistics' style='float: right;' />\n"
   + "

\n"
    + "
\n
\n
\nNumber of Arrays:	\n" + arrayCount + "	\n
\n"
    + "
\nNumber of Objects:	\n" + objectCount + "	\n
\n"
     + "
\nTotal number of all elements:	\n" + elementCount + "	\n
\n"
      + "
\nNesting depth:	\n" + nestingLevel + "	\n
\n"
      + "
\n
\n
\n";
  return out;
}

function parse(str) {
  try {
    return JSON.parse(str);
  }
  catch(e) {
    if(e instanceof SyntaxError) {
      alert("There was a syntax error in your JSON string.\n" + e.message + "\nPlease check your syntax and try again.");
    }
    else {
      alert("There was an unknown error. Perhaps the JSON string contained a deep level of nesting.");
    }

    $("#text").focus();
    return;
  }
}

function transform(val, parent, level) {
  if(level > nestingLevel) nestingLevel = level;

  var type = typeof(val);

  if(val == null) return { type: "void", typeLabel: "Void", value: "(null)" };
  if(type == "string") return { type: "string", typeLabel: "String", value: val };
  if(type == "number") return { type: "number", typeLabel: "Number", value: val.toString() };
  if(type == "boolean") return { type: "boolean", typeLabel: "Boolean", value: val.toString() };
  return transformObject(val, parent, level);
}

function transformObject(val, parent, level) {
  var type = (val instanceof Array) ? "array" : "object";

  var props = Object.keys(val);

  var parent = parent + (parent != "" ? " > " : "") + (type == "array" ? "Array" : "Object") + " (" + props.length + " item" + (props.length != 1 ? "s)" : ")");

  var tuples = props.map(function(prop) {
    var tuple = transform(val[prop], parent, level + 1);
    tuple.name = prop;
    return tuple;
  });

  return {
    type: type,
    breadcrumbs: parent,
    tuples: tuples
  };
}

function render(val) {
  elementCount = 0;
  arrayCount = 0;
  objectCount = 0;
  renderCount = 0;

  if(val.type == "array") return renderArray(val);
  if(val.type == "object") return renderObject(val);
  elementCount++;
  return "" + escapeHTML(val.value) + "";
}

function isSimpleTuple(tuple) {
  return tuple.type == "string" || tuple.type == "number" || tuple.type == "boolean" || tuple.type == "void";
}

function renderTuples(tuples) {
  var out = "";

  tuples.forEach(function(tuple) {
    out += "

" + escapeHTML(tuple.name) + "
	";
    out += "";

    if(isSimpleTuple(tuple)) {
      elementCount++;
      out += escapeHTML(tuple.value);
    }
    else if(tuple.type == "array") {
      out += renderArray(tuple);
    }
    else if(tuple.type == "object") {
      out += renderObject(tuple);
    }
    out += "
";
  });

  return out;
}

function renderArray(array) {
  elementCount++;
  arrayCount++;
  renderCount++;
  if(!array.tuples.length) return "(empty Array)";

  var out = "
= 1000 ? " minimised" : "") + "' onmouseover='doFocus(event, this);'>

Array
";
  out += "

Index	Value
";
  out += renderTuples(array.tuples);
  out += "

";
  return out;
}

function renderObject(object) {
  elementCount++;
  objectCount++;
  renderCount++;
  if(!object.tuples.length) return "(empty Object)";

  var out = "
= 1000 ? " minimised" : "") + "' onmouseover='doFocus(event, this);'>

Object
";
  out += "

Name	Value
";
  out += renderTuples(object.tuples);
  out += "

";
  return out;
}

function json2html(str) {
  var tree = parse(str);
  if(!tree) return;
  nestingLevel = 0;
  var transformedTree = transform(tree, "", 1);
  var result = render(transformedTree);
  $("#output").innerHTML = result;

  $("#stats").innerHTML = doStats();
  $("#stats").className = "";

  //doTooltips();

  $("#submit").value = "json 2 html";
  $("#submit").disabled = null;

  $("#output").scrollIntoView();
}

function doParse() {
  $("#submit").value = "processing...";
  $("#submit").disabled = "disabled";

  setTimeout(doParse2, 50);
}

function doParse2() {
  var value = $("#text").value;
  if(value.substr(0, 4) == "http" || value.substr(0, 4) == "file" || value.substr(0, 3) == "ftp") {
    getURL(value);
  }
  else {
    json2html(value);
  }
}

function getURL(str) {
  var http = new XMLHttpRequest();
  http.open("get", "get.php?url=" + str);
  http.onreadystatechange = function() {
    if(http.readyState == 4) json2html(http.responseText);
  };
  http.send(null);
}

function showStats() {
  if($("#statscon").style.display != "block") {
    $("#statscon").style.display = "block";
    $("#stats").className = "statson";
    $("#statst").value = "Hide Statistics";
  }
  else {
    $("#statscon").style.display = "none";
    $("#stats").className = "";
    $("#statst").value = "Show Statistics";
  }
}

var currentlyFocused = null;
function doFocus(event, ele) {
  //if(currentlyFocused != null) currentlyFocused.style.border = "1px solid #000000";
  //ele.style.border = "1px solid #ffa000";

  currentlyFocused = ele;

  if(!event) event = window.event;
  event.cancelBubble = true;
  if(event.stopPropagation) event.stopPropagation();
}

function stopFocus() {
  //if(currentlyFocused != null) currentlyFocused.style.border = "1px solid #000000";
}

//code from Painfully Obvious.
//based on code from quirksmode.org
var Client = {
  viewportWidth: function() {
  return self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth);
  },

  viewportHeight: function() {
   return self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight);
  },

  viewportSize: function() {
   return { width: this.viewportWidth(), height: this.viewportHeight() };
  }
};

function doHelp() {
  $("#help-content").style.display = "block";
  bodySize = Client.viewportSize();

  $("#backdrop").style.display = "block";

  $("#help-content").style.left = ((bodySize.width / 2) - ($("#help-content").offsetWidth / 2)) + "px";
  $("#help-content").style.top = ((bodySize.height / 2) - ($("#help-content").offsetHeight / 2)) + "px";
  $("body").scrollIntoView();
}

function hideHelp() {
  $("#help-content").style.display = "none";
  $("#backdrop").style.display = "none";
  $("#text").focus();
}

function clearPage() {
  $("#stats").innerHTML = "";
  $("#output").innerHTML = "";
}

function load() {
  window.$ = document.querySelector.bind(document);

  document.body.addEventListener("click", function(event) {
    if(event.target.matches(".widget")) {
      event.preventDefault();
      event.target.parentNode.classList.toggle("minimised");
    }
  });

  enableTooltips();

  bodySize = Client.viewportSize();

  if($("#text").focus) $("#text").focus();
}

window.onload = load;<|endoftext|>


<commit_before>(function domtModule() {
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
	module.exports = Domt;
} else {
	window.Domt = Domt;
}

Domt.toString = function() {
	return '(' + domtModule.toString() + ')()';
};

Domt.ns = {
	id: 'domt',
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

function Filters(obj) {
	addToFilters(this, obj);
}

Domt.filters = Filters.prototype;

function addToFilters(filters, obj) {
	for (var name in obj) {
		if (typeof obj[name] == "function") filters[name] = obj[name];
	}
	return filters;
}

// Value Filters
Filters.prototype.upper = function(val) {
	if (val == null) return val;
	return (val + "").toUpperCase();
};
Filters.prototype.lower = function(val) {
	if (val == null) return val;
	return (val + "").toLowerCase();
};
Filters.prototype.br = function(val) {
	if (val == null) return val;
	return (val + "").replace(/\n/g, "
");
};
Filters.prototype.text = function(val) {
	if (val == null) return val;
	return escapeText(val);
};
Filters.prototype.esc = function(val) {
	if (val == null) return val;
	return encodeURIComponent(val + "");
};
Filters.prototype.unesc = function(val) {
	if (val == null) return val;
	return decodeURIComponent(val + "");
};
Filters.prototype.json = function(val) {
	return JSON.stringify(val);
};
Filters.prototype.no = function(val) {
	if (val == null) return "";
	else return null;
};
Filters.prototype[''] = function(val) {
	if (val === undefined) return null;
	else return val;
};

// Block Filters
Filters.prototype.invert = function(row, key, info) {
	info.head.parentNode.insertBefore(info.node, info.head.nextSibling);
};

var escaper;
function escapeText(str) {
	if (!escaper) {
		escaper = document.createElement('p');
		escaper.appendChild(document.createTextNode(""));
	}
	escaper.firstChild.nodeValue = str;
	return escaper.innerHTML;
}

function match(re, str) {
	var m = re.exec(str);
	if (m && m.length == 2) return m[1];
}

function newId() {
	var num = Domt.seq;
	if (!num) num = Domt.seq = 1;
	var pref = Domt.ns.id;
	var id;
	while (true) {
		id = pref + num++;
		if (!document.getElementById(id)) break;
	}
	Domt.seq = num;
	return id;
}

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var REPEAT = Domt.ns.repeat, BIND = Domt.ns.bind;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		this.head = node;
		var orig = node[Domt.ns.holder];
		if (orig) {
			this.repeat = orig.repeat;
			this.template = orig.template;
			this.bind = orig.bind;
			this.tail = orig.tail;
			this.id = orig.id;
		} else {
			this.reload();
		}
		node.removeAttribute(REPEAT);
	} else if (node.hasAttribute(REPEAT)) {
		this.id = newId();
		this.template = node;
		this.head = document.createElement("script");
		this.head.setAttribute('tail', this.id);
		this.head.type = "text/template";
		this.repeat = node.getAttribute(REPEAT) || "";
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		node.removeAttribute(REPEAT);
		node.parentNode.insertBefore(this.head, node);
		this.head.text = node.outerHTML;
		this.tail = document.createElement("script");
		this.tail.id = this.id;
		node.parentNode.insertBefore(this.tail, node);
		node.parentNode.removeChild(node);
	} else {
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		this.head = node;
	}
	this.head[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.head;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
	if (this.bind !== undefined) {
		node.setAttribute(Domt.ns.bind, this.bind);
	}
};
Holder.prototype.reload = function() {
	var head = this.head;
	this.tail = document.getElementById(head.getAttribute('tail'));
	var REPEAT = Domt.ns.repeat;
	this.repeat = head.getAttribute(REPEAT) || this.repeat || "";
	this.bind = head.getAttribute(Domt.ns.bind) || this.bind || undefined;
	var doc = document.implementation && document.implementation.createHTMLDocument ?
		document.implementation.createHTMLDocument('') : document;
	var div = doc.createElement('div');
	var html = head.text.replace(/^\s+|\s+$/g, '');
	var tagName = match(/<(\w+)[\s>]/i, html);
	if (tagName) {
		tagName = tagName.toLowerCase();
		if (tagName == "td") {
			html = '

' + html + '

';
		} else if (tagName == "tr") {
			html = '
' + html + '
';
		}
		div.innerHTML = html;
		this.template = div.querySelector(tagName);
	}
	if (!this.template) throw DomtError("problem parsing template\n" + html);
};

function each(obj, fun) {
	if (obj == null) return 0;
	var i, len;
	if (obj.jquery || Object.prototype.toString.call(obj) === '[object Array]') {
		len = obj.length;
		for (i=0; i < len; i++) fun(obj[i], i);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		len = obj.length;
		for (i=0; i < len; i++) fun(obj.item(i), i);
	} else if (obj instanceof Object) {
		var keys = Object.keys(obj);
		len = keys.length;
		var key;
		for (i=0; i < len; i++) {
			key = keys[i];
			fun(obj[key], key);
		}
	}
	return len;
}

Domt.each = each;

function Domt(nodes, options) {
	if (!(this instanceof Domt)) return new Domt(nodes, options);
	if (typeof nodes == "string") {
		nodes = document.querySelectorAll(nodes);
	} else if (nodes && nodes.nodeType) {
		nodes = [nodes];
	}
	if (!nodes || nodes.length == 0) throw DomtError("Domt has no nodes to merge");
	this.filters = new Filters(options);
	this.nodes = nodes;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']*)' + end, "g");
};

Domt.prototype.empty = function() {
	this.merge(undefined, {empty:true});
	return this;
};

Domt.prototype.merge = function(obj, opts) {
	opts = opts || {};
	var filters = addToFilters(this.filters, opts);
	var nodes = opts.node ? [opts.node] : this.nodes;
	var that = this;
	each(nodes, function(node, num) {
		var bound, repeated, h, head, path, len, parentNode;
		var parent = node;
		var REPEAT = Domt.ns.repeat;
		var BIND = Domt.ns.bind;
		var holders = [];
		do {
			h = Holder(node);
			holders.push(h);
			parentNode = h.head.parentNode;
			bound = h.bind ? find(obj, h.bind, undefined, filters, node).val : obj;
			if (h.repeat !== undefined) {
				if (opts.empty) {
					while ((curNode = h.head.nextSibling) && curNode.id != h.tail.id) {
						parentNode.removeChild(curNode);
					}
					// restore holder.template modified by current.value === undefined (see after)
					h.reload();
				}
				var accessor = h.repeat.split('|');
				repeated = find(bound, accessor);
				if (repeated.val === undefined) {
					// merge inside template (that won't be selected because it's now out of the DOM)
					that.merge(bound, {node: h.template});
				} else {
					each(repeated.val, function(val, key) {
						var clone = h.template.cloneNode(true);
						// overwrite obj
						bound[repeated.name] = val;
						that.replace(bound, clone, key);
						bound[repeated.name] = repeated.val;
						var insertNode = true;
						for (var i=1; i < accessor.length; i++) {
							var bfilter = filters[accessor[i]];
							if (!bfilter) continue;
							var maybe = bfilter(val, key, {
								parent: h.head.parentNode,
								filters: filters,
								node: clone,
								scope:bound,
								path: accessor[0],
								head: h.head,
								tail: h.tail
							});
							if (maybe && maybe.nodeType) clone = maybe;
							else if (maybe === false) {
								insertNode = false;
								break;
							}
						}
						if (insertNode && clone.parentNode == null) {
							if (h.head.parentNode != h.tail.parentNode) throw new Error("Head and tail split");
							parentNode.insertBefore(clone, h.tail);
						}
					});
				}
			} else {
				that.replace(bound, node);
			}
		} while ((node = parent.querySelector('[' + REPEAT + '],[' + BIND + ']')));

		len = holders.length;
		for (i=0; i < len; i++) {
			holders[i].close();
		}
	});
	return this;
};

Domt.prototype.replace = function(obj, node, key) {
	var descendants = node.querySelectorAll('*');
	var i = 0;
	var len = descendants.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	var filters = this.filters;
	var willRepeat = {};
	do {
		each(Array.prototype.slice.call(node.attributes, 0), function(att, index) { // iterates over a copy
			if (att.name == Domt.ns.repeat && att.value) {
				willRepeat[att.value.split('|').shift()] = true;
				return;
			}
			var name = match(reBind, att.name);
			if (name == "text" || name == "html") {
				val = node.innerHTML;
			}	else {
				val = att.value;
			}
			var replacements = 0, initial = val;
			if (att.value) initial = att.value;
			if (initial == null) initial = "";
			val = initial.replace(reExpr, function(str, path) {
				var accessor = path.split('|');
				if (willRepeat[accessor[0]]) return;
				var repl = find(obj, accessor, key, filters, node).val;
				if (repl === undefined || repl !== null && typeof repl == "object") return "";
				replacements++;
				if (repl == null) return "";
				else if (name == "text") return escapeText(repl);
				else return repl;
			});
			if (replacements) {
				if (!att.value) att.value = initial;
				if (!name) {
					name = att.name;
					if (key == null) {
						node.setAttribute(Domt.ns.bind + '-' + name, initial);
					}
				}
			} else {
				var accessor = (att.value || "").split('|');
				if (willRepeat[accessor[0]]) return;
				val = find(obj, accessor, key, filters, node).val;
				if (name == "text" && val != null && typeof val != "object") val = escapeText(val);
			}
			if (name) {
				if (replace(node, name, val)) replacements++;
			}
			if (replacements && key != null && name != att.name) {
				node.removeAttribute(att.name);
			}
		});
	} while (i < len && (node = descendants.item(i++)));
};

function replace(node, name, val) {
	if (val === undefined || val !== null && typeof val == "object") return false;
	if (name == "text" || name == "html") node.innerHTML = val == null ? "" : val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
	return true;
}

function find(scope, accessor, key, filters, node) {
	var name, last, val = scope, prev = scope, filter;
	if (!accessor) accessor = [];
	else if (typeof accessor == "string") accessor = accessor.split('|');
	var path = accessor[0];
	if (scope == null) {
		if (path) val = undefined;
		return {val: val};
	}
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	var first = true;
	for (var index = 0; index < path.length; index++) {
		name = path[index];
		prev = val;
		if (key !== undefined && path.length == index + 1) {
			if (name == '#key') {
				val = key;
				break;
			} else if (name == '#val') {
				break;
			}
		}
		if (!prev || name == "" && !(typeof prev == "object")) break;
		val = prev[name];
		if (first) {
			first = false;
			if (val === undefined) return {val: val};
		}
		if (typeof val == "function") val = val(prev, path);
		last = name;
	}
	if (filters) for (var i=1; i < accessor.length; i++) {
		filter = filters[accessor[i]];
		if (filter) val = filter(val, {node: node, filters: filters, scope:scope, index:index-1, path:path, name: last});
	}
	if (last == null) last = "";
	return {name: last, val: val};
}

function DomtError(message) {
	var error = new Error(message);
	error.name = arguments.callee.name;
	return error;
}

})();
<commit_msg>Import foreign node<commit_after>(function domtModule() {
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
	module.exports = Domt;
} else {
	window.Domt = Domt;
}

Domt.toString = function() {
	return '(' + domtModule.toString() + ')()';
};

Domt.ns = {
	id: 'domt',
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

function Filters(obj) {
	addToFilters(this, obj);
}

Domt.filters = Filters.prototype;

function addToFilters(filters, obj) {
	for (var name in obj) {
		if (typeof obj[name] == "function") filters[name] = obj[name];
	}
	return filters;
}

// Value Filters
Filters.prototype.upper = function(val) {
	if (val == null) return val;
	return (val + "").toUpperCase();
};
Filters.prototype.lower = function(val) {
	if (val == null) return val;
	return (val + "").toLowerCase();
};
Filters.prototype.br = function(val) {
	if (val == null) return val;
	return (val + "").replace(/\n/g, "
");
};
Filters.prototype.text = function(val) {
	if (val == null) return val;
	return escapeText(val);
};
Filters.prototype.esc = function(val) {
	if (val == null) return val;
	return encodeURIComponent(val + "");
};
Filters.prototype.unesc = function(val) {
	if (val == null) return val;
	return decodeURIComponent(val + "");
};
Filters.prototype.json = function(val) {
	return JSON.stringify(val);
};
Filters.prototype.no = function(val) {
	if (val == null) return "";
	else return null;
};
Filters.prototype[''] = function(val) {
	if (val === undefined) return null;
	else return val;
};

// Block Filters
Filters.prototype.invert = function(row, key, info) {
	info.head.parentNode.insertBefore(info.node, info.head.nextSibling);
};

var escaper;
function escapeText(str) {
	if (!escaper) {
		escaper = document.createElement('p');
		escaper.appendChild(document.createTextNode(""));
	}
	escaper.firstChild.nodeValue = str;
	return escaper.innerHTML;
}

function match(re, str) {
	var m = re.exec(str);
	if (m && m.length == 2) return m[1];
}

function newId() {
	var num = Domt.seq;
	if (!num) num = Domt.seq = 1;
	var pref = Domt.ns.id;
	var id;
	while (true) {
		id = pref + num++;
		if (!document.getElementById(id)) break;
	}
	Domt.seq = num;
	return id;
}

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var REPEAT = Domt.ns.repeat, BIND = Domt.ns.bind;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		this.head = node;
		var orig = node[Domt.ns.holder];
		if (orig) {
			this.repeat = orig.repeat;
			this.template = orig.template;
			if (this.template && this.template.ownerDocument != document && document.importNode) {
				this.template = document.importNode(this.template, true);
			}
			this.bind = orig.bind;
			this.tail = orig.tail;
			this.id = orig.id;
		} else {
			this.reload();
		}
		node.removeAttribute(REPEAT);
	} else if (node.hasAttribute(REPEAT)) {
		this.id = newId();
		this.template = node;
		this.head = document.createElement("script");
		this.head.setAttribute('tail', this.id);
		this.head.type = "text/template";
		this.repeat = node.getAttribute(REPEAT) || "";
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		node.removeAttribute(REPEAT);
		node.parentNode.insertBefore(this.head, node);
		this.head.text = node.outerHTML;
		this.tail = document.createElement("script");
		this.tail.id = this.id;
		node.parentNode.insertBefore(this.tail, node);
		node.parentNode.removeChild(node);
	} else {
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		this.head = node;
	}
	this.head[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.head;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
	if (this.bind !== undefined) {
		node.setAttribute(Domt.ns.bind, this.bind);
	}
};
Holder.prototype.reload = function() {
	var head = this.head;
	this.tail = document.getElementById(head.getAttribute('tail'));
	var REPEAT = Domt.ns.repeat;
	this.repeat = head.getAttribute(REPEAT) || this.repeat || "";
	this.bind = head.getAttribute(Domt.ns.bind) || this.bind || undefined;
	var doc = document.implementation && document.implementation.createHTMLDocument ?
		document.implementation.createHTMLDocument('') : document;
	var div = doc.createElement('div');
	var html = head.text.replace(/^\s+|\s+$/g, '');
	var tagName = match(/<(\w+)[\s>]/i, html);
	if (tagName) {
		tagName = tagName.toLowerCase();
		if (tagName == "td") {
			html = '

' + html + '

';
		} else if (tagName == "tr") {
			html = '
' + html + '
';
		}
		div.innerHTML = html;
		this.template = div.querySelector(tagName);
	}
	if (!this.template) throw DomtError("problem parsing template\n" + html);
};

function each(obj, fun) {
	if (obj == null) return 0;
	var i, len;
	if (obj.jquery || Object.prototype.toString.call(obj) === '[object Array]') {
		len = obj.length;
		for (i=0; i < len; i++) fun(obj[i], i);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		len = obj.length;
		for (i=0; i < len; i++) fun(obj.item(i), i);
	} else if (obj instanceof Object) {
		var keys = Object.keys(obj);
		len = keys.length;
		var key;
		for (i=0; i < len; i++) {
			key = keys[i];
			fun(obj[key], key);
		}
	}
	return len;
}

Domt.each = each;

function Domt(nodes, options) {
	if (!(this instanceof Domt)) return new Domt(nodes, options);
	if (typeof nodes == "string") {
		nodes = document.querySelectorAll(nodes);
	} else if (nodes && nodes.nodeType) {
		nodes = [nodes];
	}
	if (!nodes || nodes.length == 0) throw DomtError("Domt has no nodes to merge");
	this.filters = new Filters(options);
	this.nodes = nodes;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']*)' + end, "g");
};

Domt.prototype.empty = function() {
	this.merge(undefined, {empty:true});
	return this;
};

Domt.prototype.merge = function(obj, opts) {
	opts = opts || {};
	var filters = addToFilters(this.filters, opts);
	var nodes = opts.node ? [opts.node] : this.nodes;
	var that = this;
	each(nodes, function(node, num) {
		var bound, repeated, h, head, path, len, parentNode;
		var parent = node;
		var REPEAT = Domt.ns.repeat;
		var BIND = Domt.ns.bind;
		var holders = [];
		do {
			h = Holder(node);
			holders.push(h);
			parentNode = h.head.parentNode;
			bound = h.bind ? find(obj, h.bind, undefined, filters, node).val : obj;
			if (h.repeat !== undefined) {
				if (opts.empty) {
					while ((curNode = h.head.nextSibling) && curNode.id != h.tail.id) {
						parentNode.removeChild(curNode);
					}
					// restore holder.template modified by current.value === undefined (see after)
					h.reload();
				}
				var accessor = h.repeat.split('|');
				repeated = find(bound, accessor);
				if (repeated.val === undefined) {
					// merge inside template (that won't be selected because it's now out of the DOM)
					that.merge(bound, {node: h.template});
				} else {
					each(repeated.val, function(val, key) {
						var clone = h.template.cloneNode(true);
						// overwrite obj
						bound[repeated.name] = val;
						that.replace(bound, clone, key);
						bound[repeated.name] = repeated.val;
						var insertNode = true;
						for (var i=1; i < accessor.length; i++) {
							var bfilter = filters[accessor[i]];
							if (!bfilter) continue;
							var maybe = bfilter(val, key, {
								parent: h.head.parentNode,
								filters: filters,
								node: clone,
								scope:bound,
								path: accessor[0],
								head: h.head,
								tail: h.tail
							});
							if (maybe && maybe.nodeType) clone = maybe;
							else if (maybe === false) {
								insertNode = false;
								break;
							}
						}
						if (insertNode && clone.parentNode == null) {
							if (h.head.parentNode != h.tail.parentNode) throw new Error("Head and tail split");
							parentNode.insertBefore(clone, h.tail);
						}
					});
				}
			} else {
				that.replace(bound, node);
			}
		} while ((node = parent.querySelector('[' + REPEAT + '],[' + BIND + ']')));

		len = holders.length;
		for (i=0; i < len; i++) {
			holders[i].close();
		}
	});
	return this;
};

Domt.prototype.replace = function(obj, node, key) {
	var descendants = node.querySelectorAll('*');
	var i = 0;
	var len = descendants.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	var filters = this.filters;
	var willRepeat = {};
	do {
		each(Array.prototype.slice.call(node.attributes, 0), function(att, index) { // iterates over a copy
			if (att.name == Domt.ns.repeat && att.value) {
				willRepeat[att.value.split('|').shift()] = true;
				return;
			}
			var name = match(reBind, att.name);
			if (name == "text" || name == "html") {
				val = node.innerHTML;
			}	else {
				val = att.value;
			}
			var replacements = 0, initial = val;
			if (att.value) initial = att.value;
			if (initial == null) initial = "";
			val = initial.replace(reExpr, function(str, path) {
				var accessor = path.split('|');
				if (willRepeat[accessor[0]]) return;
				var repl = find(obj, accessor, key, filters, node).val;
				if (repl === undefined || repl !== null && typeof repl == "object") return "";
				replacements++;
				if (repl == null) return "";
				else if (name == "text") return escapeText(repl);
				else return repl;
			});
			if (replacements) {
				if (!att.value) att.value = initial;
				if (!name) {
					name = att.name;
					if (key == null) {
						node.setAttribute(Domt.ns.bind + '-' + name, initial);
					}
				}
			} else {
				var accessor = (att.value || "").split('|');
				if (willRepeat[accessor[0]]) return;
				val = find(obj, accessor, key, filters, node).val;
				if (name == "text" && val != null && typeof val != "object") val = escapeText(val);
			}
			if (name) {
				if (replace(node, name, val)) replacements++;
			}
			if (replacements && key != null && name != att.name) {
				node.removeAttribute(att.name);
			}
		});
	} while (i < len && (node = descendants.item(i++)));
};

function replace(node, name, val) {
	if (val === undefined || val !== null && typeof val == "object") return false;
	if (name == "text" || name == "html") node.innerHTML = val == null ? "" : val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
	return true;
}

function find(scope, accessor, key, filters, node) {
	var name, last, val = scope, prev = scope, filter;
	if (!accessor) accessor = [];
	else if (typeof accessor == "string") accessor = accessor.split('|');
	var path = accessor[0];
	if (scope == null) {
		if (path) val = undefined;
		return {val: val};
	}
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	var first = true;
	for (var index = 0; index < path.length; index++) {
		name = path[index];
		prev = val;
		if (key !== undefined && path.length == index + 1) {
			if (name == '#key') {
				val = key;
				break;
			} else if (name == '#val') {
				break;
			}
		}
		if (!prev || name == "" && !(typeof prev == "object")) break;
		val = prev[name];
		if (first) {
			first = false;
			if (val === undefined) return {val: val};
		}
		if (typeof val == "function") val = val(prev, path);
		last = name;
	}
	if (filters) for (var i=1; i < accessor.length; i++) {
		filter = filters[accessor[i]];
		if (filter) val = filter(val, {node: node, filters: filters, scope:scope, index:index-1, path:path, name: last});
	}
	if (last == null) last = "";
	return {name: last, val: val};
}

function DomtError(message) {
	var error = new Error(message);
	error.name = arguments.callee.name;
	return error;
}

})();
<|endoftext|>


<commit_before>var sentence="";
/*sentence+=" #Rhizibot is showing you a #tutorial|";
sentence+="#Rhizi visualizes data with #Graphs and #relationships|";
sentence+="#links and #nodes have #context and #meaning|";

sentence+="#entities and #concepts are #nodes|";
sentence+="We built this entire graph in 30 seconds, try it out yourself!";*/

sentence+=' #Hi, this is #Rhizibot!|';
sentence+='#Rhizi is a tool for creating interactive #Networks|';
sentence+='With #Rhizi your #Text becomes a #Network"|';
sentence+='Use the #hashtag(#) before a word to create it as #Node|';
sentence+='#Hello|';
sentence+='#John|';
sentence+='Use #commas("") if what you want to write #"multiple words" as a #Node|';
sentence+='#"John Smith"|';
sentence+='#"Beauty and the beast"|';
sentence+='a #Node is connected to all other #Nodes in the #sentence|';
sentence+='#John is a friend of #Tim|';
sentence+='#"Beauty and the beast" is film by #Disney|';
sentence+='Use the word #"and" to #"connect multiple things together"|';
sentence+='#John likes #Apples and #Oranges and #Pistachio|';
sentence+='You can choose the node type by using #"right arrow" or #"left arrow|"';
sentence+='#Rhizi is useful for #"Mapping ideas" and "#"Creating info graphics" and #"Organising knowledge"|';
sentence+="#You can click on any #Node to change and modify it's #Properties|";
sentence+='#Play around and have #Fun!|';

var robot = function (sentence) {
    var r = {
        speed: 1,
        counter: 0,
        sentence: sentence,
        sentencecounter: 0,
        element: element || $('#textanalyser')};
    r.next_event = function () {
        if(r.counter <= r.sentence.length) {
            var text = r.element.val();
            r.counter++;
            if (r.sentence.charAt(r.counter) !== "|") {
                r.element.val(text + r.sentence.charAt(r.counter));
                //if(Math.random()>0.9)graph.editType("x","temp",nodetypes[Math.round(Math.random()*4)]);
                if (r.sentence.charAt(r.counter)==="#") {
                  r.sentencecounter++;
                  r.timeout_id = window.setTimeout( r.next_event, 30/r.speed+Math.random()*160/r.speed );
                } else {
                  r.timeout_id = window.setTimeout( r.next_event, 50/r.speed+Math.round(Math.random()*100/r.speed) );
                }
            } else {
                var e = jQuery.Event("keypress");
                e.which = 13;
                e.keyCode = 13;
                $("#textanalyser").trigger(e);
                window.setTimeout( r.next_event, 650/r.speed );
            }
        } else {
            window.clearInterval(r.timeout_id);
        }
    }
    return r;
}

$('.logo').click(function(){
    setTimeout( robot(sentence).next_event, 1000 );
});

/*var answer = confirm ("Would you like a tutorial?")
if (answer)
setTimeout( Robot, 100 );*/
<commit_msg>Improved tutorial<commit_after>var sentence="";
/*sentence+=" #Rhizibot is showing you a #tutorial|";
sentence+="#Rhizi visualizes data with #Graphs and #relationships|";
sentence+="#links and #nodes have #context and #meaning|";

sentence+="#entities and #concepts are #nodes|";
sentence+="We built this entire graph in 30 seconds, try it out yourself!";*/

sentence+='##Rhizi is a tool for creating interactive #Networks|';
sentence+='Create #Networks by writing #Sentences|';
sentence+='like a #Tweet you can put a #Hashtag in your #Sentences|';
sentence+='#Hello|';
sentence+='#John|';
sentence+='Put your text between #Commas to use #"Multiple words"|';
sentence+='#"John Smith"|';
sentence+='#"Beauty and the beast"|';
sentence+='Use the word #And to #"Connect multiple things together"|';
sentence+='#John likes #Apples and #Oranges and #Pistachio|';
//sentence+='Choose the #"node type" by using the #"TAB key"|';
sentence+='#Click on any #Node to change and modify it|';
sentence+='#Play around and have #Fun!|';

var robot = function (sentence) {
    var r = {
        speed: 1,
        counter: 0,
        sentence: sentence,
        sentencecounter: 0,
        element: element || $('#textanalyser')};
    r.next_event = function () {
        if(r.counter <= r.sentence.length) {
            var text = r.element.val();
            r.counter++;
            if (r.sentence.charAt(r.counter) !== "|") {
                r.element.val(text + r.sentence.charAt(r.counter));
                //if(Math.random()>0.9)graph.editType("x","temp",nodetypes[Math.round(Math.random()*4)]);
                if (r.sentence.charAt(r.counter)==="#") {
                  r.sentencecounter++;
                  r.timeout_id = window.setTimeout( r.next_event, 30/r.speed+Math.random()*160/r.speed );
                } else {
                  r.timeout_id = window.setTimeout( r.next_event, 50/r.speed+Math.round(Math.random()*100/r.speed) );
                }
            } else {
                var e = jQuery.Event("keypress");
                e.which = 13;
                e.keyCode = 13;
                $("#textanalyser").trigger(e);
                window.setTimeout( r.next_event, 650/r.speed );
            }
        } else {
            window.clearInterval(r.timeout_id);
        }
    }
    return r;
}

$('.logo').click(function(){
    setTimeout( robot(sentence).next_event, 1000 );
});

/*var answer = confirm ("Would you like a tutorial?")
if (answer)
setTimeout( Robot, 100 );*/
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define(function() {

  var g_colors = [
    [1.0, 0.0, 0.0],
    [1.0, 1.0, 0.0],
    [0.0, 1.0, 0.0],
    [0.0, 1.0, 1.0],
    [0.0, 0.0, 1.0],
    [1.0, 0.0, 1.0],
    [1.0, 0.5, 0.5],
    [1.0, 1.0, 0.5],
    [0.5, 1.0, 0.5],
    [0.5, 1.0, 1.0],
    [0.5, 0.5, 1.0],
    [1.0, 0.5, 1.0]
  ];
  var g_styles = [
    "drawShip",
    "drawOutlineShip",
    "drawTwoToneShip"
  ];
  var g_darkColors = {
  };
  var g_shipSize = 15;

  return {
    styles: g_styles,

    getTotalColors: function() {
      return g_styles.length * g_colors.length;
    },

    // TODO(gman): if we are going to limit the number
    // of colors and styles then we need to keep track
    // of which ones are used so if a player stops
    // playing his color is free to be used by new
    // players.
    makeColor: function(count) {
      var numStyles = g_styles.length;
      var numColors = g_colors.length;
      var total = numStyles * numColors;
      count = count % total;
      var style = count / numColors | 0;
      var colorNdx = count % numColors;

      //var color = [
      //  (count * 0.31) % 1,
      //  (count * 5.73) % 1,
      //  (count * 7.89) % 1,
      //  1,
      //];
      //var canvasColor = [];
      //var ci = count % 3;
      //for (var ii = 0; ii < 3; ++ii) {
      //  var ndx = (ii + ci) % 3;
      //  var mix = (ii == 0) ? 0.2 : 0.6;
      //  var max = (ii == 0) ? 1 : 0.6;
      //  color[ndx] = color[ndx] * mix + (1 - mix) * max;
      //  canvasColor[ndx] = Math.floor(color[ndx] * 255);
      //}

      var c = g_colors[colorNdx];
      var color = new Float32Array([0,0,0,1]);
      var canvasColor = [];
      for (var ii = 0; ii < 3; ++ii) {
        color[ii] = c[ii];
        canvasColor[ii] = Math.floor(c[ii] * 255);
      }

      return {
          style: style,
          glColor: color,
          canvasColor: "rgb(" + canvasColor.join(",") + ")"
      };
    },

    setShipSize: function(size) {
      g_shipSize = size;
    },

    drawShip: function(ctx, x, y, direction, color) {
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.fillStyle = color;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.fill();
      ctx.restore();
    },

    drawOutlineShip: function(ctx, x, y, direction, color) {
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.strokeStyle = color;
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.stroke();
      ctx.restore();
    },

    drawTwoToneShip: function(ctx, x, y, direction, color, opt_darkColor) {
      if (!opt_darkColor) {
        opt_darkColor = g_darkColors[color];
        if (!opt_darkColor) {
          var m = color.match(/rgb\((\d+),(\d+),(\d+)\)/)
          opt_darkColor = "rgb(" +
              Math.floor(parseInt(m[1]) / 2) + "," +
              Math.floor(parseInt(m[2]) / 2) + "," +
              Math.floor(parseInt(m[3]) / 2) + ")";
          g_darkColors[color] = opt_darkColor;
        }
      }
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.fillStyle = color;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.closePath();
      ctx.fill();
      ctx.fillStyle = opt_darkColor;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.fill();
      ctx.restore();
    }
  };

}());

<commit_msg>make ships.js compatible with almond<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define([], function() {

  var g_colors = [
    [1.0, 0.0, 0.0],
    [1.0, 1.0, 0.0],
    [0.0, 1.0, 0.0],
    [0.0, 1.0, 1.0],
    [0.0, 0.0, 1.0],
    [1.0, 0.0, 1.0],
    [1.0, 0.5, 0.5],
    [1.0, 1.0, 0.5],
    [0.5, 1.0, 0.5],
    [0.5, 1.0, 1.0],
    [0.5, 0.5, 1.0],
    [1.0, 0.5, 1.0]
  ];
  var g_styles = [
    "drawShip",
    "drawOutlineShip",
    "drawTwoToneShip"
  ];
  var g_darkColors = {
  };
  var g_shipSize = 15;

  return {
    styles: g_styles,

    getTotalColors: function() {
      return g_styles.length * g_colors.length;
    },

    // TODO(gman): if we are going to limit the number
    // of colors and styles then we need to keep track
    // of which ones are used so if a player stops
    // playing his color is free to be used by new
    // players.
    makeColor: function(count) {
      var numStyles = g_styles.length;
      var numColors = g_colors.length;
      var total = numStyles * numColors;
      count = count % total;
      var style = count / numColors | 0;
      var colorNdx = count % numColors;

      //var color = [
      //  (count * 0.31) % 1,
      //  (count * 5.73) % 1,
      //  (count * 7.89) % 1,
      //  1,
      //];
      //var canvasColor = [];
      //var ci = count % 3;
      //for (var ii = 0; ii < 3; ++ii) {
      //  var ndx = (ii + ci) % 3;
      //  var mix = (ii == 0) ? 0.2 : 0.6;
      //  var max = (ii == 0) ? 1 : 0.6;
      //  color[ndx] = color[ndx] * mix + (1 - mix) * max;
      //  canvasColor[ndx] = Math.floor(color[ndx] * 255);
      //}

      var c = g_colors[colorNdx];
      var color = new Float32Array([0,0,0,1]);
      var canvasColor = [];
      for (var ii = 0; ii < 3; ++ii) {
        color[ii] = c[ii];
        canvasColor[ii] = Math.floor(c[ii] * 255);
      }

      return {
          style: style,
          glColor: color,
          canvasColor: "rgb(" + canvasColor.join(",") + ")"
      };
    },

    setShipSize: function(size) {
      g_shipSize = size;
    },

    drawShip: function(ctx, x, y, direction, color) {
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.fillStyle = color;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.fill();
      ctx.restore();
    },

    drawOutlineShip: function(ctx, x, y, direction, color) {
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.strokeStyle = color;
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.stroke();
      ctx.restore();
    },

    drawTwoToneShip: function(ctx, x, y, direction, color, opt_darkColor) {
      if (!opt_darkColor) {
        opt_darkColor = g_darkColors[color];
        if (!opt_darkColor) {
          var m = color.match(/rgb\((\d+),(\d+),(\d+)\)/)
          opt_darkColor = "rgb(" +
              Math.floor(parseInt(m[1]) / 2) + "," +
              Math.floor(parseInt(m[2]) / 2) + "," +
              Math.floor(parseInt(m[3]) / 2) + ")";
          g_darkColors[color] = opt_darkColor;
        }
      }
      ctx.save();
      ctx.translate(x, y);
      ctx.rotate(direction);
      ctx.fillStyle = color;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(g_shipSize, -g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.closePath();
      ctx.fill();
      ctx.fillStyle = opt_darkColor;
      ctx.beginPath();
      ctx.moveTo(0, g_shipSize);
      ctx.lineTo(0, -g_shipSize * 2 / 3);
      ctx.lineTo(-g_shipSize, -g_shipSize);
      ctx.closePath();
      ctx.fill();
      ctx.restore();
    }
  };

}());

<|endoftext|>


<commit_before>
function createEdit(graph) {
  var self = {};

  var NODE_SPACING = 40;

  function getText(id) {
    return document.getElementById(id).value;
  }

  function getInteger(id) {
    return Math.floor(parseInt(document.getElementById(id).value, 10));
  }

  function getFloat(id) {
    return parseInt(document.getElementById(id).value, 10);
  }

  function getBoolean(id) {
    return document.getElementById(id).checked;
  }

  function readFileContent(id, callback) {
    var file = document.getElementById(id).files[0];
    if (file) {
      var r = new FileReader();
      r.onload = function(e) {
        callback(e.target.result);
      }
      r.readAsText(file);
    }
  }

  self.changeLinkQuality = function changeLinkQuality(type_id, value_id) {
    var type = getText(type_id);
    var value = getFloat(value_id);

    graph.getSelectedIntLinks().forEach(function(e) {
      if (type == 'random') {
        e.quality = 100 * Math.random();
      } else {
        e.quality = value;
      }
    });
    graph.redraw();
  }

  self.changeLinkBandwidth = function changeLinkBandwidth(value_id) {
    var value = getFloat(value_id);

    graph.getSelectedIntLinks().forEach(function(e) {
      e.bandwidth = value;
    });
    graph.redraw();
  }

  self.addSingle = function addSingle () {
    graph.addElements([{}], []);
  }

  self.addLine = function addLine (count, loop) {
    var nodes = [];
    var links = [];

    count = getInteger(count);
    loop = getBoolean(loop);
    if (count < 1 || isNaN(count)) {
      return;
    }

    for (var i = 0; i < count; i++) {
      nodes.push({x: (i * NODE_SPACING), y: 0});
      if (i > 0) {
        var source = nodes[i - 1];
        var target = nodes[i];
        links.push({source: source, target: target});
      }
    }

    if (loop && (count > 2)) {
      var source = nodes[0];
      var target = nodes[count - 1];
      links.push({source: source, target: target});
    }

    graph.addElements(nodes, links);
  }

  self.addStar = function addStar(count) {
    var nodes = [];
    var links = [];

    count = getInteger(count);
    if (count < 1 || isNaN(count)) {
      return;
    }

    nodes.push({x: 0, y: 0});

    for (var i = 0; i < count; i++) {
      var a = i * 2 * Math.PI / count;
      var x = NODE_SPACING * Math.cos(a);
      var y = NODE_SPACING * Math.sin(a);
      nodes.push({x: x, y: y});

      var source = nodes[0];
      var target = nodes[nodes.length - 1];
      links.push({source: source, target: target});
    }

    graph.addElements(nodes, links);
  }

  /*
  self.addLayer = function addLayer(x_count, y_count) {
    var nodes = [];
    var links = [];

    x_count = getInteger(x_count);
    y_count = getInteger(y_count);

    if (x_count < 1 || y_count < 1 || isNaN(x_count) || isNaN(y_count)) {
      return;
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < y_count; y++) {
        nodes.push({x: (x * NODE_SPACING), y: (y * NODE_SPACING * 0.8)});
        if (x > 0) {
          for (var ny = 0; ny < y_count; ny++) {
            var source = nodes[(x - 1) * y_count + ny];
            var target = nodes[nodes.length - 1];
            links.push({source: source, target: target});
          }
        }
      }
    }

    graph.addElements(nodes, links);
  }
  */

  self.addLattice = function addLattice(x_count, y_count) {
    var nodes = [];
    var links = [];

    x_count = getInteger(x_count);
    y_count = getInteger(y_count);

    if (x_count < 1 || y_count < 1 || isNaN(x_count) || isNaN(y_count)) {
      return;
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < y_count; y++) {
        nodes.push({x: (x * NODE_SPACING), y: (y * NODE_SPACING)});
      }
    }

    for (var x = 0; x < (x_count - 1); x++) {
      for (var y = 0; y < y_count; y++) {
        var source = nodes[x * y_count + y];
        var target = nodes[(x + 1) * y_count + y];
        links.push({source: source, target: target});
      }
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < (y_count - 1); y++) {
        var source = nodes[x * y_count + y];
        var target = nodes[x * y_count + (y + 1)];
        links.push({source: source, target: target});
      }
    }

    graph.addElements(nodes, links);
  }

  // Copy elements from 'from' to 'to' object, if elements
  // are in the same place of the structure of scheme
  function applyByScheme(from, to, scheme) {
    var path = [];
    function copy(from, scheme) {
      if (typeof scheme === 'object') {
        if (typeof from === 'object') {
          for (key in scheme) {
            if (key in from) {
              path.push(key);
              copy(from[key], scheme[key]);
              path.pop();
            }
          }
        }
      } else if ((typeof scheme === typeof from)) {
        var o = to;
        for (var i = 0; i < (path.length - 1); i++) {
          if (!(path[i] in o)) {
            var e = {};
            o[path[i]] = e;
            o = e;
          }
        }
        o[path[path.length - 1]] = from;
      }
    }

    copy(from, scheme);
    return to;
  }

  self.saveMeshViewerData = function saveMeshViewerData() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    var nodesDataNodes = [];
    var graphDataNodes = [];
    var graphDataLinks = [];

    var nodesScheme = {
      firstseen: '',
      flags: {gateway: false,  online: false },
      lastseen: '',
      nodeinfo: {
        hardware: { model: '' },
        hostname: '',
        location: {
          latitude: 0,
          longitude: 0
        },
        network: { mac: '' },
        node_id: '',
        owner: { contact: '' },
        software: { firmware: { release: '' } },
        system: { role: '', site_code: '' }
      },
      statistics: {
        clients: 0,
        memory_usage: 0,
        rootfs_usage: 0,
        uptime: 0
      }
    }

    intNodes.forEach(function(e) {
      //var o = applyByScheme(e.o.meta, {}, nodesScheme);

      nodesDataNodes.push(e.o);
      graphDataNodes.push({
        id: e.o.mac,
        node_id: e.o.mac.replace(/:/g, '')
      });
    });

    intLinks.forEach(function(e) {
      graphDataLinks.push({
        bidirect: true,
        source: e.source.index,
        target: e.target.index,
        tq: (100 / e.quality),
        vpn: (e.bandwidth > 50)
      });
    });

    var graph_json = {
      batadv: {
        directed: false,
        graph: [],
        multigraph: false,
        nodes: graphDataNodes,
        links: graphDataLinks
      },
      version: 1
    };

    var nodes_json = {
      meta: {
        timestamp: Date.now().format('DD.MM.Y HH:mm')
      },
      nodes: [],
      version: 2
    };
    // TODO: write files here
  }

  self.loadMeshViewerData = function loadMeshViewerData(graph_id, nodes_id) {
    readFileContent(graph_id, function(graph_content) {
      readFileContent(nodes_id, function(nodes_content) {
        var graphData = JSON.parse(graph_content);
        var nodesData = JSON.parse(nodes_content);

        if (typeof graphData !== 'object' || typeof nodesData !== 'object') {
          return;
        }

        var nodeDict = {};
        var graphDataNodes = graphData.batadv.nodes;
        var graphDataLinks = graphData.batadv.links;
        var nodesDataNodes = nodesData.nodes;
        var nodes = [];
        var links = [];

        nodesDataNodes.forEach(function(e) {
          var mac = e.nodeinfo.network.mac;
          var node = new Node(mac);
          node.name = e.nodeinfo.hostname;
          node.clients = e.statistics.clients;
          nodeDict[mac] = {o: node};
        });

        graphDataNodes.forEach(function(e) {
          var mac = e.id;
          if (!(mac in nodeDict)) {
            nodeDict[mac] = {o: new Node(mac)};
          }
        });

        graphDataLinks.map(function(e) {
          var sid = graphDataNodes[e.source].id;
          var tid = graphDataNodes[e.target].id;
          links.push({
            source: nodeDict[sid],
            target: nodeDict[tid],
            quality: (100 / e.tq),
            bandwidth: (e.vpn ? 80 : 20)
          });
        });

        nodes = Object.values(nodeDict);
        addElements(nodes, links);
      });
    });
  }

  return self;
}<commit_msg>fix assignment<commit_after>
function createEdit(graph) {
  var self = {};

  var NODE_SPACING = 40;

  function getText(id) {
    return document.getElementById(id).value;
  }

  function getInteger(id) {
    return Math.floor(parseInt(document.getElementById(id).value, 10));
  }

  function getFloat(id) {
    return parseInt(document.getElementById(id).value, 10);
  }

  function getBoolean(id) {
    return document.getElementById(id).checked;
  }

  function readFileContent(id, callback) {
    var file = document.getElementById(id).files[0];
    if (file) {
      var r = new FileReader();
      r.onload = function(e) {
        callback(e.target.result);
      }
      r.readAsText(file);
    }
  }

  self.changeLinkQuality = function changeLinkQuality(type_id, value_id) {
    var type = getText(type_id);
    var value = getFloat(value_id);

    graph.getSelectedIntLinks().forEach(function(e) {
      if (type == 'random') {
        e.quality = 100 * Math.random();
      } else {
        e.quality = value;
      }
    });
    graph.redraw();
  }

  self.changeLinkBandwidth = function changeLinkBandwidth(value_id) {
    var value = getFloat(value_id);

    graph.getSelectedIntLinks().forEach(function(e) {
      e.bandwidth = value;
    });
    graph.redraw();
  }

  self.addSingle = function addSingle () {
    graph.addElements([{}], []);
  }

  self.addLine = function addLine (count, loop) {
    var nodes = [];
    var links = [];

    count = getInteger(count);
    loop = getBoolean(loop);
    if (count < 1 || isNaN(count)) {
      return;
    }

    for (var i = 0; i < count; i++) {
      nodes.push({x: (i * NODE_SPACING), y: 0});
      if (i > 0) {
        var source = nodes[i - 1];
        var target = nodes[i];
        links.push({source: source, target: target});
      }
    }

    if (loop && (count > 2)) {
      var source = nodes[0];
      var target = nodes[count - 1];
      links.push({source: source, target: target});
    }

    graph.addElements(nodes, links);
  }

  self.addStar = function addStar(count) {
    var nodes = [];
    var links = [];

    count = getInteger(count);
    if (count < 1 || isNaN(count)) {
      return;
    }

    nodes.push({x: 0, y: 0});

    for (var i = 0; i < count; i++) {
      var a = i * 2 * Math.PI / count;
      var x = NODE_SPACING * Math.cos(a);
      var y = NODE_SPACING * Math.sin(a);
      nodes.push({x: x, y: y});

      var source = nodes[0];
      var target = nodes[nodes.length - 1];
      links.push({source: source, target: target});
    }

    graph.addElements(nodes, links);
  }

  /*
  self.addLayer = function addLayer(x_count, y_count) {
    var nodes = [];
    var links = [];

    x_count = getInteger(x_count);
    y_count = getInteger(y_count);

    if (x_count < 1 || y_count < 1 || isNaN(x_count) || isNaN(y_count)) {
      return;
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < y_count; y++) {
        nodes.push({x: (x * NODE_SPACING), y: (y * NODE_SPACING * 0.8)});
        if (x > 0) {
          for (var ny = 0; ny < y_count; ny++) {
            var source = nodes[(x - 1) * y_count + ny];
            var target = nodes[nodes.length - 1];
            links.push({source: source, target: target});
          }
        }
      }
    }

    graph.addElements(nodes, links);
  }
  */

  self.addLattice = function addLattice(x_count, y_count) {
    var nodes = [];
    var links = [];

    x_count = getInteger(x_count);
    y_count = getInteger(y_count);

    if (x_count < 1 || y_count < 1 || isNaN(x_count) || isNaN(y_count)) {
      return;
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < y_count; y++) {
        nodes.push({x: (x * NODE_SPACING), y: (y * NODE_SPACING)});
      }
    }

    for (var x = 0; x < (x_count - 1); x++) {
      for (var y = 0; y < y_count; y++) {
        var source = nodes[x * y_count + y];
        var target = nodes[(x + 1) * y_count + y];
        links.push({source: source, target: target});
      }
    }

    for (var x = 0; x < x_count; x++) {
      for (var y = 0; y < (y_count - 1); y++) {
        var source = nodes[x * y_count + y];
        var target = nodes[x * y_count + (y + 1)];
        links.push({source: source, target: target});
      }
    }

    graph.addElements(nodes, links);
  }

  // Copy elements from 'from' to 'to' object, if elements
  // are in the same place of the structure of scheme
  function applyByScheme(from, to, scheme) {
    var path = [];
    function copy(from, scheme) {
      if (typeof scheme === 'object') {
        if (typeof from === 'object') {
          for (key in scheme) {
            if (key in from) {
              path.push(key);
              copy(from[key], scheme[key]);
              path.pop();
            }
          }
        }
      } else if ((typeof scheme === typeof from)) {
        var o = to;
        for (var i = 0; i < (path.length - 1); i++) {
          if (!(path[i] in o)) {
            var e = {};
            o[path[i]] = e;
            o = e;
          }
        }
        o[path[path.length - 1]] = from;
      }
    }

    copy(from, scheme);
    return to;
  }

  self.saveMeshViewerData = function saveMeshViewerData() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    var nodesDataNodes = [];
    var graphDataNodes = [];
    var graphDataLinks = [];

    var nodesScheme = {
      firstseen: '',
      flags: {gateway: false,  online: false },
      lastseen: '',
      nodeinfo: {
        hardware: { model: '' },
        hostname: '',
        location: {
          latitude: 0,
          longitude: 0
        },
        network: { mac: '' },
        node_id: '',
        owner: { contact: '' },
        software: { firmware: { release: '' } },
        system: { role: '', site_code: '' }
      },
      statistics: {
        clients: 0,
        memory_usage: 0,
        rootfs_usage: 0,
        uptime: 0
      }
    }

    intNodes.forEach(function(e) {
      //var o = applyByScheme(e.o.meta, {}, nodesScheme);

      nodesDataNodes.push(e.o);
      graphDataNodes.push({
        id: e.o.mac,
        node_id: e.o.mac.replace(/:/g, '')
      });
    });

    intLinks.forEach(function(e) {
      graphDataLinks.push({
        bidirect: true,
        source: e.source.index,
        target: e.target.index,
        tq: (100 / e.quality),
        vpn: (e.bandwidth > 50)
      });
    });

    var graph_json = {
      batadv: {
        directed: false,
        graph: [],
        multigraph: false,
        nodes: graphDataNodes,
        links: graphDataLinks
      },
      version: 1
    };

    var nodes_json = {
      meta: {
        timestamp: Date.now().format('DD.MM.Y HH:mm')
      },
      nodes: [],
      version: 2
    };
    // TODO: write files here
  }

  self.loadMeshViewerData = function loadMeshViewerData(graph_id, nodes_id) {
    readFileContent(graph_id, function(graph_content) {
      readFileContent(nodes_id, function(nodes_content) {
        var graphData = JSON.parse(graph_content);
        var nodesData = JSON.parse(nodes_content);

        if (typeof graphData !== 'object' || typeof nodesData !== 'object') {
          return;
        }

        var nodeDict = {};
        var graphDataNodes = graphData.batadv.nodes;
        var graphDataLinks = graphData.batadv.links;
        var nodesDataNodes = nodesData.nodes;
        var nodes = [];
        var links = [];

        nodesDataNodes.forEach(function(e) {
          var mac = e.nodeinfo.network.mac;
          var node = new Node(mac);
          node.name = e.nodeinfo.hostname;
          node.clientCount = e.statistics.clients;
          nodeDict[mac] = {o: node};
        });

        graphDataNodes.forEach(function(e) {
          var mac = e.id;
          if (!(mac in nodeDict)) {
            nodeDict[mac] = {o: new Node(mac)};
          }
        });

        graphDataLinks.map(function(e) {
          var sid = graphDataNodes[e.source].id;
          var tid = graphDataNodes[e.target].id;
          links.push({
            source: nodeDict[sid],
            target: nodeDict[tid],
            quality: (100 / e.tq),
            bandwidth: (e.vpn ? 80 : 20)
          });
        });

        nodes = Object.values(nodeDict);
        addElements(nodes, links);
      });
    });
  }

  return self;
}<|endoftext|>


<commit_before>'use strict';

const webpack = require('webpack');
const spawn = require('cross-spawn');
const path = require('path');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const express = require('express');
const httpProxy = require('http-proxy');
const config = require('../config/webpack.client.dev');
const serverConfig = require('../config/webpack.server.dev');

const app = express();

const compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  hot: true,
  stats: 'minimal',
}));

app.use(webpackHotMiddleware(compiler));

// since the devserver config uses style-loader, we don't want to serve the
// extracted main.css, and without this line the browser hangs when asking the
// dev server for main.css & never times out
app.get('/assets/main.css', (req, res) => {
  res.status(404).send('not found');
});

const APP_PORT = process.env.APP_PORT || 3232;

// proxy everything to app server except webpack output
const proxy = httpProxy.createProxyServer();
app.all('*', (req, res) => {
  if (!new RegExp(`^${config.output.publicPath}`).test(req.path)) {
    proxy.web(req, res, { target: `http://localhost:${APP_PORT}` }, () => {
      res.send(`<!doctype html>

`);
    });
  } else {
    res.sendStatus(404);
  }
});

const PORT = process.env.PORT || 3233;

app.listen(PORT, (err) => {
  if (err) {
    return console.error(err);
  }
  return console.log(`Dev server is listening on port ${PORT} and proxying to app server`);
});

const serverCompiler = webpack(Object.assign({}, serverConfig));
const serverPath = path.resolve('build/server.js');

let child;

function startServer() {
  child = spawn('node', [serverPath], { stdio: 'inherit' });
  child.on('close', code => {
    console.log('EXIT', code);
    child = null;
  });
}

function restartServer() {
  if (child) {
    child.on('close', () => startServer());
    child.kill();
  } else {
    startServer();
  }
}

console.log('Compiling server build... this will take a while...');
serverCompiler.watch({ poll: 1000 }, (err, stats) => {
  if (err) {
    console.error(err.message || err);
  }
  if (stats.hasErrors()) {
    console.log(stats.toString('errors-only'));
  } else {
    console.log('Starting new server...');
    restartServer();
  }
});

// relay compiler

const relayCompiler = spawn(
  path.resolve(__dirname, '../node_modules/.bin/relay-compiler'),
  [
    '--src',
    path.resolve('.'),

    '--include',
    'src/**',
    'node_modules/eyrie/lib/**',

    '--exclude',
    '**/__generated__/**',
    'node_modules/eyrie/node_mobules/**',

    '--schema',
    'schema.graphql',

    '--watch',
  ],
  { stdio: 'inherit' }
);

relayCompiler.on('close', code => process.exit(code));
<commit_msg>point relay schema to json (fixes issue with incompatible graphql schema syntax)<commit_after>'use strict';

const webpack = require('webpack');
const spawn = require('cross-spawn');
const path = require('path');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const express = require('express');
const httpProxy = require('http-proxy');
const config = require('../config/webpack.client.dev');
const serverConfig = require('../config/webpack.server.dev');

const app = express();

const compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  hot: true,
  stats: 'minimal',
}));

app.use(webpackHotMiddleware(compiler));

// since the devserver config uses style-loader, we don't want to serve the
// extracted main.css, and without this line the browser hangs when asking the
// dev server for main.css & never times out
app.get('/assets/main.css', (req, res) => {
  res.status(404).send('not found');
});

const APP_PORT = process.env.APP_PORT || 3232;

// proxy everything to app server except webpack output
const proxy = httpProxy.createProxyServer();
app.all('*', (req, res) => {
  if (!new RegExp(`^${config.output.publicPath}`).test(req.path)) {
    proxy.web(req, res, { target: `http://localhost:${APP_PORT}` }, () => {
      res.send(`<!doctype html>

`);
    });
  } else {
    res.sendStatus(404);
  }
});

const PORT = process.env.PORT || 3233;

app.listen(PORT, (err) => {
  if (err) {
    return console.error(err);
  }
  return console.log(`Dev server is listening on port ${PORT} and proxying to app server`);
});

const serverCompiler = webpack(Object.assign({}, serverConfig));
const serverPath = path.resolve('build/server.js');

let child;

function startServer() {
  child = spawn('node', [serverPath], { stdio: 'inherit' });
  child.on('close', code => {
    console.log('EXIT', code);
    child = null;
  });
}

function restartServer() {
  if (child) {
    child.on('close', () => startServer());
    child.kill();
  } else {
    startServer();
  }
}

console.log('Compiling server build... this will take a while...');
serverCompiler.watch({ poll: 1000 }, (err, stats) => {
  if (err) {
    console.error(err.message || err);
  }
  if (stats.hasErrors()) {
    console.log(stats.toString('errors-only'));
  } else {
    console.log('Starting new server...');
    restartServer();
  }
});

// relay compiler

const relayCompiler = spawn(
  path.resolve(__dirname, '../node_modules/.bin/relay-compiler'),
  [
    '--src',
    path.resolve('.'),

    '--include',
    'src/**',
    'node_modules/eyrie/lib/**',

    '--exclude',
    '**/__generated__/**',
    'node_modules/eyrie/node_mobules/**',

    '--schema',
    'schema.json',

    '--watch',
  ],
  { stdio: 'inherit' }
);

relayCompiler.on('close', code => process.exit(code));
<|endoftext|>


<commit_before>// (c) 2012 Richard Carter
// This code is licensed under the MIT license; see LICENSE.txt for details.

// This script handles the following functions:
//     some url - look up the url's title and announce it

var entities = require('./lib/entities'),
    fs = require('fs'),
    exec = require('child_process').exec;

var db = require('./lib/listdb').getDB('links');

var request = require('request').defaults({
    strictSSL: false,
    timeout: 10000,
    encoding: 'utf8',
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36'
    }
});

function dbHasValue(link) {
    return db.hasValue(link, true);
}

listen(/PRIVMSG [^ ]+ :.*?\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?]))/i, function(match, data, replyTo, from) {
    var url = match[1];

    if (from === 'NURDbot') return;

    if(url.indexOf('http') != 0) {
        url = 'http://' + url;
    }

    // /me fix
    console.log(url.charCodeAt(url.length-1))
    if (url.charCodeAt(url.length-1) === 1) {
      url = url.slice(0,-1)
    }
    console.log(url.charCodeAt(url.length-1))

    console.log('title: Found url: "' + url + '"');

    if (!dbHasValue(url)) {
        db.add(url);
    }

    var maxSize = 10485760;

    request({url: url, method: 'HEAD'}, function (error, headRes) {
        if (error) {
            if((""+error).indexOf('SSL routines') < 0) {
                irc.privmsg(replyTo, "Error looking up URL: " + error);
            }
            return;
        }

        var size = headRes.headers['content-length'];
        if (size && size > maxSize) {
            irc.privmsg(replyTo, "size: " + Math.floor(size/1024/1024) + " MB");
            console.log('Page size too large: ' + size);
            return;
        }

        var req = request({url: url});
        req.on('error', function (error) {
            if((""+error).indexOf('SSL routines') < 0) {
                irc.privmsg(replyTo, "Error looking up URL(2): " + error);
            }
        });
        var hostname = "";
        req.on('response', function (response) {
            hostname = response.request.host;

            var statusCode = response.statusCode;
            if (statusCode != 200) {
                req.abort();
                // Ignore 403 Access Forbidden; some websites block bots with this
                // code (e.g. Wikipedia).
                if (statusCode != 403) {
                    irc.privmsg(replyTo, "" + response.statusCode);
                }
            }
        });

        var pageBody = "", foundTitle = false;
        req.on('data', function (data) {
            if (foundTitle) {
                return;
            }
            pageBody += data;
            if (pageBody.length > maxSize) {
                console.log('Page size exceeded limit (' + pageBody.length + ')');
                req.abort();
            }

            var titleMatch = /<title(?: [^>]+)?>([^<]+)<\/title>/i.exec(pageBody);

            if(titleMatch && titleMatch[1]) {
                req.abort();
                foundTitle = true;

                var title = titleMatch[1];

                // replace multi-spaces/newlines with spaces
                title = title.replace(/\s{2,}/g, " ");

                // trim front and back
                title = title.replace(/^\s+/, "");
                title = title.replace(/\s+$/, "");
                title = title.replace(/\r?\n|\r/gm, "");

                // decode HTML entities
                title = entities.decode(title);

                irc.privmsg(replyTo, hostname + ": " + title, false);
                // irc.privmsg(replyTo, "^ " + title, false);
            }
        });

    });

});
<commit_msg>title fix<commit_after>// (c) 2012 Richard Carter
// This code is licensed under the MIT license; see LICENSE.txt for details.

// This script handles the following functions:
//     some url - look up the url's title and announce it

var entities = require('./lib/entities'),
    fs = require('fs'),
    exec = require('child_process').exec;

var db = require('./lib/listdb').getDB('links');

var request = require('request').defaults({
    strictSSL: false,
    timeout: 10000,
    encoding: 'utf8',
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36'
    }
});

function dbHasValue(link) {
    return db.hasValue(link, true);
}

listen(/PRIVMSG [^ ]+ :.*?\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?]))/i, function(match, data, replyTo, from) {
    var url = match[1];

    if (from === 'NURDbot') return;

    if(url.indexOf('http') != 0) {
        url = 'http://' + url;
    }

    // /me fix
    if (url.charCodeAt(url.length-1) === 1) {
      url = url.slice(0,-1)
    }
    console.log('title: Found url: "' + url + '"');

    if (!dbHasValue(url)) {
        db.add(url);
    }

    var maxSize = 10485760;

    request({url: url, method: 'HEAD'}, function (error, headRes) {
        if (error) {
            if((""+error).indexOf('SSL routines') < 0) {
                irc.privmsg(replyTo, "Error looking up URL: " + error);
            }
            return;
        }

        var size = headRes.headers['content-length'];
        if (size && size > maxSize) {
            irc.privmsg(replyTo, "size: " + Math.floor(size/1024/1024) + " MB");
            console.log('Page size too large: ' + size);
            return;
        }

        var req = request({url: url});
        req.on('error', function (error) {
            if((""+error).indexOf('SSL routines') < 0) {
                irc.privmsg(replyTo, "Error looking up URL(2): " + error);
            }
        });
        var hostname = "";
        req.on('response', function (response) {
            hostname = response.request.host;

            var statusCode = response.statusCode;
            if (statusCode != 200) {
                req.abort();
                // Ignore 403 Access Forbidden; some websites block bots with this
                // code (e.g. Wikipedia).
                if (statusCode != 403) {
                    irc.privmsg(replyTo, "" + response.statusCode);
                }
            }
        });

        var pageBody = "", foundTitle = false;
        req.on('data', function (data) {
            if (foundTitle) {
                return;
            }
            pageBody += data;
            if (pageBody.length > maxSize) {
                console.log('Page size exceeded limit (' + pageBody.length + ')');
                req.abort();
            }

            var titleMatch = /<title(?: [^>]+)?>([^<]+)<\/title>/i.exec(pageBody);

            if(titleMatch && titleMatch[1]) {
                req.abort();
                foundTitle = true;

                var title = titleMatch[1];

                // replace multi-spaces/newlines with spaces
                title = title.replace(/\s{2,}/g, " ");

                // trim front and back
                title = title.replace(/^\s+/, "");
                title = title.replace(/\s+$/, "");
                title = title.replace(/\r?\n|\r/gm, "");

                // decode HTML entities
                title = entities.decode(title);

                irc.privmsg(replyTo, hostname + ": " + title, false);
                // irc.privmsg(replyTo, "^ " + title, false);
            }
        });

    });

});
<|endoftext|>


<commit_before>// scrollTrigger.js

;(function($) {

  $.fn.scrollTrigger = function(options) {

    var settings = $.extend({
          offset: 60,
          target: this
        }, options),
        el = this;

    var activate = function() {

      el.each(function(k, v) {
        var sT = $(window).scrollTop(),
            wH = $(window).height();

        if(settings.target != el) {
          if(sT > $(el[0]).offset().top - wH + settings.offset) {
            $(settings.target).addClass('active');
          } else {
            $(settings.target).removeClass('active');
          }
        } else {
          if(sT > $(v).offset().top - wH + settings.offset) {
            $(v).addClass('active');
          } else {
            $(v).removeClass('active');
          }
        }

      });

    };

    var didScroll = false;
    $(window).scroll(function() {
      didScroll = true;
    });
    setInterval(function() {
      if(didScroll) {
        activate();
        didScroll = false;
      }
    }, 250);

  };

}(jQuery));
<commit_msg>Add property active to settings object<commit_after>// scrollTrigger.js

;(function($) {

  $.fn.scrollTrigger = function(options) {

    var settings = $.extend({
          offset: 60,
          target: this,
          active: 'scrolltrig--active'
        }, options),
        el = this;

    var activate = function() {

      el.each(function(k, v) {
        var sT = $(window).scrollTop(),
            wH = $(window).height();

        if(settings.target != el) {
          if(sT > $(el[0]).offset().top - wH + settings.offset) {
            $(settings.target).addClass(settings.active);
          } else {
            $(settings.target).removeClass(settings.active);
          }
        } else {
          if(sT > $(v).offset().top - wH + settings.offset) {
            $(v).addClass(settings.active);
          } else {
            $(v).removeClass(settings.active);
          }
        }

      });

    };

    var didScroll = false;
    $(window).scroll(function() {
      didScroll = true;
    });
    setInterval(function() {
      if(didScroll) {
        activate();
        didScroll = false;
      }
    }, 250);

  };

}(jQuery));
<|endoftext|>