<commit_before>// ==UserScript==
// @name           Idrinth's DotD Script
// @description    A userscript for the game Dawn of the Dragons which provides multiple useful tools, like time-saving raid catching, private chatrooms and much more to discover, see the manual at https://idotd.github.io/
// @author         Idrinth
// @version        2.3.1
// @grant          none
// @hompage        https://dotd.idrinth.de
// @include        http://www.kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        https://www.kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        http://www.kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        https://www.kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        http://kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        https://kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        http://kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        https://kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        http://www.dawnofthedragons.com/game*
// @include        http://www.dawnofthedragons.com/
// @include        http://www.dawnofthedragons.com
// @include        http://dawnofthedragons.com/game*
// @include        http://www.newgrounds.com/portal/view/609826*
// @include        http://newgrounds.com/portal/view/609826*
// @include        http://dawnofthedragons.com/
// @include        http://armorgames.com/dawn-of-the-dragons-game/13509*
// @include        http://www.armorgames.com/dawn-of-the-dragons-game/13509*
// @include        http://web1.dawnofthedragons.com/*
// @include        http://50.18.191.15/*
// @include        https://web1.dawnofthedragons.com/*
// @include        https://50.18.191.15/*
// @include        https://dotd-web1.5thplanetgames.com/*
// ==/UserScript==
(function() {
  if (
    window.location.host === "50.18.191.15" ||
    window.location.host === "web1.dawnofthedragons.com" ||
    window.location.host === "dotd-web1.5thplanetgames.com"
  ) {
    window.idrinth = {};
    window.idrinth.add = function(data) {
      var s = document.createElement("script");
      s.appendChild(document.createTextNode(data));
      document.getElementsByTagName("head")[0].appendChild(s);
    };
    window.addEventListener(
      "message",
      function(event) {
        try {
          var data = JSON.parse(event.data);
          if (
            data.to !== "idotd" ||
            !window.idrinth.hasOwnProperty(data.task) ||
            !data.data
          ) {
            return;
          }
          window.idrinth[data.task](data.data);
        } catch (e) {
          //nothing
        }
      },
      false
    );
    return;
  }
  var sc = document.createElement("script");
  sc.setAttribute(
    "src",
    "https://dotd.idrinth.de/static/userscript/" + GM_info.script.version + "/"
  );
  sc.setAttribute("id", "idotd-loader");
  sc.setAttribute("async", "async");
  sc.errorCounter = 0;
  sc.errorFunction = function() {
    var self = document.getElementById("idotd-loader");
    self.parentNode.removeChild(self);
    var sc = document.createElement("script");
    sc.onerror = self.onerror;
    sc.errorCounter = self.errorCounter + 1;
    sc.errorFunction = self.errorFunction;
    sc.setAttribute("id", "idotd-loader");
    sc.setAttribute("async", "async");
    sc.setAttribute(
      "src",
      (self.getAttribute("src") + "").replace(/(userscript\/.*?\/).*$/, "$1") +
        Math.random() +
        "/"
    );
    document.getElementsByTagName("head")[0].appendChild(sc);
  };
  sc.onerror = function() {
    console.log(
      "Failed loading IDotD, retry in " +
        (500 + 100 * this.errorCounter * this.errorCounter) / 1000 +
        "sec."
    );
    window.setTimeout(
      this.errorFunction,
      500 + 100 * this.errorCounter * this.errorCounter
    );
  };
  document.getElementsByTagName("head")[0].appendChild(sc);
})();
<commit_msg>hopefully fixing loader in FF<commit_after>// ==UserScript==
// @name           Idrinth's DotD Script
// @description    A userscript for the game Dawn of the Dragons which provides multiple useful tools, like time-saving raid catching, private chatrooms and much more to discover, see the manual at https://idotd.github.io/
// @author         Idrinth
// @version        2.3.1
// @grant          none
// @hompage        https://dotd.idrinth.de
// @include        http://www.kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        https://www.kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        http://www.kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        https://www.kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        http://kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        https://kongregate.com/games/5thplanetgames/dawn-of-the-dragons*
// @include        http://kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        https://kongregate.com/games/5thPlanetGames/dawn-of-the-dragons*
// @include        http://www.dawnofthedragons.com/game*
// @include        http://www.dawnofthedragons.com/
// @include        http://www.dawnofthedragons.com
// @include        http://dawnofthedragons.com/game*
// @include        http://www.newgrounds.com/portal/view/609826*
// @include        http://newgrounds.com/portal/view/609826*
// @include        http://dawnofthedragons.com/
// @include        http://armorgames.com/dawn-of-the-dragons-game/13509*
// @include        http://www.armorgames.com/dawn-of-the-dragons-game/13509*
// @include        http://web1.dawnofthedragons.com/*
// @include        http://50.18.191.15/*
// @include        https://web1.dawnofthedragons.com/*
// @include        https://50.18.191.15/*
// @include        https://dotd-web1.5thplanetgames.com/*
// ==/UserScript==
(function() {
  if (
    window.location.host === "50.18.191.15" ||
    window.location.host === "web1.dawnofthedragons.com" ||
    window.location.host === "dotd-web1.5thplanetgames.com"
  ) {
    var f = function() {
      console.log("s");
      window.idrinth = {};
      window.idrinth.add= function(data) {
          var s = document.createElement("script");
          s.appendChild(document.createTextNode(data));
          document.getElementsByTagName("head")[0].appendChild(s);
      };
      window.addEventListener(
        "message",
        function(event) {
          try {
            var data = JSON.parse(event.data);
            if (
              !data ||
              data.to !== "idotd" ||
              !window.idrinth.hasOwnProperty(data.task) ||
              !data.data
            ) {
              return;
            }
            window.idrinth[data.task](data.data);
          } catch (e) {
            //nothing
          }
        },
        false
      );
    };
    var sc = document.createElement("script");
    sc.setAttribute("id", "idotd-loader");
    sc.appendChild(document.createTextNode('('+f.toString()+'());'));
    document.getElementsByTagName("head")[0].appendChild(sc);
    return;
  }
  var sc = document.createElement("script");
  sc.setAttribute(
    "src",
    "https://dotd.idrinth.de/static/userscript/" + GM_info.script.version + "/"
  );
  sc.setAttribute("id", "idotd-loader");
  sc.setAttribute("async", "async");
  sc.errorCounter = 0;
  sc.errorFunction = function() {
    var self = document.getElementById("idotd-loader");
    self.parentNode.removeChild(self);
    var sc = document.createElement("script");
    sc.onerror = self.onerror;
    sc.errorCounter = self.errorCounter + 1;
    sc.errorFunction = self.errorFunction;
    sc.setAttribute("id", "idotd-loader");
    sc.setAttribute("async", "async");
    sc.setAttribute(
      "src",
      (self.getAttribute("src") + "").replace(/(userscript\/.*?\/).*$/, "$1") +
        Math.random() +
        "/"
    );
    document.getElementsByTagName("head")[0].appendChild(sc);
  };
  sc.onerror = function() {
    console.log(
      "Failed loading IDotD, retry in " +
        (500 + 100 * this.errorCounter * this.errorCounter) / 1000 +
        "sec."
    );
    window.setTimeout(
      this.errorFunction,
      500 + 100 * this.errorCounter * this.errorCounter
    );
  };
  document.getElementsByTagName("head")[0].appendChild(sc);
})();
<|endoftext|>


<commit_before>UI.Tools = new (function() {
	var that = this;

	var command_history = [];
	var command_history_idx = 0;
	var command_library = CommandLib.load();

	var last_ros_command = undefined;

	Mousetrap.bind("ctrl+space", function() { UI.Tools.toggle(); }, 'keydown');
	Mousetrap.bind("ctrl+space", function() { UI.Tools.evaluate(); }, 'keyup');
	Mousetrap.bind("enter", function() { that.displayCommandInput(); }, 'keyup');
	var mouse = {x: 0, y: 0};
	document.addEventListener('mousemove', function(e){
		mouse.x = e.clientX || e.pageX;
		mouse.y = e.clientY || e.pageY
	}, false);
	var hover_mode = false;
	var closest_button = undefined;

	var id_list = ["dfg", "undo", "redo", "copy", "cut", "paste", "terminal", "save"];

	var hide_timeout = undefined;

	var getPanel = function() { return document.getElementById("tool_overlay"); }

	var placeButtonsCircular = function(radius, animate) {
		for (var i = 0; i < id_list.length; i++) {
			var d = document.createElement("div");
			d.setAttribute("class", "tool_overlay_button");
			getPanel().appendChild(d);
			var el = document.getElementById("tool_overlay_" + id_list[i]);
			var angle = -225 + i * 45;
			d.setAttribute("style", "transform: rotate(" + angle + "deg) translate(" + radius + "px) rotate(" + -angle + "deg);");
			var bb = d.getBoundingClientRect();
			var p = el.parentNode;
			el.setAttribute("style", "top: " + (bb.top - parseInt(p.style.top)) + "px; left: " + (bb.left - parseInt(p.style.left)) + "px;"
							+ (animate? "transition: all 0.2s ease;" : ""));
			p.removeChild(d);
		}
	}

	var getClosestButton = function() {
		var panel = getPanel();
		var angle = Math.atan2((mouse.y - (parseInt(panel.style.top) + 50)), (mouse.x - (parseInt(panel.style.left) + 50)));
		angle = angle * 180 / Math.PI;
		var snapped_angle = Math.round(angle / 45) * 45;
		var angle_index = (snapped_angle + 225) / 45;
		angle_index = angle_index % 8;
		return document.getElementById("tool_overlay_" + id_list[angle_index]);
	}

	var createHistoryContent = function() {
		var activities = ActivityTracer.getActivityList();
		var current = ActivityTracer.getCurrentIndex();
		var save = ActivityTracer.getLastSaveIndex();
		var changes = ActivityTracer.hasUnsavedChanges();

		var info = document.getElementById("history_info");
		info.innerHTML = "" + Behavior.getBehaviorName() + "

";
		if (!changes) {
			info.innerHTML += "Last saved: no changes
";
		} else if (save == 0) {
			info.innerHTML += "Last saved: never
";
		} else {
			var savetime = Math.round((Date.now() - activities[save].time) / 60000);
			info.innerHTML += "Last saved: " + savetime + " min ago
";
		}

		var list = document.getElementById("history_list");
		list.innerHTML = "";
		for (var i = activities.length - 1; i >= 0; i--) {
			var a = (i > 0)? activities[i] : {description: "no changes"};
			var entry = document.createElement("div");
			entry.setAttribute("class", "history_element");
			entry.innerHTML = ((i == current)? "> " : "") + ((i == save)? "# " : "") + a.description;
			list.appendChild(entry);

			var addListener = function(index) {
				entry.addEventListener('click', function() {
					ActivityTracer.goToIndex(index);
					createHistoryContent();
				});
			};
			addListener(i);
		}
	}

	this.printAvailableCommands = function() {
		T.clearLog();
		T.show();
		T.logInfo("The following commands are available:");
		command_library.forEach(function(c) {
			T.logInfo(c.desc + ' - ' + c.text + '');
		});
	}

	this.display = function() {
		if (RC.Controller.isReadonly()) return;

		if (hide_timeout != undefined) clearTimeout(hide_timeout);
		var panel = getPanel();

		var position_top = Math.min(Math.max(mouse.y - 50, 120), window.innerHeight - 210);
		var position_left = Math.min(Math.max(mouse.x - 50, 120), window.innerWidth - 210);

		panel.style.display = "block";
		panel.style.top = position_top + "px";
		panel.style.left = position_left + "px";
		placeButtonsCircular(300, false);

		setTimeout(function() {
			placeButtonsCircular(120, true);
			panel.style.opacity = "1";
		}, 10);
	}

	this.hide = function() {
		getPanel().style.opacity = "0";
		hide_timeout = setTimeout(function() {
			getPanel().style.display = "none";
			document.getElementById("command_overlay").style.display = "none";
		}, 200);
		placeButtonsCircular(300, true);

		document.getElementById("tool_input_command").blur();
		document.getElementById("tool_input_command").value = "";

		document.getElementById("history_overlay").style.left = "-295px";
		document.getElementById("command_overlay").style.bottom = "0px";
		document.getElementById("command_overlay").style.opacity = "0";
		document.getElementById("command_overlay_suggestions").style.display = "none";
		document.getElementById("command_overlay_suggestions").style.opacity = "0";
	}

	this.toggle = function() {
		if (RC.Controller.isReadonly()) return;

		var panel = getPanel();
		if (!hover_mode) {
			if (panel.style.display != "block") {
				that.display();
				hover_mode = true;
			} else {
				that.hide();
			}
		} else {
			var mouse_distance = Math.sqrt(Math.pow(mouse.x - (parseInt(panel.style.left) + 50), 2) + Math.pow(mouse.y - (parseInt(panel.style.top) + 50), 2));
			if (mouse_distance > 170) {
				var new_closest_button = getClosestButton();
				if (closest_button != new_closest_button) {
					if (closest_button != undefined)
						closest_button.style.backgroundColor = "";
					closest_button = new_closest_button;
					closest_button.style.backgroundColor = "rgba(0, 0, 0, 0.9)";
				}
			} else {
				if (closest_button != undefined) {
					closest_button.style.backgroundColor = "";
					closest_button = undefined;
				}
			}
		}
	}

	this.evaluate = function() {
		var panel = getPanel();
		if (hover_mode) {
			var will_stay = true;
			hover_mode = false;
			if (closest_button != undefined) {
				will_stay = false;
				closest_button.click();
				closest_button.style.backgroundColor = "";
				closest_button = undefined;
			} else {
				// triggering keydown again the first time is slow, so make sure we dont miss any selection
				var mouse_distance = Math.sqrt(Math.pow(mouse.x - (parseInt(panel.style.left) + 50), 2) + Math.pow(mouse.y - (parseInt(panel.style.top) + 50), 2));
				if (mouse_distance > 170) {
					getClosestButton().click();
					will_stay = false;
				}
			}
			if (will_stay) {
				// display panels

				document.getElementById("history_overlay").style.left = "-15px";
				ActivityTracer.setUpdateCallback(createHistoryContent);
				createHistoryContent();

				that.displayCommandInput();
			}
		}

	}

	this.displayCommandInput = function() {
		document.getElementById("command_overlay").style.display = "block";
		document.getElementById("command_overlay_suggestions").style.display = "block";
		setTimeout(function() {
			document.getElementById("command_overlay").style.bottom = "20px";
			document.getElementById("command_overlay").style.opacity = "1";
			document.getElementById("tool_input_command").focus();
		}, 10);
	}

	this.tryExecuteCommand = function(cmd) {
		try {
			/*var result = eval(document.getElementById("tool_input_command").value);
			if (result != undefined) {
				T.logInfo(result.toString());
				T.show();
			}*/

			command_history.push(cmd);
			command_history_idx = command_history.length;

			for (var i = 0; i < command_library.length; i++) {
				var c = command_library[i];
				var args = cmd.match(c.match);
				if (args != null) {
					c.impl(args);
					return true;
				}
			}

			if (cmd != "" && !found_command) {
				T.clearLog();
				T.show();
				T.logWarn("Command not recognized: " + cmd);
			}

		} catch (err) {
			T.logError(err.toString());
		}
		return false;
	}

	this.commandListener = function(event) {
		var hide = false;
		var cmd_input = document.getElementById("tool_input_command");
		var cmd = cmd_input.value;

		// process command
		if (event.keyCode == 13) { // enter
			hide = true;

			that.tryExecuteCommand(cmd);
		}

		// close overlay
		if (event.keyCode == 27 // esc
		 || event.keyCode == 32 && event.ctrlKey) { // ctrl+space
			hide = true;
		}

		// navigate history
		if (event.keyCode == 38) { // up arrow
			if (command_history_idx > 0) {
				command_history_idx -= 1;
				cmd = command_history[command_history_idx];
				cmd_input.value = cmd;
			}
		}
		if (event.keyCode == 40) { // down arrow
			if (command_history_idx < command_history.length) {
				command_history_idx += 1;
				cmd = (command_history_idx < command_history.length)? command_history[command_history_idx] : "";
				cmd_input.value = cmd;
			}
		}

		// add autocomplete
		var suggestions = (cmd == "")? [] : Autocomplete.generateCommandList(cmd, command_library);
		document.getElementById("command_overlay_suggestions").innerHTML = "";
		var displaySuggestions = function(s) {
			var div = document.createElement("div");
			div.setAttribute("class", "command_overlay_suggestion");
			div.innerText = s.text;
			document.getElementById("command_overlay_suggestions").appendChild(div);
		};
		suggestions.forEach(displaySuggestions);
		if (suggestions.length == 0) {
			document.getElementById("command_overlay_suggestions").style.opacity = "0";
		} else {
			document.getElementById("command_overlay_suggestions").style.opacity = "1";
		}
		if (event.keyCode == 39 // right arrow
			&& cmd_input.selectionStart == cmd.length
			&& suggestions.length > 0)
		{
			if (cmd.indexOf(" ") == -1) {
				cmd_input.value = cmd + Autocomplete.getSameFill(cmd, suggestions);
			} else {
				var suggested_cmd = command_library.findElement(function(el) { return el.desc == suggestions[0].text; });
				var count_spaces = cmd.split(" ").length - 1;
				var split_suggested_cmd = suggested_cmd.desc.split(" ");
				if (split_suggested_cmd[count_spaces].endsWith(":")) {
					cmd_input.value += split_suggested_cmd[count_spaces] + " ";
				} else {
					var arg_idx = count_spaces - cmd.split(":").length;
					var current_arg = cmd.substr(cmd.lastIndexOf(" ") + 1);
					if (suggested_cmd.completions != undefined && suggested_cmd.completions[arg_idx] != undefined) {
						var completions = suggested_cmd.completions[arg_idx]().filter(function(el) {
							return el.startsWith(current_arg);
						}).map(function(el) {
							return {text: el, hint: "", fill: el};
						});
						if (completions.length > 0) {
							var fill = Autocomplete.getSameFill(current_arg, completions);
							if (fill.length > 0 || completions.length == 1) {
								cmd_input.value = cmd.substr(0, cmd.lastIndexOf(" ") + 1) + current_arg + fill;
							} else {
								document.getElementById("command_overlay_suggestions").innerHTML = "";
								completions.sort(function(a,b) { return a.text.toLowerCase().localeCompare(b.text.toLowerCase()); });
								completions.forEach(displaySuggestions);
							}
						} else  {
							document.getElementById("command_overlay_suggestions").innerHTML = '
no suggestions
';
						}
					} else  {
						document.getElementById("command_overlay_suggestions").innerHTML = '
no suggestions
';
					}
				}
			}
		}

		if (hide) {
			that.hide();
		}
	}

	this.undoClicked = function() {
		ActivityTracer.undo();
		that.hide();
	}

	this.redoClicked = function() {
		ActivityTracer.redo();
		that.hide();
	}

	this.copyClicked = function() {
		Tools.copy();
		that.hide();
	}

	this.pasteClicked = function() {
		Tools.paste();
		that.hide();
	}

	this.cutClicked = function() {
		Tools.cut();
		that.hide();
	}

	this.dfgClicked = function() {
		UI.Statemachine.toggleDataflow();
		that.hide();
	}

	this.terminalClicked = function() {
		UI.Panels.Terminal.show();
		that.hide();
	}

	this.saveClicked = function() {
		UI.Menu.saveBehaviorClicked();
		that.hide();
	}

	this.startRosCommand = function(cmd) {
		last_ros_command = cmd;
		that.tryExecuteCommand(cmd);
	}

	this.notifyRosCommand = function(cmd) {
		if (last_ros_command != undefined && last_ros_command.startsWith(cmd)) {
			RC.PubSub.sendRosNotification(last_ros_command);
			last_ros_command = undefined;
		}
	}

}) ();<commit_msg>fixed unknown symbol error<commit_after>UI.Tools = new (function() {
	var that = this;

	var command_history = [];
	var command_history_idx = 0;
	var command_library = CommandLib.load();

	var last_ros_command = undefined;

	Mousetrap.bind("ctrl+space", function() { UI.Tools.toggle(); }, 'keydown');
	Mousetrap.bind("ctrl+space", function() { UI.Tools.evaluate(); }, 'keyup');
	Mousetrap.bind("enter", function() { that.displayCommandInput(); }, 'keyup');
	var mouse = {x: 0, y: 0};
	document.addEventListener('mousemove', function(e){
		mouse.x = e.clientX || e.pageX;
		mouse.y = e.clientY || e.pageY
	}, false);
	var hover_mode = false;
	var closest_button = undefined;

	var id_list = ["dfg", "undo", "redo", "copy", "cut", "paste", "terminal", "save"];

	var hide_timeout = undefined;

	var getPanel = function() { return document.getElementById("tool_overlay"); }

	var placeButtonsCircular = function(radius, animate) {
		for (var i = 0; i < id_list.length; i++) {
			var d = document.createElement("div");
			d.setAttribute("class", "tool_overlay_button");
			getPanel().appendChild(d);
			var el = document.getElementById("tool_overlay_" + id_list[i]);
			var angle = -225 + i * 45;
			d.setAttribute("style", "transform: rotate(" + angle + "deg) translate(" + radius + "px) rotate(" + -angle + "deg);");
			var bb = d.getBoundingClientRect();
			var p = el.parentNode;
			el.setAttribute("style", "top: " + (bb.top - parseInt(p.style.top)) + "px; left: " + (bb.left - parseInt(p.style.left)) + "px;"
							+ (animate? "transition: all 0.2s ease;" : ""));
			p.removeChild(d);
		}
	}

	var getClosestButton = function() {
		var panel = getPanel();
		var angle = Math.atan2((mouse.y - (parseInt(panel.style.top) + 50)), (mouse.x - (parseInt(panel.style.left) + 50)));
		angle = angle * 180 / Math.PI;
		var snapped_angle = Math.round(angle / 45) * 45;
		var angle_index = (snapped_angle + 225) / 45;
		angle_index = angle_index % 8;
		return document.getElementById("tool_overlay_" + id_list[angle_index]);
	}

	var createHistoryContent = function() {
		var activities = ActivityTracer.getActivityList();
		var current = ActivityTracer.getCurrentIndex();
		var save = ActivityTracer.getLastSaveIndex();
		var changes = ActivityTracer.hasUnsavedChanges();

		var info = document.getElementById("history_info");
		info.innerHTML = "" + Behavior.getBehaviorName() + "

";
		if (!changes) {
			info.innerHTML += "Last saved: no changes
";
		} else if (save == 0) {
			info.innerHTML += "Last saved: never
";
		} else {
			var savetime = Math.round((Date.now() - activities[save].time) / 60000);
			info.innerHTML += "Last saved: " + savetime + " min ago
";
		}

		var list = document.getElementById("history_list");
		list.innerHTML = "";
		for (var i = activities.length - 1; i >= 0; i--) {
			var a = (i > 0)? activities[i] : {description: "no changes"};
			var entry = document.createElement("div");
			entry.setAttribute("class", "history_element");
			entry.innerHTML = ((i == current)? "> " : "") + ((i == save)? "# " : "") + a.description;
			list.appendChild(entry);

			var addListener = function(index) {
				entry.addEventListener('click', function() {
					ActivityTracer.goToIndex(index);
					createHistoryContent();
				});
			};
			addListener(i);
		}
	}

	this.printAvailableCommands = function() {
		T.clearLog();
		T.show();
		T.logInfo("The following commands are available:");
		command_library.forEach(function(c) {
			T.logInfo(c.desc + ' - ' + c.text + '');
		});
	}

	this.display = function() {
		if (RC.Controller.isReadonly()) return;

		if (hide_timeout != undefined) clearTimeout(hide_timeout);
		var panel = getPanel();

		var position_top = Math.min(Math.max(mouse.y - 50, 120), window.innerHeight - 210);
		var position_left = Math.min(Math.max(mouse.x - 50, 120), window.innerWidth - 210);

		panel.style.display = "block";
		panel.style.top = position_top + "px";
		panel.style.left = position_left + "px";
		placeButtonsCircular(300, false);

		setTimeout(function() {
			placeButtonsCircular(120, true);
			panel.style.opacity = "1";
		}, 10);
	}

	this.hide = function() {
		getPanel().style.opacity = "0";
		hide_timeout = setTimeout(function() {
			getPanel().style.display = "none";
			document.getElementById("command_overlay").style.display = "none";
		}, 200);
		placeButtonsCircular(300, true);

		document.getElementById("tool_input_command").blur();
		document.getElementById("tool_input_command").value = "";

		document.getElementById("history_overlay").style.left = "-295px";
		document.getElementById("command_overlay").style.bottom = "0px";
		document.getElementById("command_overlay").style.opacity = "0";
		document.getElementById("command_overlay_suggestions").style.display = "none";
		document.getElementById("command_overlay_suggestions").style.opacity = "0";
	}

	this.toggle = function() {
		if (RC.Controller.isReadonly()) return;

		var panel = getPanel();
		if (!hover_mode) {
			if (panel.style.display != "block") {
				that.display();
				hover_mode = true;
			} else {
				that.hide();
			}
		} else {
			var mouse_distance = Math.sqrt(Math.pow(mouse.x - (parseInt(panel.style.left) + 50), 2) + Math.pow(mouse.y - (parseInt(panel.style.top) + 50), 2));
			if (mouse_distance > 170) {
				var new_closest_button = getClosestButton();
				if (closest_button != new_closest_button) {
					if (closest_button != undefined)
						closest_button.style.backgroundColor = "";
					closest_button = new_closest_button;
					closest_button.style.backgroundColor = "rgba(0, 0, 0, 0.9)";
				}
			} else {
				if (closest_button != undefined) {
					closest_button.style.backgroundColor = "";
					closest_button = undefined;
				}
			}
		}
	}

	this.evaluate = function() {
		var panel = getPanel();
		if (hover_mode) {
			var will_stay = true;
			hover_mode = false;
			if (closest_button != undefined) {
				will_stay = false;
				closest_button.click();
				closest_button.style.backgroundColor = "";
				closest_button = undefined;
			} else {
				// triggering keydown again the first time is slow, so make sure we dont miss any selection
				var mouse_distance = Math.sqrt(Math.pow(mouse.x - (parseInt(panel.style.left) + 50), 2) + Math.pow(mouse.y - (parseInt(panel.style.top) + 50), 2));
				if (mouse_distance > 170) {
					getClosestButton().click();
					will_stay = false;
				}
			}
			if (will_stay) {
				// display panels

				document.getElementById("history_overlay").style.left = "-15px";
				ActivityTracer.setUpdateCallback(createHistoryContent);
				createHistoryContent();

				that.displayCommandInput();
			}
		}

	}

	this.displayCommandInput = function() {
		document.getElementById("command_overlay").style.display = "block";
		document.getElementById("command_overlay_suggestions").style.display = "block";
		setTimeout(function() {
			document.getElementById("command_overlay").style.bottom = "20px";
			document.getElementById("command_overlay").style.opacity = "1";
			document.getElementById("tool_input_command").focus();
		}, 10);
	}

	this.tryExecuteCommand = function(cmd) {
		try {
			/*var result = eval(document.getElementById("tool_input_command").value);
			if (result != undefined) {
				T.logInfo(result.toString());
				T.show();
			}*/

			command_history.push(cmd);
			command_history_idx = command_history.length;

			for (var i = 0; i < command_library.length; i++) {
				var c = command_library[i];
				var args = cmd.match(c.match);
				if (args != null) {
					c.impl(args);
					return true;
				}
			}

			if (cmd != "") {
				T.clearLog();
				T.show();
				T.logWarn("Command not recognized: " + cmd);
			}

		} catch (err) {
			T.logError(err.toString());
		}
		return false;
	}

	this.commandListener = function(event) {
		var hide = false;
		var cmd_input = document.getElementById("tool_input_command");
		var cmd = cmd_input.value;

		// process command
		if (event.keyCode == 13) { // enter
			hide = true;

			that.tryExecuteCommand(cmd);
		}

		// close overlay
		if (event.keyCode == 27 // esc
		 || event.keyCode == 32 && event.ctrlKey) { // ctrl+space
			hide = true;
		}

		// navigate history
		if (event.keyCode == 38) { // up arrow
			if (command_history_idx > 0) {
				command_history_idx -= 1;
				cmd = command_history[command_history_idx];
				cmd_input.value = cmd;
			}
		}
		if (event.keyCode == 40) { // down arrow
			if (command_history_idx < command_history.length) {
				command_history_idx += 1;
				cmd = (command_history_idx < command_history.length)? command_history[command_history_idx] : "";
				cmd_input.value = cmd;
			}
		}

		// add autocomplete
		var suggestions = (cmd == "")? [] : Autocomplete.generateCommandList(cmd, command_library);
		document.getElementById("command_overlay_suggestions").innerHTML = "";
		var displaySuggestions = function(s) {
			var div = document.createElement("div");
			div.setAttribute("class", "command_overlay_suggestion");
			div.innerText = s.text;
			document.getElementById("command_overlay_suggestions").appendChild(div);
		};
		suggestions.forEach(displaySuggestions);
		if (suggestions.length == 0) {
			document.getElementById("command_overlay_suggestions").style.opacity = "0";
		} else {
			document.getElementById("command_overlay_suggestions").style.opacity = "1";
		}
		if (event.keyCode == 39 // right arrow
			&& cmd_input.selectionStart == cmd.length
			&& suggestions.length > 0)
		{
			if (cmd.indexOf(" ") == -1) {
				cmd_input.value = cmd + Autocomplete.getSameFill(cmd, suggestions);
			} else {
				var suggested_cmd = command_library.findElement(function(el) { return el.desc == suggestions[0].text; });
				var count_spaces = cmd.split(" ").length - 1;
				var split_suggested_cmd = suggested_cmd.desc.split(" ");
				if (split_suggested_cmd[count_spaces].endsWith(":")) {
					cmd_input.value += split_suggested_cmd[count_spaces] + " ";
				} else {
					var arg_idx = count_spaces - cmd.split(":").length;
					var current_arg = cmd.substr(cmd.lastIndexOf(" ") + 1);
					if (suggested_cmd.completions != undefined && suggested_cmd.completions[arg_idx] != undefined) {
						var completions = suggested_cmd.completions[arg_idx]().filter(function(el) {
							return el.startsWith(current_arg);
						}).map(function(el) {
							return {text: el, hint: "", fill: el};
						});
						if (completions.length > 0) {
							var fill = Autocomplete.getSameFill(current_arg, completions);
							if (fill.length > 0 || completions.length == 1) {
								cmd_input.value = cmd.substr(0, cmd.lastIndexOf(" ") + 1) + current_arg + fill;
							} else {
								document.getElementById("command_overlay_suggestions").innerHTML = "";
								completions.sort(function(a,b) { return a.text.toLowerCase().localeCompare(b.text.toLowerCase()); });
								completions.forEach(displaySuggestions);
							}
						} else  {
							document.getElementById("command_overlay_suggestions").innerHTML = '
no suggestions
';
						}
					} else  {
						document.getElementById("command_overlay_suggestions").innerHTML = '
no suggestions
';
					}
				}
			}
		}

		if (hide) {
			that.hide();
		}
	}

	this.undoClicked = function() {
		ActivityTracer.undo();
		that.hide();
	}

	this.redoClicked = function() {
		ActivityTracer.redo();
		that.hide();
	}

	this.copyClicked = function() {
		Tools.copy();
		that.hide();
	}

	this.pasteClicked = function() {
		Tools.paste();
		that.hide();
	}

	this.cutClicked = function() {
		Tools.cut();
		that.hide();
	}

	this.dfgClicked = function() {
		UI.Statemachine.toggleDataflow();
		that.hide();
	}

	this.terminalClicked = function() {
		UI.Panels.Terminal.show();
		that.hide();
	}

	this.saveClicked = function() {
		UI.Menu.saveBehaviorClicked();
		that.hide();
	}

	this.startRosCommand = function(cmd) {
		last_ros_command = cmd;
		that.tryExecuteCommand(cmd);
	}

	this.notifyRosCommand = function(cmd) {
		if (last_ros_command != undefined && last_ros_command.startsWith(cmd)) {
			RC.PubSub.sendRosNotification(last_ros_command);
			last_ros_command = undefined;
		}
	}

}) ();<|endoftext|>


<commit_before>import TreeBuilder from './builder.js';

const dTree = {

  version: '/* @echo DTREE_VERSION */',

  init: function(data, options = {}) {

    var opts = _.defaultsDeep(options || {}, {
      target: '#graph',
      debug: false,
      width: 600,
      height: 600,
      callbacks: {
        nodeClick: function(name, extra, id) {},
        nodeRenderer: function(name, x, y, height, width, extra, id, nodeClass, textClass, textRenderer) {
          return TreeBuilder._nodeRenderer(name, x, y, height, width, extra,
            id,nodeClass, textClass, textRenderer);
        },
        textRenderer: function(name, extra, textClass) {
          return TreeBuilder._textRenderer(name, extra, textClass);
        }
      },
      margin: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
      },
      styles: {
        node: 'node',
        linage: 'linage',
        marriage: 'marriage',
        text: 'nodeText'
      }
    });

    var data = this._preprocess(data);
    var treeBuilder = new TreeBuilder(data.root, data.siblings, opts);
    treeBuilder.create();

  },

  _preprocess: function(data) {

    var siblings = [];
    var id = 0;

    var root = {
      name: '',
      id: id++,
      hidden: true,
      children: []
    };

    var reconstructTree = function(person, parent) {

      // convert to person to d3 node
      var node = {
        name: person.name,
        id: id++,
        hidden: false,
        children: [],
        extra: person.extra,
        textClass: person.textClass,
        class: person.class
      };

      // add to parent as child
      parent.children.push(node);

      // go through marriage
      if (person.marriage) {

        var m = {
          name: '',
          id: id++,
          hidden: true,
          noParent: true,
          children: [],
          extra: person.marriage.extra
        };

        parent.children.push(m);

        var spouse = {
          name: person.marriage.spouse.name,
          id: id++,
          hidden: false,
          noParent: true,
          children: [],
          textClass: person.marriage.spouse.textClass,
          class: person.marriage.spouse.class,
          extra: person.marriage.spouse.extra
        };

        parent.children.push(spouse);

        _.forEach(person.marriage.children, function(child) {
          reconstructTree(child, m);
        });

        siblings.push({
          source: {
            id: node.id
          },
          target: {
            id: spouse.id
          }
        });

      }

    };

    _.forEach(data, function(person) {
      reconstructTree(person, root);
    });

    _.forEach(root.children, function(child) {
      child.noParent = true;
    });

    return {
      root: root,
      siblings: siblings
    };

  }

};

export default dTree;
<commit_msg>feat: Add direct children nodes #19<commit_after>import TreeBuilder from './builder.js';

const dTree = {

  version: '/* @echo DTREE_VERSION */',

  init: function(data, options = {}) {

    var opts = _.defaultsDeep(options || {}, {
      target: '#graph',
      debug: false,
      width: 600,
      height: 600,
      callbacks: {
        nodeClick: function(name, extra, id) {},
        nodeRenderer: function(name, x, y, height, width, extra, id, nodeClass, textClass, textRenderer) {
          return TreeBuilder._nodeRenderer(name, x, y, height, width, extra,
            id,nodeClass, textClass, textRenderer);
        },
        textRenderer: function(name, extra, textClass) {
          return TreeBuilder._textRenderer(name, extra, textClass);
        }
      },
      margin: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
      },
      styles: {
        node: 'node',
        linage: 'linage',
        marriage: 'marriage',
        text: 'nodeText'
      }
    });

    var data = this._preprocess(data);
    var treeBuilder = new TreeBuilder(data.root, data.siblings, opts);
    treeBuilder.create();

  },

  _preprocess: function(data) {

    var siblings = [];
    var id = 0;

    var root = {
      name: '',
      id: id++,
      hidden: true,
      children: []
    };

    var reconstructTree = function(person, parent) {

      // convert to person to d3 node
      var node = {
        name: person.name,
        id: id++,
        hidden: false,
        children: [],
        extra: person.extra,
        textClass: person.textClass,
        class: person.class
      };

      // add to parent as child
      parent.children.push(node);

      // add "direct" children
      _.forEach(person.children, function(child) {
        reconstructTree(child, node);
      });

      // go through marriage
      if (person.marriage) {

        var m = {
          name: '',
          id: id++,
          hidden: true,
          noParent: true,
          children: [],
          extra: person.marriage.extra
        };

        parent.children.push(m);

        var spouse = {
          name: person.marriage.spouse.name,
          id: id++,
          hidden: false,
          noParent: true,
          children: [],
          textClass: person.marriage.spouse.textClass,
          class: person.marriage.spouse.class,
          extra: person.marriage.spouse.extra
        };

        parent.children.push(spouse);

        _.forEach(person.marriage.children, function(child) {
          reconstructTree(child, m);
        });

        siblings.push({
          source: {
            id: node.id
          },
          target: {
            id: spouse.id
          }
        });

      }

    };

    _.forEach(data, function(person) {
      reconstructTree(person, root);
    });

    _.forEach(root.children, function(child) {
      child.noParent = true;
    });

    return {
      root: root,
      siblings: siblings
    };

  }

};

export default dTree;
<|endoftext|>


<commit_before>"use strict";

const defs    = require('./defs.js');
const { lua_assert } = require('./llimits.js');
const ldebug  = require('./ldebug.js');
const lobject = require('./lobject.js');
const lstring = require('./lstring.js');
const lstate  = require('./lstate.js');
const CT      = defs.constant_types;

/* used to prevent conflicts with lightuserdata keys */
let lightuserdata_hashes = new WeakMap();
const get_lightuserdata_hash = function(v) {
    let hash = lightuserdata_hashes.get(v);
    if (!hash) {
        /* Hash should be something unique that is a valid WeakMap key
           so that it ends up in dead_weak when removed from a table */
        hash = {};
        lightuserdata_hashes.set(v, hash);
    }
    return hash;
};

const table_hash = function(L, key) {
    switch(key.type) {
        case CT.LUA_TNIL:
            return ldebug.luaG_runerror(L, defs.to_luastring("table index is nil", true));
        case CT.LUA_TNUMFLT:
            if (isNaN(key.value))
                return ldebug.luaG_runerror(L, defs.to_luastring("table index is NaN", true));
            /* fall through */
        case CT.LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */
        case CT.LUA_TBOOLEAN:
        case CT.LUA_TTABLE:
        case CT.LUA_TLCL:
        case CT.LUA_TLCF:
        case CT.LUA_TCCL:
        case CT.LUA_TUSERDATA:
        case CT.LUA_TTHREAD:
            return key.value;
        case CT.LUA_TSHRSTR:
        case CT.LUA_TLNGSTR:
            return lstring.luaS_hashlongstr(key.tsvalue());
        case CT.LUA_TLIGHTUSERDATA: {
            let v = key.value;
            switch(typeof v) {
                case "string":
                    /* possible conflict with LUA_TSTRING.
                       prefix this string with "*" so they don't clash */
                    return "*" + v;
                case "number":
                    /* possible conflict with LUA_TNUMBER.
                       turn into string and prefix with "#" to avoid clash with other strings */
                    return "#" + v;
                case "boolean":
                    /* possible conflict with LUA_TBOOLEAN. use strings ?true and ?false instead */
                    return v?"?true":"?false";
                case "function":
                    /* possible conflict with LUA_TLCF.
                       indirect via a weakmap */
                    return get_lightuserdata_hash(v);
                case "object":
                    /* v could be a lua_State, CClosure, LClosure, Table or Userdata from this state as returned by lua_topointer */
                    if ((v instanceof lstate.lua_State && v.l_G === L.l_G) ||
                        v instanceof Table ||
                        v instanceof lobject.Udata ||
                        v instanceof lobject.LClosure ||
                        v instanceof lobject.CClosure) {
                        /* indirect via a weakmap */
                        return get_lightuserdata_hash(v);
                    }
                    /* fall through */
                default:
                    return v;
            }
        }
        default:
            throw new Error("unknown key type: " + key.type);
    }
};

class Table {
    constructor(L) {
        this.id = L.l_G.id_counter++;
        this.strong = new Map();
        this.dead_strong = new Map();
        this.dead_weak = void 0; /* initialised when needed */
        this.f = void 0; /* first entry */
        this.l = void 0; /* last entry */
        this.metatable = null;
        this.flags = ~0;
    }
}

const invalidateTMcache = function(t) {
    t.flags = 0;
};

const add = function(t, hash, key, value) {
    t.dead_strong.clear();
    t.dead_weak = void 0;
    let prev = null;
    let entry = {
        key: key,
        value: value,
        p: prev = t.l,
        n: void 0
    };
    if (!t.f) t.f = entry;
    if (prev) prev.n = entry;
    t.strong.set(hash, entry);
    t.l = entry;
};

const is_valid_weakmap_key = function(k) {
    return typeof k === 'object' ? k !== null : typeof k === 'function';
};

/* Move out of 'strong' part and into 'dead' part. */
const mark_dead = function(t, hash) {
    let e = t.strong.get(hash);
    if (e) {
        e.key.setdeadvalue();
        e.value = void 0;
        let next = e.n;
        let prev = e.p;
        e.p = void 0; /* no need to know previous item any more */
        if(prev) prev.n = next;
        if(next) next.p = prev;
        if(t.f === e) t.f = next;
        if(t.l === e) t.l = prev;
        t.strong.delete(hash);
        if (is_valid_weakmap_key(hash)) {
            if (!t.dead_weak) t.dead_weak = new WeakMap();
            t.dead_weak.set(hash, e);
        } else {
            /* can't be used as key in weakmap */
            t.dead_strong.set(hash, e);
        }
    }
};

const luaH_new = function(L) {
    return new Table(L);
};

const getgeneric = function(t, hash) {
    let v = t.strong.get(hash);
    return v ? v.value : lobject.luaO_nilobject;
};

const luaH_getint = function(t, key) {
    lua_assert(typeof key == "number" && (key|0) === key);
    return getgeneric(t, key);
};

const luaH_getstr = function(t, key) {
    lua_assert(key instanceof lstring.TString);
    return getgeneric(t, lstring.luaS_hashlongstr(key));
};

const luaH_get = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    if (key.ttisnil() || (key.ttisfloat() && isNaN(key.value)))
        return lobject.luaO_nilobject;
    return getgeneric(t, table_hash(L, key));
};

const setgeneric = function(t, hash, key) {
    let v = t.strong.get(hash);
    if (v)
        return v.value;

    let kv = key.value;
    if ((key.ttisfloat() && (kv|0) === kv)) { /* does index fit in an integer? */
        /* insert it as an integer */
        key = new lobject.TValue(CT.LUA_TNUMINT, kv);
    } else {
        key = new lobject.TValue(key.type, kv);
    }
    let tv = new lobject.TValue(CT.LUA_TNIL, null);
    add(t, hash, key, tv);
    return tv;
};

const luaH_setint = function(t, key, value) {
    lua_assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue);
    let hash = key; /* table_hash known result */
    if (value.ttisnil()) {
        mark_dead(t, hash);
        return;
    }
    let v = t.strong.get(hash);
    if (v) {
        let tv = v.value;
        tv.setfrom(value);
    } else {
        let k = new lobject.TValue(CT.LUA_TNUMINT, key);
        let v = new lobject.TValue(value.type, value.value);
        add(t, hash, k, v);
    }
};

const luaH_set = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    let hash = table_hash(L, key);
    return setgeneric(t, hash, key);
};

const luaH_delete = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    let hash = table_hash(L, key);
    return mark_dead(t, hash);
};

/*
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
const luaH_getn = function(t) {
    let i = 0;
    let j = t.strong.size + 1; /* use known size of Map to bound search */
    /* now do a binary search between them */
    while (j - i > 1) {
        let m = Math.floor((i+j)/2);
        if (luaH_getint(t, m).ttisnil()) j = m;
        else i = m;
    }
    return i;
};

const luaH_next = function(L, table, keyI) {
    let keyO = L.stack[keyI];

    let entry;
    if (keyO.type === CT.LUA_TNIL) {
        entry = table.f;
        if (!entry)
            return false;
    } else {
        /* First find current key */
        let hash = table_hash(L, keyO);
        /* Look in main part of table */
        entry = table.strong.get(hash);
        if (entry) {
            entry = entry.n;
            if (!entry)
                return false;
        } else {
            /* Try dead keys */
            entry = (table.dead_weak && table.dead_weak.get(hash)) || table.dead_strong.get(hash);
            if (!entry)
                /* item not in table */
                return ldebug.luaG_runerror(L, defs.to_luastring("invalid key to 'next'"));
            /* Iterate until either out of keys, or until finding a non-dead key */
            do {
                entry = entry.n;
                if (!entry)
                    return false;
            } while (entry.key.ttisdeadkey());
        }
    }
    lobject.setobj2s(L, keyI, entry.key);
    lobject.setobj2s(L, keyI+1, entry.value);
    return true;
};

module.exports.invalidateTMcache = invalidateTMcache;
module.exports.luaH_delete  = luaH_delete;
module.exports.luaH_get     = luaH_get;
module.exports.luaH_getint  = luaH_getint;
module.exports.luaH_getn    = luaH_getn;
module.exports.luaH_getstr  = luaH_getstr;
module.exports.luaH_set     = luaH_set;
module.exports.luaH_setint  = luaH_setint;
module.exports.luaH_new     = luaH_new;
module.exports.luaH_next    = luaH_next;
module.exports.Table        = Table;
<commit_msg>src/ltable.js: Use destructuring assignment for defs.js<commit_after>"use strict";

const {
    constant_types: {
        LUA_TBOOLEAN,
        LUA_TCCL,
        LUA_TLCF,
        LUA_TLCL,
        LUA_TLIGHTUSERDATA,
        LUA_TLNGSTR,
        LUA_TNIL,
        LUA_TNUMFLT,
        LUA_TNUMINT,
        LUA_TSHRSTR,
        LUA_TTABLE,
        LUA_TTHREAD,
        LUA_TUSERDATA
    },
    to_luastring
} = require('./defs.js');
const { lua_assert } = require('./llimits.js');
const ldebug  = require('./ldebug.js');
const lobject = require('./lobject.js');
const lstring = require('./lstring.js');
const lstate  = require('./lstate.js');

/* used to prevent conflicts with lightuserdata keys */
let lightuserdata_hashes = new WeakMap();
const get_lightuserdata_hash = function(v) {
    let hash = lightuserdata_hashes.get(v);
    if (!hash) {
        /* Hash should be something unique that is a valid WeakMap key
           so that it ends up in dead_weak when removed from a table */
        hash = {};
        lightuserdata_hashes.set(v, hash);
    }
    return hash;
};

const table_hash = function(L, key) {
    switch(key.type) {
        case LUA_TNIL:
            return ldebug.luaG_runerror(L, to_luastring("table index is nil", true));
        case LUA_TNUMFLT:
            if (isNaN(key.value))
                return ldebug.luaG_runerror(L, to_luastring("table index is NaN", true));
            /* fall through */
        case LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */
        case LUA_TBOOLEAN:
        case LUA_TTABLE:
        case LUA_TLCL:
        case LUA_TLCF:
        case LUA_TCCL:
        case LUA_TUSERDATA:
        case LUA_TTHREAD:
            return key.value;
        case LUA_TSHRSTR:
        case LUA_TLNGSTR:
            return lstring.luaS_hashlongstr(key.tsvalue());
        case LUA_TLIGHTUSERDATA: {
            let v = key.value;
            switch(typeof v) {
                case "string":
                    /* possible conflict with LUA_TSTRING.
                       prefix this string with "*" so they don't clash */
                    return "*" + v;
                case "number":
                    /* possible conflict with LUA_TNUMBER.
                       turn into string and prefix with "#" to avoid clash with other strings */
                    return "#" + v;
                case "boolean":
                    /* possible conflict with LUA_TBOOLEAN. use strings ?true and ?false instead */
                    return v?"?true":"?false";
                case "function":
                    /* possible conflict with LUA_TLCF.
                       indirect via a weakmap */
                    return get_lightuserdata_hash(v);
                case "object":
                    /* v could be a lua_State, CClosure, LClosure, Table or Userdata from this state as returned by lua_topointer */
                    if ((v instanceof lstate.lua_State && v.l_G === L.l_G) ||
                        v instanceof Table ||
                        v instanceof lobject.Udata ||
                        v instanceof lobject.LClosure ||
                        v instanceof lobject.CClosure) {
                        /* indirect via a weakmap */
                        return get_lightuserdata_hash(v);
                    }
                    /* fall through */
                default:
                    return v;
            }
        }
        default:
            throw new Error("unknown key type: " + key.type);
    }
};

class Table {
    constructor(L) {
        this.id = L.l_G.id_counter++;
        this.strong = new Map();
        this.dead_strong = new Map();
        this.dead_weak = void 0; /* initialised when needed */
        this.f = void 0; /* first entry */
        this.l = void 0; /* last entry */
        this.metatable = null;
        this.flags = ~0;
    }
}

const invalidateTMcache = function(t) {
    t.flags = 0;
};

const add = function(t, hash, key, value) {
    t.dead_strong.clear();
    t.dead_weak = void 0;
    let prev = null;
    let entry = {
        key: key,
        value: value,
        p: prev = t.l,
        n: void 0
    };
    if (!t.f) t.f = entry;
    if (prev) prev.n = entry;
    t.strong.set(hash, entry);
    t.l = entry;
};

const is_valid_weakmap_key = function(k) {
    return typeof k === 'object' ? k !== null : typeof k === 'function';
};

/* Move out of 'strong' part and into 'dead' part. */
const mark_dead = function(t, hash) {
    let e = t.strong.get(hash);
    if (e) {
        e.key.setdeadvalue();
        e.value = void 0;
        let next = e.n;
        let prev = e.p;
        e.p = void 0; /* no need to know previous item any more */
        if(prev) prev.n = next;
        if(next) next.p = prev;
        if(t.f === e) t.f = next;
        if(t.l === e) t.l = prev;
        t.strong.delete(hash);
        if (is_valid_weakmap_key(hash)) {
            if (!t.dead_weak) t.dead_weak = new WeakMap();
            t.dead_weak.set(hash, e);
        } else {
            /* can't be used as key in weakmap */
            t.dead_strong.set(hash, e);
        }
    }
};

const luaH_new = function(L) {
    return new Table(L);
};

const getgeneric = function(t, hash) {
    let v = t.strong.get(hash);
    return v ? v.value : lobject.luaO_nilobject;
};

const luaH_getint = function(t, key) {
    lua_assert(typeof key == "number" && (key|0) === key);
    return getgeneric(t, key);
};

const luaH_getstr = function(t, key) {
    lua_assert(key instanceof lstring.TString);
    return getgeneric(t, lstring.luaS_hashlongstr(key));
};

const luaH_get = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    if (key.ttisnil() || (key.ttisfloat() && isNaN(key.value)))
        return lobject.luaO_nilobject;
    return getgeneric(t, table_hash(L, key));
};

const setgeneric = function(t, hash, key) {
    let v = t.strong.get(hash);
    if (v)
        return v.value;

    let kv = key.value;
    if ((key.ttisfloat() && (kv|0) === kv)) { /* does index fit in an integer? */
        /* insert it as an integer */
        key = new lobject.TValue(LUA_TNUMINT, kv);
    } else {
        key = new lobject.TValue(key.type, kv);
    }
    let tv = new lobject.TValue(LUA_TNIL, null);
    add(t, hash, key, tv);
    return tv;
};

const luaH_setint = function(t, key, value) {
    lua_assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue);
    let hash = key; /* table_hash known result */
    if (value.ttisnil()) {
        mark_dead(t, hash);
        return;
    }
    let v = t.strong.get(hash);
    if (v) {
        let tv = v.value;
        tv.setfrom(value);
    } else {
        let k = new lobject.TValue(LUA_TNUMINT, key);
        let v = new lobject.TValue(value.type, value.value);
        add(t, hash, k, v);
    }
};

const luaH_set = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    let hash = table_hash(L, key);
    return setgeneric(t, hash, key);
};

const luaH_delete = function(L, t, key) {
    lua_assert(key instanceof lobject.TValue);
    let hash = table_hash(L, key);
    return mark_dead(t, hash);
};

/*
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
const luaH_getn = function(t) {
    let i = 0;
    let j = t.strong.size + 1; /* use known size of Map to bound search */
    /* now do a binary search between them */
    while (j - i > 1) {
        let m = Math.floor((i+j)/2);
        if (luaH_getint(t, m).ttisnil()) j = m;
        else i = m;
    }
    return i;
};

const luaH_next = function(L, table, keyI) {
    let keyO = L.stack[keyI];

    let entry;
    if (keyO.type === LUA_TNIL) {
        entry = table.f;
        if (!entry)
            return false;
    } else {
        /* First find current key */
        let hash = table_hash(L, keyO);
        /* Look in main part of table */
        entry = table.strong.get(hash);
        if (entry) {
            entry = entry.n;
            if (!entry)
                return false;
        } else {
            /* Try dead keys */
            entry = (table.dead_weak && table.dead_weak.get(hash)) || table.dead_strong.get(hash);
            if (!entry)
                /* item not in table */
                return ldebug.luaG_runerror(L, to_luastring("invalid key to 'next'"));
            /* Iterate until either out of keys, or until finding a non-dead key */
            do {
                entry = entry.n;
                if (!entry)
                    return false;
            } while (entry.key.ttisdeadkey());
        }
    }
    lobject.setobj2s(L, keyI, entry.key);
    lobject.setobj2s(L, keyI+1, entry.value);
    return true;
};

module.exports.invalidateTMcache = invalidateTMcache;
module.exports.luaH_delete  = luaH_delete;
module.exports.luaH_get     = luaH_get;
module.exports.luaH_getint  = luaH_getint;
module.exports.luaH_getn    = luaH_getn;
module.exports.luaH_getstr  = luaH_getstr;
module.exports.luaH_set     = luaH_set;
module.exports.luaH_setint  = luaH_setint;
module.exports.luaH_new     = luaH_new;
module.exports.luaH_next    = luaH_next;
module.exports.Table        = Table;
<|endoftext|>


<commit_before>/**
 * Created by vst on 3/10/2016.
 */
"use strict";

require("app")
	.config(["$locationProvider", function (locationProvider) {
		locationProvider.html5Mode ({
			enabled: true,
			requireBase: false
		});
	}]);

// Components
require("components/navigator");<commit_msg>Redirect to navigator by default.<commit_after>/**
 * Created by vst on 3/10/2016.
 */
"use strict";

require("app")
	.config(["$routeProvider", "$locationProvider", function ($routeProvider, $locationProvider) {
		$routeProvider.otherwise('/nav');

		$locationProvider.html5Mode ({
			enabled: true,
			requireBase: false
		});
	}]);

// Components
require("components/navigator");<|endoftext|>


<commit_before>/**
* @namespace JenScript
*/
var JenScript = {};

(function() {

		JenScript = {

				version : '@VERSION',
				views : [],
				sequenceId: 0,
				SVG_NS : 'http://www.w3.org/2000/svg',
				XLINK_NS : 'http://www.w3.org/1999/xlink',
				SVG_VERSION : '1.1',

				/**
	             * create color as hex representation
	             * @method
	             * @return {String} color as hex string
	             * @memberof JenScript
	             */
	            createColor: function() {
	                var color = (Math.random() * 0xFFFFFF << 0).toString(16);
	                while (color.length < 6) {
	                	color = '0' + color;
	                }
	                return '#' + color;
	            },

	            /**
	             * get browser agent
	             * @method
	             * @returns {Object} browser.name and browser.version
	             */
		        agent: (function() {
		            var ua = navigator.userAgent.toLowerCase(),
		                // jQuery UA regex
		                match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
		                /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
		                /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
		                /(msie) ([\w.]+)/.exec( ua ) ||
		                ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
		                [];
		            return {
		                browser: match[ 1 ] || '',
		                version: match[ 2 ] || '0'
		            };
		        })(),

		        /**
		         * View Part Name
		         * @contructor
		         * @memberof JenScript
		         */
		        ViewPart : {
		        		View   : 'View',
		        		North  : 'North',
		        		South  : 'South',
		        		West   : 'West',
		        		East   : 'East',
		        		Device : 'Device'
		        },

		    	/**
		         * @constructor
		         * @memberof JenScript
		         * @param {Object} config
		         * @param {String} [config.part] South, West, East, North, Device
		         * @param {Number} [config.width] The component width in pixel
		         * @param {Number} [config.height] The component height in pixel
		         * @param {Object} [config.view] The component parent views
		         */
		    	ViewPartComponent : function(config) {
		    		this.init(config);
		    	},

		    	/**
		    	 * Object View()
		         * @constructor
		         * @memberof JenScript
		         * @param {Object} config
		         * @param {String} [config.name] The view chart name
		         * @param {Number} [config.width] The view width in pixel
		         * @param {Number} [config.height] The view height in pixel
		         * @param {Number} [config.west] The west part width
		         * @param {Number} [config.east] The east part width
		         * @param {Number} [config.north] The north part height
		         * @param {Number} [config.south] The south part height
		         *
		         */
		        View: function(config) {
		            this.init(config);
		        },

		        /**
		         * Object Projection()
		         * @constructor
		         * @memberof JenScript
		         * @abstract
		         */
		    	Projection : function(config) {
		    		this.init(config);
		    	},

		    	/**
		    	 * Object Plugin()
		         * @constructor
		         * @memberof JenScript
		         * @abstract
		         */
		        Plugin : function(config) {
		    		this.init(config);
		    	},

		    	//stream wrapper function with interfaces builders
	    		view : function(config){
	    			return new JenScript.ViewBuilder(config);
				},
		};

		//EXPORT
		(function(root, factory) {
		 if(typeof exports === 'object') {
		     // Node
		     module.exports = factory();
		 }
		 else if(typeof define === 'function' && define.amd) {
		     // AMD
		     define(factory);
		 }
		 else {
		     // globals UMD
		     root.returnExports = factory();
		 }
		}(this, function() {
			return JenScript;
		}));
})();<commit_msg>add xhtml ns<commit_after>/**
* @namespace JenScript
*/
var JenScript = {};

(function() {

		JenScript = {

				version : '@VERSION',
				views : [],
				sequenceId: 0,
				SVG_NS : 'http://www.w3.org/2000/svg',
				XLINK_NS : 'http://www.w3.org/1999/xlink',
				XHTML_NS : 'http://www.w3.org/1999/xhtml',
				SVG_VERSION : '1.1',

				/**
	             * create color as hex representation
	             * @method
	             * @return {String} color as hex string
	             * @memberof JenScript
	             */
	            createColor: function() {
	                var color = (Math.random() * 0xFFFFFF << 0).toString(16);
	                while (color.length < 6) {
	                	color = '0' + color;
	                }
	                return '#' + color;
	            },

	            /**
	             * get browser agent
	             * @method
	             * @returns {Object} browser.name and browser.version
	             */
		        agent: (function() {
		            var ua = navigator.userAgent.toLowerCase(),
		                // jQuery UA regex
		                match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
		                /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
		                /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
		                /(msie) ([\w.]+)/.exec( ua ) ||
		                ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
		                [];
		            return {
		                browser: match[ 1 ] || '',
		                version: match[ 2 ] || '0'
		            };
		        })(),

		        /**
		         * View Part Name
		         * @contructor
		         * @memberof JenScript
		         */
		        ViewPart : {
		        		View   : 'View',
		        		North  : 'North',
		        		South  : 'South',
		        		West   : 'West',
		        		East   : 'East',
		        		Device : 'Device'
		        },

		    	/**
		         * @constructor
		         * @memberof JenScript
		         * @param {Object} config
		         * @param {String} [config.part] South, West, East, North, Device
		         * @param {Number} [config.width] The component width in pixel
		         * @param {Number} [config.height] The component height in pixel
		         * @param {Object} [config.view] The component parent views
		         */
		    	ViewPartComponent : function(config) {
		    		this.init(config);
		    	},

		    	/**
		    	 * Object View()
		         * @constructor
		         * @memberof JenScript
		         * @param {Object} config
		         * @param {String} [config.name] The view chart name
		         * @param {Number} [config.width] The view width in pixel
		         * @param {Number} [config.height] The view height in pixel
		         * @param {Number} [config.west] The west part width
		         * @param {Number} [config.east] The east part width
		         * @param {Number} [config.north] The north part height
		         * @param {Number} [config.south] The south part height
		         *
		         */
		        View: function(config) {
		            this.init(config);
		        },

		        /**
		         * Object Projection()
		         * @constructor
		         * @memberof JenScript
		         * @abstract
		         */
		    	Projection : function(config) {
		    		this.init(config);
		    	},

		    	/**
		    	 * Object Plugin()
		         * @constructor
		         * @memberof JenScript
		         * @abstract
		         */
		        Plugin : function(config) {
		    		this.init(config);
		    	},

		    	//stream wrapper function with interfaces builders
	    		view : function(config){
	    			return new JenScript.ViewBuilder(config);
				},
		};

		//EXPORT
		(function(root, factory) {
		 if(typeof exports === 'object') {
		     // Node
		     module.exports = factory();
		 }
		 else if(typeof define === 'function' && define.amd) {
		     // AMD
		     define(factory);
		 }
		 else {
		     // globals UMD
		     root.returnExports = factory();
		 }
		}(this, function() {
			return JenScript;
		}));
})();<|endoftext|>


<commit_before>export class LaconaError extends Error {
  constructor(message) {
    super()
    this.message = message
    this.stack = (new Error()).stack;
    this.name = this.constructor.name;
  }
}
<commit_msg>Update error for new babel 6 impl<commit_after>export function LaconaError(message){
    this.message = message;
}

LaconaError.prototype = new Error();
<|endoftext|>


<commit_before>;(function(exports) {
  var codeAnalyzer;
  if(typeof module !== 'undefined' && module.exports) { // node
    codeAnalyzer = require('../src/code-analyzer').codeAnalyzer;
  } else { // browser
    codeAnalyzer = window.codeAnalyzer;
  }

  mapper = {
    // returns cell that text point is at
    getIndex: function(terminal, text, relativePoint) {
      var charDimes = terminal.getCharDimes();
      var point = offset(relativePoint, terminal.getOffset());
      for (var i = 0, x = 0, y = charDimes.y; i < text.length; i++) {
        if (codeAnalyzer.isAtNewline(text, i)) {
          y += charDimes.y;
          x = 0;
        } else  { // not reached end of line
          x += charDimes.x
        }

        if (point.x >= x - charDimes.x && point.x < x &&
            point.y >= y - charDimes.y && point.y < y) {
          return i;
        }
      }

      return undefined;
    },

    getLineNumber: function(terminal, text, relativePoint) {
      var charDimes = terminal.getCharDimes();
      var point = offset(relativePoint, terminal.getLineOffset());
      if (point.x < 0 || point.x >= terminal.getWidth()) {
        return undefined;
      }

      var lines = text.split("\n");
      for (var i = 0, y = charDimes.y; i < lines.length; i++) {
        if (point.y >= y - charDimes.y && point.y < y) {
          return i;
        }
        y += charDimes.y;
      }

      return undefined;
    }
  };

  var offset = function(point, offset) {
    return {
      x: point.x - offset.l,
      y: point.y - offset.t
    };
  };

  exports.mapper = mapper;
})(typeof exports === 'undefined' ? this : exports)
<commit_msg>Add handy getLine fn to mapper.<commit_after>;(function(exports) {
  var codeAnalyzer;
  if(typeof module !== 'undefined' && module.exports) { // node
    codeAnalyzer = require('../src/code-analyzer').codeAnalyzer;
  } else { // browser
    codeAnalyzer = window.codeAnalyzer;
  }

  mapper = {
    // returns cell that text point is at
    getIndex: function(terminal, text, relativePoint) {
      var charDimes = terminal.getCharDimes();
      var point = offset(relativePoint, terminal.getOffset());
      for (var i = 0, x = 0, y = charDimes.y; i < text.length; i++) {
        if (codeAnalyzer.isAtNewline(text, i)) {
          y += charDimes.y;
          x = 0;
        } else  { // not reached end of line
          x += charDimes.x
        }

        if (point.x >= x - charDimes.x && point.x < x &&
            point.y >= y - charDimes.y && point.y < y) {
          return i;
        }
      }

      return undefined;
    },

    getLineNumber: function(terminal, text, relativePoint) {
      var charDimes = terminal.getCharDimes();
      var point = offset(relativePoint, terminal.getLineOffset());

      if (point.x < 0 || point.x >= terminal.getWidth()) {
        return undefined;
      }

      var lines = text.split("\n");
      for (var i = 0, y = charDimes.y; i < lines.length; i++) {
        if (point.y >= y - charDimes.y && point.y < y) {
          return i;
        }
        y += charDimes.y;
      }

      return undefined;
    },

    getLine: function(terminal, text, point) {
      var lineNumber = mapper.getLineNumber(terminal, text, point);
      return text.split("\n")[lineNumber];
    }
  };

  var offset = function(point, offset) {
    return {
      x: point.x - offset.l,
      y: point.y - offset.t
    };
  };

  exports.mapper = mapper;
})(typeof exports === 'undefined' ? this : exports)
<|endoftext|>


<commit_before>
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 **/

"use strict";

const runner = require("./runner");

function Visitor (callback) {
	this.callback = callback;
};

Visitor.prototype.get_type = function (item) {
	return item.constructor.name;
};

Visitor.prototype.eval = function (skeleton, params) {
	switch (this.get_type(skeleton)) {
		case "Seq":
			this.eval_seq(skeleton, params);
			break;
	}
};

Visitor.prototype.eval_seq  = function (skeleton, params) {
	runner.series(skeleton.execute, params, this.callback);
};

exports.Visitor = function (callback) {
	return new Visitor(callback);
};
<commit_msg>Update visitor.js<commit_after>
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 **/

"use strict";

const runner = require("./runner");

function Visitor (callback) {
	this.callback = callback;
};

Visitor.prototype.get_type = function (item) {
	return item.constructor.name;
};

Visitor.prototype.eval = function (skeleton, params) {
	switch (this.get_type(skeleton)) {
		case "Seq":
			this.eval_seq(skeleton, params);
			break;
		case "Map":
			this.eval_map(skeleton, params);
			break;
	}
};

Visitor.prototype.eval_seq  = function (skeleton, params) {
	runner.series(skeleton.execute, params, this.callback);
};

Visitor.prototype.eval_map  = function (skeleton, params) {
	runner.map(skeleton.execute, params, this.callback);
};

exports.Visitor = function (callback) {
	return new Visitor(callback);
};
<|endoftext|>


<commit_before>module.exports = (function () {
    "use strict";

    var THREE = require("three"),
        TrackballControls = require("../lib/trackball-controls/TrackballControls");

    var Frame = function (elem, graph) {
        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        if (graph._nodes.length < 2) {
            throw "A graph needs at least two nodes";
        }

        this.graph = graph;

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;
        var aspectRatio = width/height;

        this._initScene();
        this._initRenderer(width, height, elem);
        this._initNodes(graph.getNodes());
        this._normalizeNodes();
        this._initEdges(graph.getEdges());

        this._initCamera(aspectRatio);
        this._initControls(elem);

        this.positionCamera();

        this._initMouseEvents(elem);

        this._animate();
    };

    Frame.prototype._initScene = function () {
        this.scene = new THREE.Scene();
    };

    Frame.prototype._initCamera = function (aspect) {
        var self = this;

        var viewAngle = this.graph._fov;
        var camera = new THREE.PerspectiveCamera(viewAngle, aspect);

        this.camera = camera;

        window.addEventListener('resize', function () {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            // TODO this should be the element width/height, not the window
            self.renderer.setSize(window.innerWidth, window.innerHeight);
            self.forceRerender();
        }, false);
    };

    Frame.prototype._initRenderer = function (width, height, elem) {
        var renderer = new THREE.WebGLRenderer({
            antialias: this.graph._antialias,
            alpha: true,
        });
        renderer.setClearColor(this.graph._bgColor, this.graph._bgOpacity);
        renderer.setSize(width, height);
        elem.appendChild(renderer.domElement);

        this.renderer = renderer;
    };

    Frame.prototype.forceRerender = function () {
        this.renderer.render(this.scene, this.camera);
    };

    Frame.prototype._initControls = function (elem) {
        var self = this;
        var controls = new TrackballControls(this.camera, elem);

        controls.addEventListener('change', function () {
            self.forceRerender();
        });

        this.controls = controls;
    };

    Frame.prototype.positionCamera = function () {
        // Calculate optimal camera position
        this.points.computeBoundingSphere();
        var sphere = this.points.boundingSphere;

        var optimalDistance = sphere.radius * 1.5 / Math.tan(this.graph._fov / 2);

        this.camera.position.x = sphere.center.x + optimalDistance;
        this.camera.position.y = sphere.center.y;
        this.camera.position.z = sphere.center.z;

        this.controls.target = sphere.center.clone();
    };

    Frame.prototype._initNodes = function (nodes) {
        var self = this;

        var material = new THREE.PointCloudMaterial({
            size: this.graph._nodeSize,
            vertexColors: true,
            sizeAttenuation: this.graph._sizeAttenuation,
            depthWrite: false,
        });

        if (this.graph._nodeImage !== undefined) {
            var texture = THREE.ImageUtils.loadTexture(
                this.graph._nodeImage, undefined, function () {
                    // Force a rerender after node image has finished loading
                    self.forceRerender();
                });
            material.map = texture;
        }

        var positions = new Float32Array(nodes.length * 3);
        var colors = new Float32Array(nodes.length * 3);
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            var pos = node._pos;
            var color = node._color;

            positions[3 * i] = pos.x;
            positions[3 * i + 1] = pos.y;
            positions[3 * i + 2] = pos.z;

            colors[3 * i] = color.r;
            colors[3 * i + 1] = color.g;
            colors[3 * i + 2] = color.b;
        }
        this.points = new THREE.BufferGeometry();
        this.points.addAttribute(
            'position', new THREE.BufferAttribute(positions, 3));
        this.points.addAttribute(
            'color', new THREE.BufferAttribute(colors, 3));

        this.pointCloud = new THREE.PointCloud(this.points, material);

        if (this.graph._nodeImageTransparent === true) {
            material.transparent = true;
            this.pointCloud.sortParticles = true;
        }

        this.scene.add(this.pointCloud);
    };

    Frame.prototype._normalizeNodes = function () {
        this.points.computeBoundingSphere();

        this.scale = 1 / this.points.boundingSphere.radius;
        var positions = this.points.attributes.position.array;

        for (var i = 0; i < positions.length; i++) {
            positions[i] *= this.scale;
        }
    };

    Frame.prototype._initEdges = function (edges) {
        var material = new THREE.LineBasicMaterial({
            vertexColors: true,
            linewidth: this.graph._edgeWidth,
            opacity: this.graph._edgeOpacity,
            transparent: this.graph._edgeOpacity < 1,
        });

        var positions = new Float32Array(edges.length * 6);
        var colors = new Float32Array(edges.length * 6);
        for (var i = 0; i < edges.length; i++) {
            var nodes = edges[i].getNodes();

            positions[3 * i] =     this.scale * nodes[0]._pos.x;
            positions[3 * i + 1] = this.scale * nodes[0]._pos.y;
            positions[3 * i + 2] = this.scale * nodes[0]._pos.z;

            positions[3 * i + 3] = this.scale * nodes[1]._pos.x;
            positions[3 * i + 4] = this.scale * nodes[1]._pos.y;
            positions[3 * i + 5] = this.scale * nodes[1]._pos.z;

            colors[3 * i] = colors[3 * i + 3] = edges[i]._color.r;
            colors[3 * i + 1] = colors[3 * i + 4] = edges[i]._color.g;
            colors[3 * i + 2] = colors[3 * i + 5] = edges[i]._color.b;
        }

        this.edges = new THREE.BufferGeometry();
        this.edges.addAttribute(
            'position', new THREE.BufferAttribute(positions, 3));
        this.edges.addAttribute(
            'color', new THREE.BufferAttribute(colors, 3));

        this.line = new THREE.Line(this.edges, material, THREE.LinePieces);
        this.scene.add(this.line);
    };

    Frame.prototype._initMouseEvents = function (elem) {
        var createMouseHandler = function (callback) {
            var raycaster = new THREE.Raycaster();

            return function (evt) {
                evt.preventDefault();

                var mouseX = (evt.clientX / window.innerWidth) * 2 - 1;
                var mouseY = 1 - (evt.clientY / window.innerHeight) * 2;

                // Calculate mouse position
                var mousePosition = new THREE.Vector3(mouseX, mouseY, 0.1);
                var radiusPosition = mousePosition.clone();
                mousePosition.unproject(this.camera);

                // Calculate threshold
                var clickRadiusPx = 5;  // 5px
                var radiusX = ((evt.clientX + clickRadiusPx) / window.innerWidth) * 2 - 1;
                radiusPosition.setX(radiusX);
                radiusPosition.unproject(this.camera);

                var clickRadius = radiusPosition.distanceTo(mousePosition);
                var threshold = this.camera.far * clickRadius / this.camera.near;

                raycaster.params.PointCloud.threshold = threshold;

                // Determine intersects
                raycaster.set(this.camera.position, mousePosition.sub(this.camera.position).normalize());
                var intersects = raycaster.intersectObject(this.pointCloud);
                if (intersects.length) {
                    callback(intersects[0]);
                }
            };
        };

        if (this.graph._hover) {
            elem.addEventListener('mousemove', createMouseHandler(this.graph._hover), false);
        }

        if (this.graph._click) {
            elem.addEventListener('click', createMouseHandler(this.graph._click), false);
        }
    };

    Frame.prototype._animate = function () {
        var self = this,
            prevCameraPos;

        // Update near/far camera range
        (function animate() {
            // TODO: this shouldn't update every frame
            var cameraPos = self.camera.position;
            if (cameraPos !== prevCameraPos) {
                var boundingSphere = self.points.boundingSphere;
                var distance = boundingSphere.distanceToPoint(cameraPos);

                if (distance > 0) {
                    self.camera.near = distance;
                    self.camera.far = distance + boundingSphere.radius * 2;
                    self.camera.updateProjectionMatrix();
                }

                prevCameraPos = cameraPos.clone();
            }

            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

    return Frame;
}());
<commit_msg>Fix 'this' errors, correctly pass G.Node to callback<commit_after>module.exports = (function () {
    "use strict";

    var THREE = require("three"),
        TrackballControls = require("../lib/trackball-controls/TrackballControls");

    var Frame = function (elem, graph) {
        if (typeof elem === 'string') {
            elem = document.getElementById(elem);
        }

        if (graph._nodes.length < 2) {
            throw "A graph needs at least two nodes";
        }

        this.graph = graph;

        var width = elem.scrollWidth;
        var height = elem.scrollHeight;
        var aspectRatio = width/height;

        this._initScene();
        this._initRenderer(width, height, elem);
        this._initNodes(graph.getNodes());
        this._normalizeNodes();
        this._initEdges(graph.getEdges());

        this._initCamera(aspectRatio);
        this._initControls(elem);

        this.positionCamera();

        this._initMouseEvents(elem);

        this._animate();
    };

    Frame.prototype._initScene = function () {
        this.scene = new THREE.Scene();
    };

    Frame.prototype._initCamera = function (aspect) {
        var self = this;

        var viewAngle = this.graph._fov;
        var camera = new THREE.PerspectiveCamera(viewAngle, aspect);

        this.camera = camera;

        window.addEventListener('resize', function () {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            // TODO this should be the element width/height, not the window
            self.renderer.setSize(window.innerWidth, window.innerHeight);
            self.forceRerender();
        }, false);
    };

    Frame.prototype._initRenderer = function (width, height, elem) {
        var renderer = new THREE.WebGLRenderer({
            antialias: this.graph._antialias,
            alpha: true,
        });
        renderer.setClearColor(this.graph._bgColor, this.graph._bgOpacity);
        renderer.setSize(width, height);
        elem.appendChild(renderer.domElement);

        this.renderer = renderer;
    };

    Frame.prototype.forceRerender = function () {
        this.renderer.render(this.scene, this.camera);
    };

    Frame.prototype._initControls = function (elem) {
        var self = this;
        var controls = new TrackballControls(this.camera, elem);

        controls.addEventListener('change', function () {
            self.forceRerender();
        });

        this.controls = controls;
    };

    Frame.prototype.positionCamera = function () {
        // Calculate optimal camera position
        this.points.computeBoundingSphere();
        var sphere = this.points.boundingSphere;

        var optimalDistance = sphere.radius * 1.5 / Math.tan(this.graph._fov / 2);

        this.camera.position.x = sphere.center.x + optimalDistance;
        this.camera.position.y = sphere.center.y;
        this.camera.position.z = sphere.center.z;

        this.controls.target = sphere.center.clone();
    };

    Frame.prototype._initNodes = function (nodes) {
        var self = this;

        var material = new THREE.PointCloudMaterial({
            size: this.graph._nodeSize,
            vertexColors: true,
            sizeAttenuation: this.graph._sizeAttenuation,
            depthWrite: false,
        });

        if (this.graph._nodeImage !== undefined) {
            var texture = THREE.ImageUtils.loadTexture(
                this.graph._nodeImage, undefined, function () {
                    // Force a rerender after node image has finished loading
                    self.forceRerender();
                });
            material.map = texture;
        }

        var positions = new Float32Array(nodes.length * 3);
        var colors = new Float32Array(nodes.length * 3);
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            var pos = node._pos;
            var color = node._color;

            positions[3 * i] = pos.x;
            positions[3 * i + 1] = pos.y;
            positions[3 * i + 2] = pos.z;

            colors[3 * i] = color.r;
            colors[3 * i + 1] = color.g;
            colors[3 * i + 2] = color.b;
        }
        this.points = new THREE.BufferGeometry();
        this.points.addAttribute(
            'position', new THREE.BufferAttribute(positions, 3));
        this.points.addAttribute(
            'color', new THREE.BufferAttribute(colors, 3));

        this.pointCloud = new THREE.PointCloud(this.points, material);

        if (this.graph._nodeImageTransparent === true) {
            material.transparent = true;
            this.pointCloud.sortParticles = true;
        }

        this.scene.add(this.pointCloud);
    };

    Frame.prototype._normalizeNodes = function () {
        this.points.computeBoundingSphere();

        this.scale = 1 / this.points.boundingSphere.radius;
        var positions = this.points.attributes.position.array;

        for (var i = 0; i < positions.length; i++) {
            positions[i] *= this.scale;
        }
    };

    Frame.prototype._initEdges = function (edges) {
        var material = new THREE.LineBasicMaterial({
            vertexColors: true,
            linewidth: this.graph._edgeWidth,
            opacity: this.graph._edgeOpacity,
            transparent: this.graph._edgeOpacity < 1,
        });

        var positions = new Float32Array(edges.length * 6);
        var colors = new Float32Array(edges.length * 6);
        for (var i = 0; i < edges.length; i++) {
            var nodes = edges[i].getNodes();

            positions[3 * i] =     this.scale * nodes[0]._pos.x;
            positions[3 * i + 1] = this.scale * nodes[0]._pos.y;
            positions[3 * i + 2] = this.scale * nodes[0]._pos.z;

            positions[3 * i + 3] = this.scale * nodes[1]._pos.x;
            positions[3 * i + 4] = this.scale * nodes[1]._pos.y;
            positions[3 * i + 5] = this.scale * nodes[1]._pos.z;

            colors[3 * i] = colors[3 * i + 3] = edges[i]._color.r;
            colors[3 * i + 1] = colors[3 * i + 4] = edges[i]._color.g;
            colors[3 * i + 2] = colors[3 * i + 5] = edges[i]._color.b;
        }

        this.edges = new THREE.BufferGeometry();
        this.edges.addAttribute(
            'position', new THREE.BufferAttribute(positions, 3));
        this.edges.addAttribute(
            'color', new THREE.BufferAttribute(colors, 3));

        this.line = new THREE.Line(this.edges, material, THREE.LinePieces);
        this.scene.add(this.line);
    };

    Frame.prototype._initMouseEvents = function (elem) {
        var self = this;
        var createMouseHandler = function (callback) {
            var raycaster = new THREE.Raycaster();

            return function (evt) {
                evt.preventDefault();

                var mouseX = (evt.clientX / window.innerWidth) * 2 - 1;
                var mouseY = 1 - (evt.clientY / window.innerHeight) * 2;

                // Calculate mouse position
                var mousePosition = new THREE.Vector3(mouseX, mouseY, 0.1);
                var radiusPosition = mousePosition.clone();
                mousePosition.unproject(self.camera);

                // Calculate threshold
                var clickRadiusPx = 5;  // 5px
                var radiusX = ((evt.clientX + clickRadiusPx) / window.innerWidth) * 2 - 1;
                radiusPosition.setX(radiusX);
                radiusPosition.unproject(self.camera);

                var clickRadius = radiusPosition.distanceTo(mousePosition);
                var threshold = self.camera.far * clickRadius / self.camera.near;

                raycaster.params.PointCloud.threshold = threshold;

                // Determine intersects
                raycaster.set(self.camera.position, mousePosition.sub(self.camera.position).normalize());
                var intersects = raycaster.intersectObject(self.pointCloud);
                if (intersects.length) {
                    var nodeIndex = intersects[0].index;
                    callback(self.graph._nodes[nodeIndex]);
                }
            };
        };

        if (this.graph._hover) {
            elem.addEventListener('mousemove', createMouseHandler(this.graph._hover), false);
        }

        if (this.graph._click) {
            elem.addEventListener('click', createMouseHandler(this.graph._click), false);
        }
    };

    Frame.prototype._animate = function () {
        var self = this,
            prevCameraPos;

        // Update near/far camera range
        (function animate() {
            // TODO: this shouldn't update every frame
            var cameraPos = self.camera.position;
            if (cameraPos !== prevCameraPos) {
                var boundingSphere = self.points.boundingSphere;
                var distance = boundingSphere.distanceToPoint(cameraPos);

                if (distance > 0) {
                    self.camera.near = distance;
                    self.camera.far = distance + boundingSphere.radius * 2;
                    self.camera.updateProjectionMatrix();
                }

                prevCameraPos = cameraPos.clone();
            }

            window.requestAnimationFrame(animate);
            self.controls.update();
        }());
    };

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


<commit_before>var $ = require('zepto-browserify').$
var _ = require('lodash')
var DateTime = require('dateutils').DateTime
var DateFormat = require('dateutils').DateFormat
var DateLocale = require('dateutils').DateLocale
var attachFastClick = require('fastclick')
var navigation = require('./navigation')
attachFastClick(document.body)
var markupForDateRange = require('./markupForDateRange')
var locations = require('../generated/locations')
const format = require('./format')
var didScroll = false
var alreadyLoadingMoreResults = false
var today = DateTime.fromIsoDate(window.serverDate)
var activeDate = today.plusDays(2)
const body = document.body
window.addEventListener('scroll', () => { didScroll = true })
setInterval(() => {
    if (didScroll) {
        didScroll = false
        if (!alreadyLoadingMoreResults && body.scrollTop + window.innerHeight > body.scrollHeight - 400) {
            loadMoreResults(5)
            ga('send', 'event', 'Scroll to end', today.distanceInDays(activeDate))
        }
    }
}, 250)

navigation.init()
listAvailabilityForActiveDate(30)
document.getElementById('schedule').addEventListener('click', e => {
    var reservationModal = document.querySelector('.reservationModal')
    var clickArea = e.target
    var openAction = clickArea.classList.contains('locationLabel')
    if (openAction) {
        var locationBoxes = clickArea.parentNode
        var fields = JSON.parse(locationBoxes.getAttribute('data-fields'))
        reservationModal.innerHTML = reservationModalMarkup(fields)
        reservationModal.style.display = 'block'
    } else if(clickArea.classList.contains('close')) {
        reservationModal.style.display = 'none'
    }
    ga('send', 'event', 'Reservation', openAction ? 'open' : 'close')
})

document.querySelector('.locationMap .close').addEventListener('click', e => e.target.parentNode.style.display = 'none')
document.querySelector('.information .close').addEventListener('click', e => e.target.parentNode.style.display = 'none')

function loadMoreResults(days) {
    if (!alreadyLoadingMoreResults) {
        alreadyLoadingMoreResults = true
        listAvailabilityForActiveDate(days)
    }
}

function reservationModalMarkup(obj) {
    var dateTime = DateTime.fromIsoDate(obj.date)
    var currentLocation = obj.location
    var locationObject = locations.find(location => location.title === currentLocation)
    var address = locationObject.address
    var url = locationObject.url
    var tel = locationObject.tel

    return `
${currentLocation}

${format.formatDate(dateTime)} klo ${obj.time}

Lisää kalenteriin
 ${obj.fields.map(toButtonMarkup).join('')}

Tiedot

        ${linksMarkup(locationObject)}

×
`

    function toButtonMarkup(field) {
        return `${field.field}
${format.formatPrice(field.price)}`
    }
}

function linksMarkup(locationObject) {
    var address = locationObject.address
    var url = locationObject.url
    var tel = locationObject.tel
    return `

${tel}

${address}
` +
        (url ? `<div><a target="_blank" onclick="ga('send', 'event', 'Booking', '${locationObject.title}'); return true;" href="${url}">Siirry varausjärjestelmään</a></div>` : '') + '
'
}

function listAvailabilityForActiveDate(days) {
    var requestedDate = activeDate.toISODateString()
    activeDate = activeDate.plusDays(days - 1)
    document.getElementById('schedule').classList.add('loading')
    alreadyLoadingMoreResults = true
    return $.getJSON(`/courts?date=${requestedDate}&days=${days}&refresh=${window.refresh}`, allDataWithDates => {
        schedule.classList.remove('loading')
        schedule.innerHTML += markupForDateRange(allDataWithDates, today)
        alreadyLoadingMoreResults = false
    })
}
<commit_msg>Use native ajax<commit_after>var _ = require('lodash')
var DateTime = require('dateutils').DateTime
var DateFormat = require('dateutils').DateFormat
var DateLocale = require('dateutils').DateLocale
var attachFastClick = require('fastclick')
var navigation = require('./navigation')
attachFastClick(document.body)
var markupForDateRange = require('./markupForDateRange')
var locations = require('../generated/locations')
const format = require('./format')
var didScroll = false
var alreadyLoadingMoreResults = false
var today = DateTime.fromIsoDate(window.serverDate)
var activeDate = today.plusDays(2)
const body = document.body
window.addEventListener('scroll', () => { didScroll = true })
setInterval(() => {
    if (didScroll) {
        didScroll = false
        if (!alreadyLoadingMoreResults && body.scrollTop + window.innerHeight > body.scrollHeight - 400) {
            loadMoreResults(5)
            ga('send', 'event', 'Scroll to end', today.distanceInDays(activeDate))
        }
    }
}, 250)

navigation.init()
listAvailabilityForActiveDate(30)
document.getElementById('schedule').addEventListener('click', e => {
    var reservationModal = document.querySelector('.reservationModal')
    var clickArea = e.target
    var openAction = clickArea.classList.contains('locationLabel')
    if (openAction) {
        var locationBoxes = clickArea.parentNode
        var fields = JSON.parse(locationBoxes.getAttribute('data-fields'))
        reservationModal.innerHTML = reservationModalMarkup(fields)
        reservationModal.style.display = 'block'
    } else if(clickArea.classList.contains('close')) {
        reservationModal.style.display = 'none'
    }
    ga('send', 'event', 'Reservation', openAction ? 'open' : 'close')
})

document.querySelector('.locationMap .close').addEventListener('click', e => e.target.parentNode.style.display = 'none')
document.querySelector('.information .close').addEventListener('click', e => e.target.parentNode.style.display = 'none')

function loadMoreResults(days) {
    if (!alreadyLoadingMoreResults) {
        alreadyLoadingMoreResults = true
        listAvailabilityForActiveDate(days)
    }
}

function reservationModalMarkup(obj) {
    var dateTime = DateTime.fromIsoDate(obj.date)
    var currentLocation = obj.location
    var locationObject = locations.find(location => location.title === currentLocation)
    var address = locationObject.address
    var url = locationObject.url
    var tel = locationObject.tel

    return `
${currentLocation}

${format.formatDate(dateTime)} klo ${obj.time}

Lisää kalenteriin
 ${obj.fields.map(toButtonMarkup).join('')}

Tiedot

        ${linksMarkup(locationObject)}

×
`

    function toButtonMarkup(field) {
        return `${field.field}
${format.formatPrice(field.price)}`
    }
}

function linksMarkup(locationObject) {
    var address = locationObject.address
    var url = locationObject.url
    var tel = locationObject.tel
    return `

${tel}

${address}
` +
        (url ? `<div><a target="_blank" onclick="ga('send', 'event', 'Booking', '${locationObject.title}'); return true;" href="${url}">Siirry varausjärjestelmään</a></div>` : '') + '
'
}

function listAvailabilityForActiveDate(days) {
    var requestedDate = activeDate.toISODateString()
    activeDate = activeDate.plusDays(days - 1)
    document.getElementById('schedule').classList.add('loading')
    alreadyLoadingMoreResults = true
    getJson(`/courts?date=${requestedDate}&days=${days}&refresh=${window.refresh}`, allDataWithDates => {
        schedule.classList.remove('loading')
        schedule.innerHTML += markupForDateRange(allDataWithDates, today)
        alreadyLoadingMoreResults = false
    })
}

function getJson(url, cb) {
    var request = new XMLHttpRequest()
    request.open('GET', url, true)
    request.onload = () => {
        if (request.status >= 200 && request.status < 400) {
            cb(JSON.parse(request.responseText))
        } else {
            console.error('Error with ajax request')
        }
    }
    request.onerror = () => console.error('There was a connection error of some sort')
    request.send()
}
<|endoftext|>