diff --git a/Gruntfile.js b/Gruntfile.js index b63ad56..6d034b7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,24 +1,24 @@ module.exports = function (grunt) { - grunt.loadNpmTasks("grunt-git-describe") + grunt.loadNpmTasks("grunt-git-describe"); grunt.initConfig({ "git-describe": { options: {}, default: {} } - }) + }); grunt.registerTask("saveRevision", function() { grunt.event.once("git-describe", function (rev) { - grunt.option("gitRevision", rev) - }) - grunt.task.run("git-describe") - }) + grunt.option("gitRevision", rev); + }); + grunt.task.run("git-describe"); + }); - grunt.loadTasks("tasks") + grunt.loadTasks("tasks"); - grunt.registerTask("default", ["bower-install-simple", "lint", "saveRevision", "copy", "sass", "postcss", "requirejs"]) - grunt.registerTask("lint", ["eslint"]) - grunt.registerTask("dev", ["default", "connect:server", "watch"]) -} + grunt.registerTask("default", ["bower-install-simple", "lint", "saveRevision", "copy", "sass", "postcss", "requirejs"]); + grunt.registerTask("lint", ["eslint"]); + grunt.registerTask("dev", ["default", "connect:server", "watch"]); +}; diff --git a/app.js b/app.js index e848121..ef131ef 100644 --- a/app.js +++ b/app.js @@ -29,8 +29,8 @@ require.config({ "tablesort.numeric": ["tablesort"], "helper": ["numeral-intl"] } -}) +}); require(["main", "helper"], function (main) { - getJSON("config.json").then(main) -}) + getJSON("config.json").then(main); +}); diff --git a/build.js b/build.js index 021929a..1295a7d 100644 --- a/build.js +++ b/build.js @@ -6,4 +6,4 @@ wrap: true, optimize: "uglify", out: "app-combined.js" -}) +}); diff --git a/helper.js b/helper.js index e14faf3..949d7d0 100644 --- a/helper.js +++ b/helper.js @@ -51,22 +51,22 @@ function trueDefault(d) { } function dictGet(dict, key) { - var k = key.shift() + var k = key.shift(); if (!(k in dict)) - return null + return null; if (key.length == 0) - return dict[k] + return dict[k]; return dictGet(dict[k], key) } function localStorageTest() { - var test = 'test' + var test = 'test'; try { - localStorage.setItem(test, test) - localStorage.removeItem(test) + localStorage.setItem(test, test); + localStorage.removeItem(test); return true } catch(e) { return false @@ -98,11 +98,11 @@ function has_location(d) { } function subtract(a, b) { - var ids = {} + var ids = {}; b.forEach( function (d) { ids[d.nodeinfo.node_id] = true - }) + }); return a.filter( function (d) { return !(d.nodeinfo.node_id in ids) @@ -113,7 +113,7 @@ function subtract(a, b) { function showDistance(d) { if (isNaN(d.distance)) - return + return; return numeral(d.distance).format("0,0") + " m" } @@ -126,96 +126,96 @@ function showTq(d) { function attributeEntry(el, label, value) { if (value === null || value == undefined) - return + return; - var tr = document.createElement("tr") - var th = document.createElement("th") - th.textContent = label - tr.appendChild(th) + var tr = document.createElement("tr"); + var th = document.createElement("th"); + th.textContent = label; + tr.appendChild(th); - var td = document.createElement("td") + var td = document.createElement("td"); if (typeof value == "function") - value(td) + value(td); else - td.appendChild(document.createTextNode(value)) + td.appendChild(document.createTextNode(value)); - tr.appendChild(td) + tr.appendChild(td); - el.appendChild(tr) + el.appendChild(tr); return td } function createIframe(opt, width, height) { - el = document.createElement("iframe") + el = document.createElement("iframe"); width = typeof width !== 'undefined' ? width : '525px'; height = typeof height !== 'undefined' ? height : '350px'; if (opt.src) - el.src = opt.src + el.src = opt.src; else - el.src = opt + el.src = opt; if (opt.frameBorder) - el.frameBorder = opt.frameBorder + el.frameBorder = opt.frameBorder; else - el.frameBorder = 1 + el.frameBorder = 1; if (opt.width) - el.width = opt.width + el.width = opt.width; else - el.width = width + el.width = width; if (opt.height) - el.height = opt.height + el.height = opt.height; else - el.height = height + el.height = height; - el.scrolling = "no" - el.seamless = "seamless" + el.scrolling = "no"; + el.seamless = "seamless"; return el } function showStat(o, subst) { - var content, caption + var content, caption; subst = typeof subst !== 'undefined' ? subst : {}; if (o.thumbnail) { - content = document.createElement("img") + content = document.createElement("img"); content.src = listReplace(o.thumbnail, subst) } if (o.caption) { - caption = listReplace(o.caption, subst) + caption = listReplace(o.caption, subst); if (!content) content = document.createTextNode(caption) } if (o.iframe) { - content = createIframe(o.iframe, o.width, o.height) + content = createIframe(o.iframe, o.width, o.height); if (o.iframe.src) - content.src = listReplace(o.iframe.src, subst) + content.src = listReplace(o.iframe.src, subst); else content.src = listReplace(o.iframe, subst) } - var p = document.createElement("p") + var p = document.createElement("p"); if (o.href) { - var link = document.createElement("a") - link.target = "_blank" - link.href = listReplace(o.href, subst) - link.appendChild(content) + var link = document.createElement("a"); + link.target = "_blank"; + link.href = listReplace(o.href, subst); + link.appendChild(content); if (caption && o.thumbnail) - link.title = caption + link.title = caption; p.appendChild(link) } else - p.appendChild(content) + p.appendChild(content); return p } diff --git a/lib/about.js b/lib/about.js index 6a44b78..2e80987 100644 --- a/lib/about.js +++ b/lib/about.js @@ -1,38 +1,38 @@ define(function () { return function() { this.render = function (d) { - var el = document.createElement("div") - d.appendChild(el) - var s = "

Über HopGlass

" + var el = document.createElement("div"); + d.appendChild(el); + var s = "

Über HopGlass

"; - s += "

Mit Doppelklick und Shift+Doppelklick kann man in der Karte " - s += "auch zoomen.

" + s += "

Mit Doppelklick und Shift+Doppelklick kann man in der Karte "; + s += "auch zoomen.

"; - s += "

AGPL 3

" + s += "

AGPL 3

"; - s += "

Copyright (C) Milan Pässler

" - s += "

Copyright (C) Nils Schneider

" + s += "

Copyright (C) Milan Pässler

"; + s += "

Copyright (C) Nils Schneider

"; - s += "

This program is free software: you can redistribute it and/or " - s += "modify it under the terms of the GNU Affero General Public " - s += "License as published by the Free Software Foundation, either " - s += "version 3 of the License, or (at your option) any later version.

" + s += "

This program is free software: you can redistribute it and/or "; + s += "modify it under the terms of the GNU Affero General Public "; + s += "License as published by the Free Software Foundation, either "; + s += "version 3 of the License, or (at your option) any later version.

"; - s += "

This program is distributed in the hope that it will be useful, " - s += "but WITHOUT ANY WARRANTY; without even the implied warranty of " - s += "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " - s += "GNU Affero General Public License for more details.

" + s += "

This program is distributed in the hope that it will be useful, "; + s += "but WITHOUT ANY WARRANTY; without even the implied warranty of "; + s += "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "; + s += "GNU Affero General Public License for more details.

"; - s += "

You should have received a copy of the GNU Affero General " - s += "Public License along with this program. If not, see " - s += "" - s += "https://www.gnu.org/licenses/.

" + s += "

You should have received a copy of the GNU Affero General "; + s += "Public License along with this program. If not, see "; + s += ""; + s += "https://www.gnu.org/licenses/.

"; - s += "

The source code is available at " - s += "" - s += "https://github.com/plumpudding/hopglass." + s += "

The source code is available at "; + s += ""; + s += "https://github.com/plumpudding/hopglass."; - el.innerHTML = s - } - } -}) + el.innerHTML = s; + }; + }; +}); diff --git a/lib/container.js b/lib/container.js index a33ab75..cbdb3f5 100644 --- a/lib/container.js +++ b/lib/container.js @@ -1,20 +1,20 @@ define([], function () { return function (tag) { if (!tag) - tag = "div" + tag = "div"; - var self = this + var self = this; - var container = document.createElement(tag) + var container = document.createElement(tag); self.add = function (d) { - d.render(container) - } + d.render(container); + }; self.render = function (el) { - el.appendChild(container) - } + el.appendChild(container); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/datadistributor.js b/lib/datadistributor.js index 67cf7eb..e7df6b8 100644 --- a/lib/datadistributor.js +++ b/lib/datadistributor.js @@ -1,71 +1,71 @@ define(["filters/nodefilter"], function (NodeFilter) { return function () { - var targets = [] - var filterObservers = [] - var filters = [] - var filteredData - var data + var targets = []; + var filterObservers = []; + var filters = []; + var filteredData; + var data; function remove(d) { - targets = targets.filter( function (e) { return d !== e } ) + targets = targets.filter( function (e) { return d !== e; } ); } function add(d) { - targets.push(d) + targets.push(d); if (filteredData !== undefined) - d.setData(filteredData) + d.setData(filteredData); } function setData(d) { - data = d - refresh() + data = d; + refresh(); } function refresh() { if (data === undefined) - return + return; var filter = filters.reduce( function (a, f) { return function (d) { - return a(d) && f.run(d) - } - }, function () { return true }) + return a(d) && f.run(d); + }; + }, function () { return true; }); - filteredData = new NodeFilter(filter)(data) + filteredData = new NodeFilter(filter)(data); targets.forEach( function (t) { - t.setData(filteredData) - }) + t.setData(filteredData); + }); } function notifyObservers() { filterObservers.forEach( function (d) { - d.filtersChanged(filters) - }) + d.filtersChanged(filters); + }); } function addFilter(d) { - filters.push(d) - notifyObservers() - d.setRefresh(refresh) - refresh() + filters.push(d); + notifyObservers(); + d.setRefresh(refresh); + refresh(); } function removeFilter(d) { - filters = filters.filter( function (e) { return d !== e } ) - notifyObservers() - refresh() + filters = filters.filter( function (e) { return d !== e; } ); + notifyObservers(); + refresh(); } function watchFilters(d) { - filterObservers.push(d) + filterObservers.push(d); - d.filtersChanged(filters) + d.filtersChanged(filters); return function () { - filterObservers = filterObservers.filter( function (e) { return d !== e }) - } + filterObservers = filterObservers.filter( function (e) { return d !== e; }); + }; } return { add: add, @@ -75,6 +75,6 @@ define(["filters/nodefilter"], function (NodeFilter) { removeFilter: removeFilter, watchFilters: watchFilters, refresh: refresh - } - } -}) + }; + }; +}); diff --git a/lib/filters/filtergui.js b/lib/filters/filtergui.js index f6c6dac..600deec 100644 --- a/lib/filters/filtergui.js +++ b/lib/filters/filtergui.js @@ -1,40 +1,40 @@ define([], function () { return function (distributor) { - var container = document.createElement("ul") - container.classList.add("filters") - var div = document.createElement("div") + var container = document.createElement("ul"); + container.classList.add("filters"); + var div = document.createElement("div"); function render(el) { - el.appendChild(div) + el.appendChild(div); } function filtersChanged(filters) { while (container.firstChild) - container.removeChild(container.firstChild) + container.removeChild(container.firstChild); filters.forEach( function (d) { - var li = document.createElement("li") - var div = document.createElement("div") - container.appendChild(li) - li.appendChild(div) - d.render(div) + var li = document.createElement("li"); + var div = document.createElement("div"); + container.appendChild(li); + li.appendChild(div); + d.render(div); - var button = document.createElement("button") - button.textContent = "" + var button = document.createElement("button"); + button.textContent = ""; button.onclick = function () { - distributor.removeFilter(d) - } - li.appendChild(button) - }) + distributor.removeFilter(d); + }; + li.appendChild(button); + }); if (container.parentNode === div && filters.length === 0) - div.removeChild(container) + div.removeChild(container); else if (filters.length > 0) - div.appendChild(container) + div.appendChild(container); } return { render: render, filtersChanged: filtersChanged - } - } -}) + }; + }; +}); diff --git a/lib/filters/genericnode.js b/lib/filters/genericnode.js index 4c2a09d..900da26 100644 --- a/lib/filters/genericnode.js +++ b/lib/filters/genericnode.js @@ -1,52 +1,52 @@ define([], function () { return function (name, key, value, f) { - var negate = false - var refresh + var negate = false; + var refresh; - var label = document.createElement("label") - var strong = document.createElement("strong") - label.textContent = name + " " - label.appendChild(strong) + var label = document.createElement("label"); + var strong = document.createElement("strong"); + label.textContent = name + " "; + label.appendChild(strong); function run(d) { - var o = dictGet(d, key.slice(0)) + var o = dictGet(d, key.slice(0)); if (f) - o = f(o) + o = f(o); - return o === value ? !negate : negate + return o === value ? !negate : negate; } function setRefresh(f) { - refresh = f + refresh = f; } function draw(el) { if (negate) - el.parentNode.classList.add("not") + el.parentNode.classList.add("not"); else - el.parentNode.classList.remove("not") + el.parentNode.classList.remove("not"); - strong.textContent = (negate ? "¬" : "" ) + value + strong.textContent = (negate ? "¬" : "" ) + value; } function render(el) { - el.appendChild(label) - draw(el) + el.appendChild(label); + draw(el); label.onclick = function () { - negate = !negate + negate = !negate; - draw(el) + draw(el); if (refresh) - refresh() - } + refresh(); + }; } return { run: run, setRefresh: setRefresh, render: render - } - } -}) + }; + }; +}); diff --git a/lib/filters/nodefilter.js b/lib/filters/nodefilter.js index 319a71e..ac07d7b 100644 --- a/lib/filters/nodefilter.js +++ b/lib/filters/nodefilter.js @@ -1,34 +1,34 @@ define([], function () { return function (filter) { return function (data) { - var n = Object.create(data) - n.nodes = {} + var n = Object.create(data); + n.nodes = {}; for (var key in data.nodes) { - n.nodes[key] = data.nodes[key].filter(filter) + n.nodes[key] = data.nodes[key].filter(filter); } - var filteredIds = new Set() + var filteredIds = new Set(); - n.graph = {} + n.graph = {}; n.graph.nodes = data.graph.nodes.filter( function (d) { - var r + var r; if (d.node) - r = filter(d.node) + r = filter(d.node); else - r = filter({}) + r = filter({}); if (r) - filteredIds.add(d.id) + filteredIds.add(d.id); - return r - }) + return r; + }); n.graph.links = data.graph.links.filter( function (d) { - return filteredIds.has(d.source.id) && filteredIds.has(d.target.id) - }) + return filteredIds.has(d.source.id) && filteredIds.has(d.target.id); + }); - return n - } - } -}) + return n; + }; + }; +}); diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 7d96ce3..bb5af85 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -1,573 +1,573 @@ define(["d3"], function (d3) { - var margin = 200 - var NODE_RADIUS = 15 - var LINE_RADIUS = 12 + var margin = 200; + var NODE_RADIUS = 15; + var LINE_RADIUS = 12; return function (config, linkScale, sidebar, router) { - var self = this - var canvas, ctx, screenRect - var nodesDict, linksDict - var zoomBehavior - var force - var el - var doAnimation = false - var intNodes = [] - var intLinks = [] - var highlight - var highlightedNodes = [] - var highlightedLinks = [] - var nodes = [] - var uplinkNodes = [] - var nonUplinkNodes = [] - var unseenNodes = [] - var unknownNodes = [] - var savedPanZoom + var self = this; + var canvas, ctx, screenRect; + var nodesDict, linksDict; + var zoomBehavior; + var force; + var el; + var doAnimation = false; + var intNodes = []; + var intLinks = []; + var highlight; + var highlightedNodes = []; + var highlightedLinks = []; + var nodes = []; + var uplinkNodes = []; + var nonUplinkNodes = []; + var unseenNodes = []; + var unknownNodes = []; + var savedPanZoom; - var draggedNode + var draggedNode; - var LINK_DISTANCE = 70 + var LINK_DISTANCE = 70; function graphDiameter(nodes) { - return Math.sqrt(nodes.length / Math.PI) * LINK_DISTANCE * 1.41 + return Math.sqrt(nodes.length / Math.PI) * LINK_DISTANCE * 1.41; } function savePositions() { if (!localStorageTest()) - return + return; var save = intNodes.map( function (d) { - return { id: d.o.id, x: d.x, y: d.y } - }) + return { id: d.o.id, x: d.x, y: d.y }; + }); - localStorage.setItem("graph/nodeposition", JSON.stringify(save)) + localStorage.setItem("graph/nodeposition", JSON.stringify(save)); } function nodeName(d) { if (d.o.node && d.o.node.nodeinfo) - return d.o.node.nodeinfo.hostname + return d.o.node.nodeinfo.hostname; else - return d.o.id + return d.o.id; } function dragstart() { - var e = translateXY(d3.mouse(el)) + var e = translateXY(d3.mouse(el)); var nodes = intNodes.filter(function (d) { - return distancePoint(e, d) < NODE_RADIUS - }) + return distancePoint(e, d) < NODE_RADIUS; + }); if (nodes.length === 0) - return + return; - draggedNode = nodes[0] - d3.event.sourceEvent.stopPropagation() - d3.event.sourceEvent.preventDefault() - draggedNode.fixed |= 2 + draggedNode = nodes[0]; + d3.event.sourceEvent.stopPropagation(); + d3.event.sourceEvent.preventDefault(); + draggedNode.fixed |= 2; - draggedNode.px = draggedNode.x - draggedNode.py = draggedNode.y + draggedNode.px = draggedNode.x; + draggedNode.py = draggedNode.y; } function dragmove() { if (draggedNode) { - var e = translateXY(d3.mouse(el)) + var e = translateXY(d3.mouse(el)); - draggedNode.px = e.x - draggedNode.py = e.y - force.resume() + draggedNode.px = e.x; + draggedNode.py = e.y; + force.resume(); } } function dragend() { if (draggedNode) { - d3.event.sourceEvent.stopPropagation() - d3.event.sourceEvent.preventDefault() - draggedNode.fixed &= ~2 - draggedNode = undefined + d3.event.sourceEvent.stopPropagation(); + d3.event.sourceEvent.preventDefault(); + draggedNode.fixed &= ~2; + draggedNode = undefined; } } var draggableNode = d3.behavior.drag() .on("dragstart", dragstart) .on("drag", dragmove) - .on("dragend", dragend) + .on("dragend", dragend); function animatePanzoom(translate, scale) { - var translateP = zoomBehavior.translate() - var scaleP = zoomBehavior.scale() + var translateP = zoomBehavior.translate(); + var scaleP = zoomBehavior.scale(); if (!doAnimation) { - zoomBehavior.translate(translate) - zoomBehavior.scale(scale) - panzoom() + zoomBehavior.translate(translate); + zoomBehavior.scale(scale); + panzoom(); } else { - var start = {x: translateP[0], y: translateP[1], scale: scaleP} - var end = {x: translate[0], y: translate[1], scale: scale} + var start = {x: translateP[0], y: translateP[1], scale: scaleP}; + var end = {x: translate[0], y: translate[1], scale: scale}; - var interpolate = d3.interpolateObject(start, end) - var duration = 500 + var interpolate = d3.interpolateObject(start, end); + var duration = 500; - var ease = d3.ease("cubic-in-out") + var ease = d3.ease("cubic-in-out"); d3.timer(function (t) { if (t >= duration) - return true + return true; - var v = interpolate(ease(t / duration)) - zoomBehavior.translate([v.x, v.y]) - zoomBehavior.scale(v.scale) - panzoom() + var v = interpolate(ease(t / duration)); + zoomBehavior.translate([v.x, v.y]); + zoomBehavior.scale(v.scale); + panzoom(); - return false - }) + return false; + }); } } function onPanZoom() { savedPanZoom = {translate: zoomBehavior.translate(), - scale: zoomBehavior.scale()} - panzoom() + scale: zoomBehavior.scale()}; + panzoom(); } function panzoom() { - var translate = zoomBehavior.translate() - var scale = zoomBehavior.scale() + var translate = zoomBehavior.translate(); + var scale = zoomBehavior.scale(); - panzoomReal(translate, scale) + panzoomReal(translate, scale); } function panzoomReal(translate, scale) { screenRect = {left: -translate[0] / scale, top: -translate[1] / scale, right: (canvas.width - translate[0]) / scale, - bottom: (canvas.height - translate[1]) / scale} + bottom: (canvas.height - translate[1]) / scale}; - requestAnimationFrame(redraw) + requestAnimationFrame(redraw); } function getSize() { - var sidebarWidth = sidebar() - var width = el.offsetWidth - sidebarWidth - var height = el.offsetHeight + var sidebarWidth = sidebar(); + var width = el.offsetWidth - sidebarWidth; + var height = el.offsetHeight; - return [width, height] + return [width, height]; } function panzoomTo(a, b) { - var sidebarWidth = sidebar() - var size = getSize() + var sidebarWidth = sidebar(); + var size = getSize(); - var targetWidth = Math.max(1, b[0] - a[0]) - var targetHeight = Math.max(1, b[1] - a[1]) + var targetWidth = Math.max(1, b[0] - a[0]); + var targetHeight = Math.max(1, b[1] - a[1]); - var scaleX = size[0] / targetWidth - var scaleY = size[1] / targetHeight - var scaleMax = zoomBehavior.scaleExtent()[1] - var scale = 0.5 * Math.min(scaleMax, Math.min(scaleX, scaleY)) + var scaleX = size[0] / targetWidth; + var scaleY = size[1] / targetHeight; + var scaleMax = zoomBehavior.scaleExtent()[1]; + var scale = 0.5 * Math.min(scaleMax, Math.min(scaleX, scaleY)); - var centroid = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2] - var x = -centroid[0] * scale + size[0] / 2 - var y = -centroid[1] * scale + size[1] / 2 - var translate = [x + sidebarWidth, y] + var centroid = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2]; + var x = -centroid[0] * scale + size[0] / 2; + var y = -centroid[1] * scale + size[1] / 2; + var translate = [x + sidebarWidth, y]; - animatePanzoom(translate, scale) + animatePanzoom(translate, scale); } function updateHighlight(nopanzoom) { - highlightedNodes = [] - highlightedLinks = [] + highlightedNodes = []; + highlightedLinks = []; if (highlight !== undefined) if (highlight.type === "node") { - var n = nodesDict[highlight.o.nodeinfo.node_id] + var n = nodesDict[highlight.o.nodeinfo.node_id]; if (n) { - highlightedNodes = [n] + highlightedNodes = [n]; if (!nopanzoom) - panzoomTo([n.x, n.y], [n.x, n.y]) + panzoomTo([n.x, n.y], [n.x, n.y]); } - return + return; } else if (highlight.type === "link") { - var l = linksDict[highlight.o.id] + var l = linksDict[highlight.o.id]; if (l) { - highlightedLinks = [l] + highlightedLinks = [l]; if (!nopanzoom) { - var x = d3.extent([l.source, l.target], function (d) { return d.x }) - var y = d3.extent([l.source, l.target], function (d) { return d.y }) - panzoomTo([x[0], y[0]], [x[1], y[1]]) + var x = d3.extent([l.source, l.target], function (d) { return d.x; }); + var y = d3.extent([l.source, l.target], function (d) { return d.y; }); + panzoomTo([x[0], y[0]], [x[1], y[1]]); } } - return + return; } if (!nopanzoom) if (!savedPanZoom) - panzoomTo([0, 0], force.size()) + panzoomTo([0, 0], force.size()); else - animatePanzoom(savedPanZoom.translate, savedPanZoom.scale) + animatePanzoom(savedPanZoom.translate, savedPanZoom.scale); } function drawLabel(d) { var neighbours = d.neighbours.filter(function (d) { - return d.link.o.type !== "fastd" && d.link.o.type !== "L2TP" - }) + return d.link.o.type !== "fastd" && d.link.o.type !== "L2TP"; + }); var sum = neighbours.reduce(function (a, b) { - return [a[0] + b.node.x, a[1] + b.node.y] - }, [0, 0]) + return [a[0] + b.node.x, a[1] + b.node.y]; + }, [0, 0]); - var sumCos = sum[0] - d.x * neighbours.length - var sumSin = sum[1] - d.y * neighbours.length + var sumCos = sum[0] - d.x * neighbours.length; + var sumSin = sum[1] - d.y * neighbours.length; - var angle = Math.PI / 2 + var angle = Math.PI / 2; if (neighbours.length > 0) - angle = Math.PI + Math.atan2(sumSin, sumCos) + angle = Math.PI + Math.atan2(sumSin, sumCos); - var cos = Math.cos(angle) - var sin = Math.sin(angle) + var cos = Math.cos(angle); + var sin = Math.sin(angle); - var width = d.labelWidth - var height = d.labelHeight + var width = d.labelWidth; + var height = d.labelHeight; - var x = d.x + d.labelA * Math.pow(Math.abs(cos), 2 / 5) * Math.sign(cos) - width / 2 - var y = d.y + d.labelB * Math.pow(Math.abs(sin), 2 / 5) * Math.sign(sin) - height / 2 + var x = d.x + d.labelA * Math.pow(Math.abs(cos), 2 / 5) * Math.sign(cos) - width / 2; + var y = d.y + d.labelB * Math.pow(Math.abs(sin), 2 / 5) * Math.sign(sin) - height / 2; - ctx.drawImage(d.label, x, y, width, height) + ctx.drawImage(d.label, x, y, width, height); } function visibleLinks(d) { return (d.source.x > screenRect.left && d.source.x < screenRect.right && d.source.y > screenRect.top && d.source.y < screenRect.bottom) || (d.target.x > screenRect.left && d.target.x < screenRect.right && - d.target.y > screenRect.top && d.target.y < screenRect.bottom) + d.target.y > screenRect.top && d.target.y < screenRect.bottom); } function visibleNodes(d) { return d.x + margin > screenRect.left && d.x - margin < screenRect.right && - d.y + margin > screenRect.top && d.y - margin < screenRect.bottom + d.y + margin > screenRect.top && d.y - margin < screenRect.bottom; } function drawNode(color, radius, scale, r) { - var node = document.createElement("canvas") - node.width = scale * radius * 8 * r - node.height = node.width + var node = document.createElement("canvas"); + node.width = scale * radius * 8 * r; + node.height = node.width; - var nctx = node.getContext("2d") - nctx.scale(scale * r, scale * r) - nctx.save() + var nctx = node.getContext("2d"); + nctx.scale(scale * r, scale * r); + nctx.save(); - nctx.translate(-node.width / scale, -node.height / scale) - nctx.lineWidth = radius + nctx.translate(-node.width / scale, -node.height / scale); + nctx.lineWidth = radius; - nctx.beginPath() - nctx.moveTo(radius, 0) - nctx.arc(0, 0, radius, 0, 2 * Math.PI) + nctx.beginPath(); + nctx.moveTo(radius, 0); + nctx.arc(0, 0, radius, 0, 2 * Math.PI); - nctx.strokeStyle = "rgba(255, 0, 0, 1)" - nctx.shadowOffsetX = node.width * 1.5 + 0 - nctx.shadowOffsetY = node.height * 1.5 + 3 - nctx.shadowBlur = 12 - nctx.shadowColor = "rgba(0, 0, 0, 0.16)" - nctx.stroke() - nctx.shadowOffsetX = node.width * 1.5 + 0 - nctx.shadowOffsetY = node.height * 1.5 + 3 - nctx.shadowBlur = 12 - nctx.shadowColor = "rgba(0, 0, 0, 0.23)" - nctx.stroke() + nctx.strokeStyle = "rgba(255, 0, 0, 1)"; + nctx.shadowOffsetX = node.width * 1.5 + 0; + nctx.shadowOffsetY = node.height * 1.5 + 3; + nctx.shadowBlur = 12; + nctx.shadowColor = "rgba(0, 0, 0, 0.16)"; + nctx.stroke(); + nctx.shadowOffsetX = node.width * 1.5 + 0; + nctx.shadowOffsetY = node.height * 1.5 + 3; + nctx.shadowBlur = 12; + nctx.shadowColor = "rgba(0, 0, 0, 0.23)"; + nctx.stroke(); - nctx.restore() - nctx.translate(node.width / 2 / scale / r, node.height / 2 / scale / r) + nctx.restore(); + nctx.translate(node.width / 2 / scale / r, node.height / 2 / scale / r); - nctx.beginPath() - nctx.moveTo(radius, 0) - nctx.arc(0, 0, radius, 0, 2 * Math.PI) + nctx.beginPath(); + nctx.moveTo(radius, 0); + nctx.arc(0, 0, radius, 0, 2 * Math.PI); - nctx.strokeStyle = color - nctx.lineWidth = radius - nctx.stroke() + nctx.strokeStyle = color; + nctx.lineWidth = radius; + nctx.stroke(); - return node + return node; } function redraw() { - var r = window.devicePixelRatio - var translate = zoomBehavior.translate() - var scale = zoomBehavior.scale() - var links = intLinks.filter(visibleLinks) + var r = window.devicePixelRatio; + var translate = zoomBehavior.translate(); + var scale = zoomBehavior.scale(); + var links = intLinks.filter(visibleLinks); - ctx.save() - ctx.setTransform(1, 0, 0, 1, 0, 0) - ctx.clearRect(0, 0, canvas.width, canvas.height) - ctx.restore() + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.restore(); - ctx.save() - ctx.translate(translate[0], translate[1]) - ctx.scale(scale, scale) + ctx.save(); + ctx.translate(translate[0], translate[1]); + ctx.scale(scale, scale); - var clientColor = "rgba(230, 50, 75, 1.0)" - var unknownColor = "#D10E2A" - var nonUplinkColor = "#F2E3C6" - var uplinkColor = "#5BAAEB" - var unseenColor = "#FFA726" - var highlightColor = "rgba(252, 227, 198, 0.15)" - var nodeRadius = 6 - var cableColor = "#50B0F0" + var clientColor = "rgba(230, 50, 75, 1.0)"; + var unknownColor = "#D10E2A"; + var nonUplinkColor = "#F2E3C6"; + var uplinkColor = "#5BAAEB"; + var unseenColor = "#FFA726"; + var highlightColor = "rgba(252, 227, 198, 0.15)"; + var nodeRadius = 6; + var cableColor = "#50B0F0"; // -- draw links -- - ctx.save() + ctx.save(); links.forEach(function (d) { - var dx = d.target.x - d.source.x - var dy = d.target.y - d.source.y - var a = Math.sqrt(dx * dx + dy * dy) - dx /= a - dy /= a + var dx = d.target.x - d.source.x; + var dy = d.target.y - d.source.y; + var a = Math.sqrt(dx * dx + dy * dy); + dx /= a; + dy /= a; - ctx.beginPath() - ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius) - ctx.lineTo(d.target.x - dx * nodeRadius, d.target.y - dy * nodeRadius) - ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color - ctx.globalAlpha = d.o.type === "fastd" || d.o.type === "L2TP" ? 0.1 : 0.8 - ctx.lineWidth = d.o.type === "fastd" || d.o.type === "L2TP" ? 1.5 : 2.5 - ctx.stroke() - }) + ctx.beginPath(); + ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius); + ctx.lineTo(d.target.x - dx * nodeRadius, d.target.y - dy * nodeRadius); + ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color; + ctx.globalAlpha = d.o.type === "fastd" || d.o.type === "L2TP" ? 0.1 : 0.8; + ctx.lineWidth = d.o.type === "fastd" || d.o.type === "L2TP" ? 1.5 : 2.5; + ctx.stroke(); + }); - ctx.restore() + ctx.restore(); // -- draw unknown nodes -- - ctx.beginPath() + ctx.beginPath(); unknownNodes.filter(visibleNodes).forEach(function (d) { - ctx.moveTo(d.x + nodeRadius, d.y) - ctx.arc(d.x, d.y, nodeRadius, 0, 2 * Math.PI) - }) + ctx.moveTo(d.x + nodeRadius, d.y); + ctx.arc(d.x, d.y, nodeRadius, 0, 2 * Math.PI); + }); - ctx.strokeStyle = unknownColor - ctx.lineWidth = nodeRadius + ctx.strokeStyle = unknownColor; + ctx.lineWidth = nodeRadius; - ctx.stroke() + ctx.stroke(); // -- draw nodes -- - ctx.save() - ctx.scale(1 / scale / r, 1 / scale / r) + ctx.save(); + ctx.scale(1 / scale / r, 1 / scale / r); - var nonUplinkNode = drawNode(nonUplinkColor, nodeRadius, scale, r) + var nonUplinkNode = drawNode(nonUplinkColor, nodeRadius, scale, r); nonUplinkNodes.filter(visibleNodes).forEach(function (d) { - ctx.drawImage(nonUplinkNode, scale * r * d.x - nonUplinkNode.width / 2, scale * r * d.y - nonUplinkNode.height / 2) - }) + ctx.drawImage(nonUplinkNode, scale * r * d.x - nonUplinkNode.width / 2, scale * r * d.y - nonUplinkNode.height / 2); + }); - var uplinkNode = drawNode(uplinkColor, nodeRadius, scale, r) + var uplinkNode = drawNode(uplinkColor, nodeRadius, scale, r); uplinkNodes.filter(visibleNodes).forEach(function (d) { - ctx.drawImage(uplinkNode, scale * r * d.x - uplinkNode.width / 2, scale * r * d.y - uplinkNode.height / 2) - }) + ctx.drawImage(uplinkNode, scale * r * d.x - uplinkNode.width / 2, scale * r * d.y - uplinkNode.height / 2); + }); - var unseenNode = drawNode(unseenColor, nodeRadius, scale, r) + var unseenNode = drawNode(unseenColor, nodeRadius, scale, r); unseenNodes.filter(visibleNodes).forEach(function (d) { - ctx.drawImage(unseenNode, scale * r * d.x - unseenNode.width / 2, scale * r * d.y - unseenNode.height / 2) - }) + ctx.drawImage(unseenNode, scale * r * d.x - unseenNode.width / 2, scale * r * d.y - unseenNode.height / 2); + }); - ctx.restore() + ctx.restore(); // -- draw clients -- - ctx.save() - ctx.beginPath() + ctx.save(); + ctx.beginPath(); nodes.filter(visibleNodes).forEach(function (d) { - var clients = d.o.node.statistics.clients + var clients = d.o.node.statistics.clients; if (clients === 0) - return + return; - var startDistance = 16 - var radius = 3 - var a = 1.2 - var startAngle = Math.PI + var startDistance = 16; + var radius = 3; + var a = 1.2; + var startAngle = Math.PI; for (var orbit = 0, i = 0; i < clients; orbit++) { - var distance = startDistance + orbit * 2 * radius * a - var n = Math.floor((Math.PI * distance) / (a * radius)) - var delta = clients - i + var distance = startDistance + orbit * 2 * radius * a; + var n = Math.floor((Math.PI * distance) / (a * radius)); + var delta = clients - i; for (var j = 0; j < Math.min(delta, n); i++, j++) { - var angle = 2 * Math.PI / n * j - var x = d.x + distance * Math.cos(angle + startAngle) - var y = d.y + distance * Math.sin(angle + startAngle) + var angle = 2 * Math.PI / n * j; + var x = d.x + distance * Math.cos(angle + startAngle); + var y = d.y + distance * Math.sin(angle + startAngle); - ctx.moveTo(x, y) - ctx.arc(x, y, radius, 0, 2 * Math.PI) + ctx.moveTo(x, y); + ctx.arc(x, y, radius, 0, 2 * Math.PI); } } - }) + }); - ctx.fillStyle = clientColor - ctx.fill() - ctx.restore() + ctx.fillStyle = clientColor; + ctx.fill(); + ctx.restore(); // -- draw node highlights -- if (highlightedNodes.length) { - ctx.save() - ctx.shadowColor = "rgba(255, 255, 255, 1.0)" - ctx.shadowBlur = 10 * nodeRadius - ctx.shadowOffsetX = 0 - ctx.shadowOffsetY = 0 - ctx.globalCompositeOperation = "lighten" - ctx.fillStyle = highlightColor + ctx.save(); + ctx.shadowColor = "rgba(255, 255, 255, 1.0)"; + ctx.shadowBlur = 10 * nodeRadius; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.globalCompositeOperation = "lighten"; + ctx.fillStyle = highlightColor; - ctx.beginPath() + ctx.beginPath(); highlightedNodes.forEach(function (d) { - ctx.moveTo(d.x + 5 * nodeRadius, d.y) - ctx.arc(d.x, d.y, 5 * nodeRadius, 0, 2 * Math.PI) - }) - ctx.fill() + ctx.moveTo(d.x + 5 * nodeRadius, d.y); + ctx.arc(d.x, d.y, 5 * nodeRadius, 0, 2 * Math.PI); + }); + ctx.fill(); - ctx.restore() + ctx.restore(); } // -- draw link highlights -- if (highlightedLinks.length) { - ctx.save() - ctx.lineWidth = 2 * 5 * nodeRadius - ctx.shadowColor = "rgba(255, 255, 255, 1.0)" - ctx.shadowBlur = 10 * nodeRadius - ctx.shadowOffsetX = 0 - ctx.shadowOffsetY = 0 - ctx.globalCompositeOperation = "lighten" - ctx.strokeStyle = highlightColor - ctx.lineCap = "round" + ctx.save(); + ctx.lineWidth = 2 * 5 * nodeRadius; + ctx.shadowColor = "rgba(255, 255, 255, 1.0)"; + ctx.shadowBlur = 10 * nodeRadius; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.globalCompositeOperation = "lighten"; + ctx.strokeStyle = highlightColor; + ctx.lineCap = "round"; - ctx.beginPath() + ctx.beginPath(); highlightedLinks.forEach(function (d) { - ctx.moveTo(d.source.x, d.source.y) - ctx.lineTo(d.target.x, d.target.y) - }) - ctx.stroke() + ctx.moveTo(d.source.x, d.source.y); + ctx.lineTo(d.target.x, d.target.y); + }); + ctx.stroke(); - ctx.restore() + ctx.restore(); } // -- draw labels -- if (scale > 0.9) - intNodes.filter(visibleNodes).forEach(drawLabel, scale) + intNodes.filter(visibleNodes).forEach(drawLabel, scale); - ctx.restore() + ctx.restore(); } function tickEvent() { - redraw() + redraw(); } function resizeCanvas() { - var r = window.devicePixelRatio - canvas.width = el.offsetWidth * r - canvas.height = el.offsetHeight * r - canvas.style.width = el.offsetWidth + "px" - canvas.style.height = el.offsetHeight + "px" - ctx.setTransform(1, 0, 0, 1, 0, 0) - ctx.scale(r, r) - requestAnimationFrame(redraw) + var r = window.devicePixelRatio; + canvas.width = el.offsetWidth * r; + canvas.height = el.offsetHeight * r; + canvas.style.width = el.offsetWidth + "px"; + canvas.style.height = el.offsetHeight + "px"; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.scale(r, r); + requestAnimationFrame(redraw); } function distance(a, b) { - return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2) + return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2); } function distancePoint(a, b) { - return Math.sqrt(distance(a, b)) + return Math.sqrt(distance(a, b)); } function distanceLink(p, a, b) { /* http://stackoverflow.com/questions/849211 */ - var l2 = distance(a, b) + var l2 = distance(a, b); if (l2 === 0) - return distance(p, a) + return distance(p, a); - var t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / l2 + var t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / l2; if (t < 0) - return distance(p, a) + return distance(p, a); if (t > 1) - return distance(p, b) + return distance(p, b); return Math.sqrt(distance(p, { x: a.x + t * (b.x - a.x), - y: a.y + t * (b.y - a.y) })) + y: a.y + t * (b.y - a.y) })); } function translateXY(d) { - var translate = zoomBehavior.translate() - var scale = zoomBehavior.scale() + var translate = zoomBehavior.translate(); + var scale = zoomBehavior.scale(); return {x: (d[0] - translate[0]) / scale, y: (d[1] - translate[1]) / scale - } + }; } function onClick() { if (d3.event.defaultPrevented) - return + return; - var e = translateXY(d3.mouse(el)) + var e = translateXY(d3.mouse(el)); var nodes = intNodes.filter(function (d) { - return distancePoint(e, d) < NODE_RADIUS - }) + return distancePoint(e, d) < NODE_RADIUS; + }); if (nodes.length > 0) { - router.node(nodes[0].o.node)() - return + router.node(nodes[0].o.node)(); + return; } var links = intLinks.filter(function (d) { - return d.o.type !== "fastd" && d.o.type !== "L2TP" + return d.o.type !== "fastd" && d.o.type !== "L2TP"; }).filter(function (d) { - return distanceLink(e, d.source, d.target) < LINE_RADIUS - }) + return distanceLink(e, d.source, d.target) < LINE_RADIUS; + }); if (links.length > 0) { - router.link(links[0].o)() - return + router.link(links[0].o)(); + return; } } function zoom(z, scale) { - var size = getSize() - var newSize = [size[0] / scale, size[1] / scale] + var size = getSize(); + var newSize = [size[0] / scale, size[1] / scale]; - var sidebarWidth = sidebar() - var delta = [size[0] - newSize[0], size[1] - newSize[1]] - var translate = z.translate() - var translateNew = [sidebarWidth + (translate[0] - sidebarWidth - delta[0] / 2) * scale, (translate[1] - delta[1] / 2) * scale] + var sidebarWidth = sidebar(); + var delta = [size[0] - newSize[0], size[1] - newSize[1]]; + var translate = z.translate(); + var translateNew = [sidebarWidth + (translate[0] - sidebarWidth - delta[0] / 2) * scale, (translate[1] - delta[1] / 2) * scale]; - animatePanzoom(translateNew, z.scale() * scale) + animatePanzoom(translateNew, z.scale() * scale); } function keyboardZoom(z) { return function () { - var e = d3.event + var e = d3.event; if (e.altKey || e.ctrlKey || e.metaKey) - return + return; if (e.keyCode === 43) - zoom(z, 1.41) + zoom(z, 1.41); if (e.keyCode === 45) - zoom(z, 1 / 1.41) - } + zoom(z, 1 / 1.41); + }; } - el = document.createElement("div") - el.classList.add("graph") + el = document.createElement("div"); + el.classList.add("graph"); zoomBehavior = d3.behavior.zoom() .scaleExtent([1 / 3, 3]) .on("zoom", onPanZoom) - .translate([sidebar(), 0]) + .translate([sidebar(), 0]); canvas = d3.select(el) .attr("tabindex", 1) @@ -576,201 +576,201 @@ define(["d3"], function (d3) { .append("canvas") .on("click", onClick) .call(draggableNode) - .node() + .node(); - ctx = canvas.getContext("2d") + ctx = canvas.getContext("2d"); force = d3.layout.force() .charge(-250) .gravity(0.1) .linkDistance(function (d) { if (d.o.type === "fastd" || d.o.type === "L2TP") - return 0 + return 0; else - return LINK_DISTANCE + return LINK_DISTANCE; }) .linkStrength(function (d) { if (d.o.type === "fastd" || d.o.type === "L2TP") - return 0 + return 0; else - return Math.max(0.5, 1 / d.o.tq) + return Math.max(0.5, 1 / d.o.tq); }) .on("tick", tickEvent) - .on("end", savePositions) + .on("end", savePositions); - window.addEventListener("resize", resizeCanvas) + window.addEventListener("resize", resizeCanvas); - panzoom() + panzoom(); self.setData = function (data) { - var oldNodes = {} + var oldNodes = {}; intNodes.forEach( function (d) { - oldNodes[d.o.id] = d - }) + oldNodes[d.o.id] = d; + }); intNodes = data.graph.nodes.map( function (d) { - var e + var e; if (d.id in oldNodes) - e = oldNodes[d.id] + e = oldNodes[d.id]; else - e = {} + e = {}; - e.o = d + e.o = d; - return e - }) + return e; + }); - var newNodesDict = {} + var newNodesDict = {}; intNodes.forEach( function (d) { - newNodesDict[d.o.id] = d - }) + newNodesDict[d.o.id] = d; + }); - var oldLinks = {} + var oldLinks = {}; intLinks.forEach( function (d) { - oldLinks[d.o.id] = d - }) + oldLinks[d.o.id] = d; + }); intLinks = data.graph.links.map( function (d) { - var e + var e; if (d.id in oldLinks) - e = oldLinks[d.id] + e = oldLinks[d.id]; else - e = {} + e = {}; - e.o = d - e.source = newNodesDict[d.source.id] - e.target = newNodesDict[d.target.id] + e.o = d; + e.source = newNodesDict[d.source.id]; + e.target = newNodesDict[d.target.id]; if (d.type === "fastd" || d.type === "L2TP") - e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")" + e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")"; else - e.color = linkScale(d.tq).hex() + e.color = linkScale(d.tq).hex(); - return e - }) + return e; + }); - linksDict = {} - nodesDict = {} + linksDict = {}; + nodesDict = {}; intNodes.forEach(function (d) { - d.neighbours = {} + d.neighbours = {}; if (d.o.node) - nodesDict[d.o.node.nodeinfo.node_id] = d + nodesDict[d.o.node.nodeinfo.node_id] = d; - var name = nodeName(d) + var name = nodeName(d); - var offset = 5 - var lineWidth = 3 - var buffer = document.createElement("canvas") - var r = window.devicePixelRatio - var bctx = buffer.getContext("2d") - bctx.font = "11px Roboto" - var width = bctx.measureText(name).width - var scale = zoomBehavior.scaleExtent()[1] * r - buffer.width = (width + 2 * lineWidth) * scale - buffer.height = (16 + 2 * lineWidth) * scale - bctx.scale(scale, scale) - bctx.textBaseline = "middle" - bctx.textAlign = "center" - bctx.fillStyle = "rgba(242, 227, 198, 1.0)" - bctx.shadowColor = "rgba(0, 0, 0, 1)" - bctx.shadowBlur = 5 - bctx.fillText(name, buffer.width / (2 * scale), buffer.height / (2 * scale)) + var offset = 5; + var lineWidth = 3; + var buffer = document.createElement("canvas"); + var r = window.devicePixelRatio; + var bctx = buffer.getContext("2d"); + bctx.font = "11px Roboto"; + var width = bctx.measureText(name).width; + var scale = zoomBehavior.scaleExtent()[1] * r; + buffer.width = (width + 2 * lineWidth) * scale; + buffer.height = (16 + 2 * lineWidth) * scale; + bctx.scale(scale, scale); + bctx.textBaseline = "middle"; + bctx.textAlign = "center"; + bctx.fillStyle = "rgba(242, 227, 198, 1.0)"; + bctx.shadowColor = "rgba(0, 0, 0, 1)"; + bctx.shadowBlur = 5; + bctx.fillText(name, buffer.width / (2 * scale), buffer.height / (2 * scale)); - d.label = buffer - d.labelWidth = buffer.width / scale - d.labelHeight = buffer.height / scale - d.labelA = offset + buffer.width / (2 * scale) - d.labelB = offset + buffer.height / (2 * scale) - }) + d.label = buffer; + d.labelWidth = buffer.width / scale; + d.labelHeight = buffer.height / scale; + d.labelA = offset + buffer.width / (2 * scale); + d.labelB = offset + buffer.height / (2 * scale); + }); intLinks.forEach(function (d) { - d.source.neighbours[d.target.o.id] = {node: d.target, link: d} - d.target.neighbours[d.source.o.id] = {node: d.source, link: d} + d.source.neighbours[d.target.o.id] = {node: d.target, link: d}; + d.target.neighbours[d.source.o.id] = {node: d.source, link: d}; if (d.o.source && d.o.target) - linksDict[d.o.id] = d - }) + linksDict[d.o.id] = d; + }); intNodes.forEach(function (d) { d.neighbours = Object.keys(d.neighbours).map(function (k) { - return d.neighbours[k] - }) - }) + return d.neighbours[k]; + }); + }); - nodes = intNodes.filter(function (d) { return !d.o.unseen && d.o.node }) - uplinkNodes = nodes.filter(function (d) { return d.o.node.flags.uplink }) - nonUplinkNodes = nodes.filter(function (d) { return !d.o.node.flags.uplink }) - unseenNodes = intNodes.filter(function (d) { return d.o.unseen && d.o.node }) - unknownNodes = intNodes.filter(function (d) { return !d.o.node }) + nodes = intNodes.filter(function (d) { return !d.o.unseen && d.o.node; }); + uplinkNodes = nodes.filter(function (d) { return d.o.node.flags.uplink; }); + nonUplinkNodes = nodes.filter(function (d) { return !d.o.node.flags.uplink; }); + unseenNodes = intNodes.filter(function (d) { return d.o.unseen && d.o.node; }); + unknownNodes = intNodes.filter(function (d) { return !d.o.node; }); if (localStorageTest()) { - var save = JSON.parse(localStorage.getItem("graph/nodeposition")) + var save = JSON.parse(localStorage.getItem("graph/nodeposition")); if (save) { - var nodePositions = {} + var nodePositions = {}; save.forEach( function (d) { - nodePositions[d.id] = d - }) + nodePositions[d.id] = d; + }); intNodes.forEach( function (d) { if (nodePositions[d.o.id] && (d.x === undefined || d.y === undefined)) { - d.x = nodePositions[d.o.id].x - d.y = nodePositions[d.o.id].y + d.x = nodePositions[d.o.id].x; + d.y = nodePositions[d.o.id].y; } - }) + }); } } - var diameter = graphDiameter(intNodes) + var diameter = graphDiameter(intNodes); force.nodes(intNodes) .links(intLinks) - .size([diameter, diameter]) + .size([diameter, diameter]); - updateHighlight(true) + updateHighlight(true); - force.start() - resizeCanvas() - } + force.start(); + resizeCanvas(); + }; self.resetView = function () { - highlight = undefined - updateHighlight() - doAnimation = true - } + highlight = undefined; + updateHighlight(); + doAnimation = true; + }; self.gotoNode = function (d) { - highlight = {type: "node", o: d} - updateHighlight() - doAnimation = true - } + highlight = {type: "node", o: d}; + updateHighlight(); + doAnimation = true; + }; self.gotoLink = function (d) { - highlight = {type: "link", o: d} - updateHighlight() - doAnimation = true - } + highlight = {type: "link", o: d}; + updateHighlight(); + doAnimation = true; + }; self.destroy = function () { - force.stop() - canvas.remove() - force = null + force.stop(); + canvas.remove(); + force = null; if (el.parentNode) - el.parentNode.removeChild(el) - } + el.parentNode.removeChild(el); + }; self.render = function (d) { - d.appendChild(el) - resizeCanvas() - updateHighlight() - } + d.appendChild(el); + resizeCanvas(); + updateHighlight(); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/gui.js b/lib/gui.js index 4ce989d..d8b3052 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -6,117 +6,117 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, Nodelist, SimpleNodelist, Infobox, Proportions, ForceGraph, Title, About, DataDistributor, FilterGUI) { return function (config, router) { - var self = this - var content - var contentDiv + var self = this; + var content; + var contentDiv; - var linkScale = chroma.scale(chroma.interpolate.bezier(["#04C714", "#FF5500", "#F02311"])).domain([1, 5]) - var sidebar + var linkScale = chroma.scale(chroma.interpolate.bezier(["#04C714", "#FF5500", "#F02311"])).domain([1, 5]); + var sidebar; - var buttons = document.createElement("div") - buttons.classList.add("buttons") + var buttons = document.createElement("div"); + buttons.classList.add("buttons"); - var fanout = new DataDistributor() - var fanoutUnfiltered = new DataDistributor() - fanoutUnfiltered.add(fanout) + var fanout = new DataDistributor(); + var fanoutUnfiltered = new DataDistributor(); + fanoutUnfiltered.add(fanout); function removeContent() { if (!content) - return + return; - router.removeTarget(content) - fanout.remove(content) + router.removeTarget(content); + fanout.remove(content); - content.destroy() + content.destroy(); - content = null + content = null; } function addContent(K) { - removeContent() + removeContent(); - content = new K(config, linkScale, sidebar.getWidth, router, buttons) - content.render(contentDiv) + content = new K(config, linkScale, sidebar.getWidth, router, buttons); + content.render(contentDiv); - fanout.add(content) - router.addTarget(content) + fanout.add(content); + router.addTarget(content); } function mkView(K) { return function () { - addContent(K) - } + addContent(K); + }; } - contentDiv = document.createElement("div") - contentDiv.classList.add("content") - document.body.appendChild(contentDiv) + contentDiv = document.createElement("div"); + contentDiv.classList.add("content"); + document.body.appendChild(contentDiv); - sidebar = new Sidebar(document.body) + sidebar = new Sidebar(document.body); - contentDiv.appendChild(buttons) + contentDiv.appendChild(buttons); - var buttonToggle = document.createElement("button") - buttonToggle.textContent = "\uF133" + var buttonToggle = document.createElement("button"); + buttonToggle.textContent = "\uF133"; buttonToggle.onclick = function () { if (content.constructor === Map) - router.view("g") + router.view("g"); else - router.view("m") - } + router.view("m"); + }; - buttons.appendChild(buttonToggle) + buttons.appendChild(buttonToggle); - var title = new Title(config) + var title = new Title(config); - var header = new Container("header") - var infobox = new Infobox(config, sidebar, router) - var tabs = new Tabs() - var overview = new Container() - var meshstats = new Meshstats(config) - var legend = new Legend() - var newnodeslist = new SimpleNodelist("new", "firstseen", router, "Neue Knoten") - var lostnodeslist = new SimpleNodelist("lost", "lastseen", router, "Verschwundene Knoten") - var nodelist = new Nodelist(router) - var linklist = new Linklist(linkScale, router) - var statistics = new Proportions(config, fanout) - var about = new About() + var header = new Container("header"); + var infobox = new Infobox(config, sidebar, router); + var tabs = new Tabs(); + var overview = new Container(); + var meshstats = new Meshstats(config); + var legend = new Legend(); + var newnodeslist = new SimpleNodelist("new", "firstseen", router, "Neue Knoten"); + var lostnodeslist = new SimpleNodelist("lost", "lastseen", router, "Verschwundene Knoten"); + var nodelist = new Nodelist(router); + var linklist = new Linklist(linkScale, router); + var statistics = new Proportions(config, fanout); + var about = new About(); - fanoutUnfiltered.add(meshstats) - fanoutUnfiltered.add(newnodeslist) - fanoutUnfiltered.add(lostnodeslist) - fanout.add(nodelist) - fanout.add(linklist) - fanout.add(statistics) + fanoutUnfiltered.add(meshstats); + fanoutUnfiltered.add(newnodeslist); + fanoutUnfiltered.add(lostnodeslist); + fanout.add(nodelist); + fanout.add(linklist); + fanout.add(statistics); - sidebar.add(header) - header.add(meshstats) - header.add(legend) + sidebar.add(header); + header.add(meshstats); + header.add(legend); - overview.add(newnodeslist) - overview.add(lostnodeslist) + overview.add(newnodeslist); + overview.add(lostnodeslist); - var filterGUI = new FilterGUI(fanout) - fanout.watchFilters(filterGUI) - header.add(filterGUI) + var filterGUI = new FilterGUI(fanout); + fanout.watchFilters(filterGUI); + header.add(filterGUI); - sidebar.add(tabs) - tabs.add("Aktuelles", overview) - tabs.add("Knoten", nodelist) - tabs.add("Verbindungen", linklist) - tabs.add("Statistiken", statistics) - tabs.add("Über", about) + sidebar.add(tabs); + tabs.add("Aktuelles", overview); + tabs.add("Knoten", nodelist); + tabs.add("Verbindungen", linklist); + tabs.add("Statistiken", statistics); + tabs.add("Über", about); - router.addTarget(title) - router.addTarget(infobox) + router.addTarget(title); + router.addTarget(infobox); - router.addView("m", mkView(Map)) - router.addView("g", mkView(ForceGraph)) + router.addView("m", mkView(Map)); + router.addView("g", mkView(ForceGraph)); - router.view("m") + router.view("m"); - self.setData = fanoutUnfiltered.setData + self.setData = fanoutUnfiltered.setData; - return self - } -}) + return self; + }; +}); diff --git a/lib/infobox/link.js b/lib/infobox/link.js index 794753a..a57efd8 100644 --- a/lib/infobox/link.js +++ b/lib/infobox/link.js @@ -1,49 +1,49 @@ define(function () { function showStatImg(o, source, target) { - var subst = {} - subst["{SOURCE}"] = source - subst["{TARGET}"] = target - return showStat(o, subst) + var subst = {}; + subst["{SOURCE}"] = source; + subst["{TARGET}"] = target; + return showStat(o, subst); } return function (config, el, router, d) { - var unknown = !(d.source.node) - var h2 = document.createElement("h2") - var a1 = document.createElement("a") + var unknown = !(d.source.node); + var h2 = document.createElement("h2"); + var a1 = document.createElement("a"); if (!unknown) { - a1.href = "#" - a1.onclick = router.node(d.source.node) + a1.href = "#"; + a1.onclick = router.node(d.source.node); } - a1.textContent = unknown ? d.source.id : d.source.node.nodeinfo.hostname - h2.appendChild(a1) - h2.appendChild(document.createTextNode(" → ")) - var a2 = document.createElement("a") - a2.href = "#" - a2.onclick = router.node(d.target.node) - a2.textContent = d.target.node.nodeinfo.hostname - h2.appendChild(a2) - el.appendChild(h2) + a1.textContent = unknown ? d.source.id : d.source.node.nodeinfo.hostname; + h2.appendChild(a1); + h2.appendChild(document.createTextNode(" → ")); + var a2 = document.createElement("a"); + a2.href = "#"; + a2.onclick = router.node(d.target.node); + a2.textContent = d.target.node.nodeinfo.hostname; + h2.appendChild(a2); + el.appendChild(h2); - var attributes = document.createElement("table") - attributes.classList.add("attributes") + var attributes = document.createElement("table"); + attributes.classList.add("attributes"); - attributeEntry(attributes, "TQ", showTq(d)) - attributeEntry(attributes, "Entfernung", showDistance(d)) - attributeEntry(attributes, "Typ", d.type) - var hw1 = unknown ? null : dictGet(d.source.node.nodeinfo, ["hardware", "model"]) - var hw2 = dictGet(d.target.node.nodeinfo, ["hardware", "model"]) - attributeEntry(attributes, "Hardware", (hw1 != null ? hw1 : "unbekannt") + " – " + (hw2 != null ? hw2 : "unbekannt")) - el.appendChild(attributes) + attributeEntry(attributes, "TQ", showTq(d)); + attributeEntry(attributes, "Entfernung", showDistance(d)); + attributeEntry(attributes, "Typ", d.type); + var hw1 = unknown ? null : dictGet(d.source.node.nodeinfo, ["hardware", "model"]); + var hw2 = dictGet(d.target.node.nodeinfo, ["hardware", "model"]); + attributeEntry(attributes, "Hardware", (hw1 != null ? hw1 : "unbekannt") + " – " + (hw2 != null ? hw2 : "unbekannt")); + el.appendChild(attributes); if (config.linkInfos) { - var source = d.source.node_id - var target = d.target.node_id + var source = d.source.node_id; + var target = d.target.node_id; config.linkInfos.forEach( function (linkInfo) { - var h4 = document.createElement("h4") - h4.textContent = linkInfo.name - el.appendChild(h4) - el.appendChild(showStatImg(linkInfo, source, target)) - }) + var h4 = document.createElement("h4"); + h4.textContent = linkInfo.name; + el.appendChild(h4); + el.appendChild(showStatImg(linkInfo, source, target)); + }); } - } -}) + }; +}); diff --git a/lib/infobox/location.js b/lib/infobox/location.js index 08805b0..a9c3034 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -1,100 +1,100 @@ define(function () { return function (config, el, router, d) { - var sidebarTitle = document.createElement("h2") - sidebarTitle.textContent = "Location: " + d.toString() - el.appendChild(sidebarTitle) + var sidebarTitle = document.createElement("h2"); + sidebarTitle.textContent = "Location: " + d.toString(); + el.appendChild(sidebarTitle); getJSON("https://nominatim.openstreetmap.org/reverse?format=json&lat=" + d.lat + "&lon=" + d.lng + "&zoom=18&addressdetails=0") .then(function(result) { if(result.display_name) - sidebarTitle.textContent = result.display_name - }) + sidebarTitle.textContent = result.display_name; + }); - var editLat = document.createElement("input") - editLat.type = "text" - editLat.value = d.lat.toFixed(9) - el.appendChild(createBox("lat", "Breitengrad", editLat)) + var editLat = document.createElement("input"); + editLat.type = "text"; + editLat.value = d.lat.toFixed(9); + el.appendChild(createBox("lat", "Breitengrad", editLat)); - var editLng = document.createElement("input") - editLng.type = "text" - editLng.value = d.lng.toFixed(9) - el.appendChild(createBox("lng", "Längengrad", editLng)) + var editLng = document.createElement("input"); + editLng.type = "text"; + editLng.value = d.lng.toFixed(9); + el.appendChild(createBox("lng", "Längengrad", editLng)); - var editUci = document.createElement("textarea") + var editUci = document.createElement("textarea"); editUci.value = "uci set gluon-node-info.@location[0]='location'; " + "uci set gluon-node-info.@location[0].share_location='1';" + "uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "';" + "uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "';" + - "uci commit gluon-node-info" + "uci commit gluon-node-info"; - el.appendChild(createBox("uci", "Befehl", editUci, false)) + el.appendChild(createBox("uci", "Befehl", editUci, false)); - var linkPlain = document.createElement("a") - linkPlain.textContent = "plain" + var linkPlain = document.createElement("a"); + linkPlain.textContent = "plain"; linkPlain.onclick = function() { - switch2plain() - return false - } - linkPlain.href = "#" + switch2plain(); + return false; + }; + linkPlain.href = "#"; - var linkUci = document.createElement("a") - linkUci.textContent = "uci" + var linkUci = document.createElement("a"); + linkUci.textContent = "uci"; linkUci.onclick = function() { - switch2uci() - return false - } - linkUci.href = "#" + switch2uci(); + return false; + }; + linkUci.href = "#"; - var hintText = document.createElement("p") - hintText.appendChild(document.createTextNode("Du kannst zwischen ")) - hintText.appendChild(linkPlain) - hintText.appendChild(document.createTextNode(" und ")) - hintText.appendChild(linkUci) - hintText.appendChild(document.createTextNode(" wechseln.")) - el.appendChild(hintText) + var hintText = document.createElement("p"); + hintText.appendChild(document.createTextNode("Du kannst zwischen ")); + hintText.appendChild(linkPlain); + hintText.appendChild(document.createTextNode(" und ")); + hintText.appendChild(linkUci); + hintText.appendChild(document.createTextNode(" wechseln.")); + el.appendChild(hintText); function createBox(name, title, inputElem, isVisible) { - var visible = typeof isVisible !== "undefined" ? isVisible : true - var box = document.createElement("div") - var heading = document.createElement("h3") - heading.textContent = title - box.appendChild(heading) - var btn = document.createElement("button") - btn.className = "ion-ios-copy" - btn.title = "Kopieren" - btn.onclick = function() { copy2clip(inputElem.id) } - inputElem.id = "location-" + name - inputElem.readOnly = true - var line = document.createElement("p") - line.appendChild(inputElem) - line.appendChild(btn) - box.appendChild(line) - box.id = "box-" + name - box.style.display = visible ? "block" : "none" - return box + var visible = typeof isVisible !== "undefined" ? isVisible : true; + var box = document.createElement("div"); + var heading = document.createElement("h3"); + heading.textContent = title; + box.appendChild(heading); + var btn = document.createElement("button"); + btn.className = "ion-ios-copy"; + btn.title = "Kopieren"; + btn.onclick = function() { copy2clip(inputElem.id); }; + inputElem.id = "location-" + name; + inputElem.readOnly = true; + var line = document.createElement("p"); + line.appendChild(inputElem); + line.appendChild(btn); + box.appendChild(line); + box.id = "box-" + name; + box.style.display = visible ? "block" : "none"; + return box; } function copy2clip(id) { - var copyField = document.querySelector("#" + id) - copyField.select() + var copyField = document.querySelector("#" + id); + copyField.select(); try { - document.execCommand("copy") + document.execCommand("copy"); } catch (err) { - console.log(err) + console.log(err); } } function switch2plain() { - document.getElementById("box-uci").style.display = "none" - document.getElementById("box-lat").style.display = "block" - document.getElementById("box-lng").style.display = "block" + document.getElementById("box-uci").style.display = "none"; + document.getElementById("box-lat").style.display = "block"; + document.getElementById("box-lng").style.display = "block"; } function switch2uci() { - document.getElementById("box-uci").style.display = "block" - document.getElementById("box-lat").style.display = "none" - document.getElementById("box-lng").style.display = "none" + document.getElementById("box-uci").style.display = "block"; + document.getElementById("box-lat").style.display = "none"; + document.getElementById("box-lng").style.display = "none"; } - } -}) + }; +}); diff --git a/lib/infobox/main.js b/lib/infobox/main.js index deebc03..dc900e4 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -1,51 +1,51 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Node, Location) { return function (config, sidebar, router) { - var self = this - var el + var self = this; + var el; function destroy() { if (el && el.parentNode) { - el.parentNode.removeChild(el) - el = undefined - sidebar.reveal() + el.parentNode.removeChild(el); + el = undefined; + sidebar.reveal(); } } function create() { - destroy() - sidebar.ensureVisible() - sidebar.hide() + destroy(); + sidebar.ensureVisible(); + sidebar.hide(); - el = document.createElement("div") - sidebar.container.insertBefore(el, sidebar.container.firstChild) + el = document.createElement("div"); + sidebar.container.insertBefore(el, sidebar.container.firstChild); - el.scrollIntoView(false) - el.classList.add("infobox") - el.destroy = destroy + el.scrollIntoView(false); + el.classList.add("infobox"); + el.destroy = destroy; - var closeButton = document.createElement("button") - closeButton.classList.add("close") - closeButton.onclick = router.reset - el.appendChild(closeButton) + var closeButton = document.createElement("button"); + closeButton.classList.add("close"); + closeButton.onclick = router.reset; + el.appendChild(closeButton); } - self.resetView = destroy + self.resetView = destroy; self.gotoNode = function (d) { - create() - new Node(config, el, router, d) - } + create(); + new Node(config, el, router, d); + }; self.gotoLink = function (d) { - create() - new Link(config, el, router, d) - } + create(); + new Link(config, el, router, d); + }; self.gotoLocation = function (d) { - create() - new Location(config, el, router, d) - } + create(); + new Location(config, el, router, d); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/infobox/node.js b/lib/infobox/node.js index a9fecca..2588f88 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -2,366 +2,366 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], function (moment, numeral, Tablesort) { function showGeoURI(d) { function showLatitude(d) { - var suffix = Math.sign(d) > -1 ? "' N" : "' S" - d = Math.abs(d) - var a = Math.floor(d) - var min = (d * 60) % 60 - a = (a < 10 ? "0" : "") + a + var suffix = Math.sign(d) > -1 ? "' N" : "' S"; + d = Math.abs(d); + var a = Math.floor(d); + var min = (d * 60) % 60; + a = (a < 10 ? "0" : "") + a; - return a + "° " + numeral(min).format("0.000") + suffix + return a + "° " + numeral(min).format("0.000") + suffix; } function showLongitude(d) { - var suffix = Math.sign(d) > -1 ? "' E" : "' W" - d = Math.abs(d) - var a = Math.floor(d) - var min = (d * 60) % 60 - a = (a < 100 ? "0" + (a < 10 ? "0" : "") : "") + a + var suffix = Math.sign(d) > -1 ? "' E" : "' W"; + d = Math.abs(d); + var a = Math.floor(d); + var min = (d * 60) % 60; + a = (a < 100 ? "0" + (a < 10 ? "0" : "") : "") + a; - return a + "° " + numeral(min).format("0.000") + suffix + return a + "° " + numeral(min).format("0.000") + suffix; } if (!has_location(d)) - return undefined + return undefined; return function (el) { - var latitude = d.nodeinfo.location.latitude - var longitude = d.nodeinfo.location.longitude - var a = document.createElement("a") + var latitude = d.nodeinfo.location.latitude; + var longitude = d.nodeinfo.location.longitude; + var a = document.createElement("a"); a.textContent = showLatitude(latitude) + " " + - showLongitude(longitude) + showLongitude(longitude); - a.href = "geo:" + latitude + "," + longitude - el.appendChild(a) - } + a.href = "geo:" + latitude + "," + longitude; + el.appendChild(a); + }; } function showStatus(d) { return function (el) { - el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline")) + el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline")); if (d.flags.online) - el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")"; else - el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" - } + el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")"; + }; } function showFirmware(d) { - var release = dictGet(d.nodeinfo, ["software", "firmware", "release"]) - var base = dictGet(d.nodeinfo, ["software", "firmware", "base"]) + var release = dictGet(d.nodeinfo, ["software", "firmware", "release"]); + var base = dictGet(d.nodeinfo, ["software", "firmware", "base"]); if (release === null || base === null) - return undefined + return undefined; - return release + " / " + base + return release + " / " + base; } function showSite(d, config) { - var site = dictGet(d.nodeinfo, ["system", "site_code"]) - var rt = site + var site = dictGet(d.nodeinfo, ["system", "site_code"]); + var rt = site; if (config.siteNames) config.siteNames.forEach( function (t) { if(site === t.site) - rt = t.name - }) - return rt + rt = t.name; + }); + return rt; } function showUptime(d) { if (!("uptime" in d.statistics)) - return undefined + return undefined; - return moment.duration(d.statistics.uptime, "seconds").humanize() + return moment.duration(d.statistics.uptime, "seconds").humanize(); } function showFirstseen(d) { if (!("firstseen" in d)) - return undefined + return undefined; - return d.firstseen.fromNow(true) + return d.firstseen.fromNow(true); } function showClients(d) { if (!d.flags.online) - return undefined + return undefined; return function (el) { - el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : "keine")) - el.appendChild(document.createElement("br")) + el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : "keine")); + el.appendChild(document.createElement("br")); - var span = document.createElement("span") - span.classList.add("clients") - span.textContent = " ".repeat(d.statistics.clients) - el.appendChild(span) - } + var span = document.createElement("span"); + span.classList.add("clients"); + span.textContent = " ".repeat(d.statistics.clients); + el.appendChild(span); + }; } function showIPs(d) { - var ips = dictGet(d.nodeinfo, ["network", "addresses"]) + var ips = dictGet(d.nodeinfo, ["network", "addresses"]); if (ips === null) - return undefined + return undefined; - ips.sort() + ips.sort(); return function (el) { ips.forEach( function (ip, i) { - var link = !ip.startsWith("fe80:") + var link = !ip.startsWith("fe80:"); if (i > 0) - el.appendChild(document.createElement("br")) + el.appendChild(document.createElement("br")); if (link) { - var a = document.createElement("a") - a.href = "http://[" + ip + "]/" - a.textContent = ip - el.appendChild(a) + var a = document.createElement("a"); + a.href = "http://[" + ip + "]/"; + a.textContent = ip; + el.appendChild(a); } else - el.appendChild(document.createTextNode(ip)) - }) - } + el.appendChild(document.createTextNode(ip)); + }); + }; } function showBar(className, v) { - var span = document.createElement("span") - span.classList.add("bar") - span.classList.add(className) + var span = document.createElement("span"); + span.classList.add("bar"); + span.classList.add(className); - var bar = document.createElement("span") - bar.style.width = (v * 100) + "%" - span.appendChild(bar) + var bar = document.createElement("span"); + bar.style.width = (v * 100) + "%"; + span.appendChild(bar); - var label = document.createElement("label") - label.textContent = (Math.round(v * 100)) + " %" - span.appendChild(label) + var label = document.createElement("label"); + label.textContent = (Math.round(v * 100)) + " %"; + span.appendChild(label); - return span + return span; } function showLoadBar(className, v) { - var span = document.createElement("span") - span.classList.add("bar") - span.classList.add(className) + var span = document.createElement("span"); + span.classList.add("bar"); + span.classList.add(className); - var bar = document.createElement("span") + var bar = document.createElement("span"); if (v >= 1) { - bar.style.width = ((v * 100) % 100) + "%" - bar.style.background = "rgba(255, 50, 50, 0.9)" - span.style.background = "rgba(255, 50, 50, 0.6)" - span.appendChild(bar) + bar.style.width = ((v * 100) % 100) + "%"; + bar.style.background = "rgba(255, 50, 50, 0.9)"; + span.style.background = "rgba(255, 50, 50, 0.6)"; + span.appendChild(bar); } else { - bar.style.width = (v * 100) + "%" - span.appendChild(bar) + bar.style.width = (v * 100) + "%"; + span.appendChild(bar); } - var label = document.createElement("label") - label.textContent = (v) - span.appendChild(label) + var label = document.createElement("label"); + label.textContent = (v); + span.appendChild(label); - return span + return span; } function showLoad(d) { if (!("loadavg" in d.statistics)) - return undefined + return undefined; return function (el) { - el.appendChild(showLoadBar("load-avg", d.statistics.loadavg)) - } + el.appendChild(showLoadBar("load-avg", d.statistics.loadavg)); + }; } function showRAM(d) { if (!("memory_usage" in d.statistics)) - return undefined + return undefined; return function (el) { - el.appendChild(showBar("memory-usage", d.statistics.memory_usage)) - } + el.appendChild(showBar("memory-usage", d.statistics.memory_usage)); + }; } function showPages(d) { - var webpages = dictGet(d.nodeinfo, ["pages"]) + var webpages = dictGet(d.nodeinfo, ["pages"]); if (webpages === null) - return undefined + return undefined; - webpages.sort() + webpages.sort(); return function (el) { webpages.forEach( function (webpage, i) { if (i > 0) - el.appendChild(document.createElement("br")) + el.appendChild(document.createElement("br")); - var a = document.createElement("span") - var link = document.createElement("a") - link.href = webpage + var a = document.createElement("span"); + var link = document.createElement("a"); + link.href = webpage; if (webpage.search(/^https:\/\//i) !== -1) { - var lock = document.createElement("span") - lock.className = "ion-android-lock" - a.appendChild(lock) - var t1 = document.createTextNode(" ") - a.appendChild(t1) - link.textContent = webpage.replace(/^https:\/\//i, "") + var lock = document.createElement("span"); + lock.className = "ion-android-lock"; + a.appendChild(lock); + var t1 = document.createTextNode(" "); + a.appendChild(t1); + link.textContent = webpage.replace(/^https:\/\//i, ""); } else - link.textContent = webpage.replace(/^http:\/\//i, "") - a.appendChild(link) - el.appendChild(a) - }) - } + link.textContent = webpage.replace(/^http:\/\//i, ""); + a.appendChild(link); + el.appendChild(a); + }); + }; } function showAutoupdate(d) { - var au = dictGet(d.nodeinfo, ["software", "autoupdater"]) + var au = dictGet(d.nodeinfo, ["software", "autoupdater"]); if (!au) - return undefined + return undefined; - return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert" + return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert"; } function showStatImg(o, d) { - var subst = {} - subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown" - subst["{NODE_NAME}"] = d.nodeinfo.hostname ? d.nodeinfo.hostname : "unknown" - return showStat(o, subst) + var subst = {}; + subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown"; + subst["{NODE_NAME}"] = d.nodeinfo.hostname ? d.nodeinfo.hostname : "unknown"; + return showStat(o, subst); } return function(config, el, router, d) { - var h2 = document.createElement("h2") - h2.textContent = d.nodeinfo.hostname - el.appendChild(h2) + var h2 = document.createElement("h2"); + h2.textContent = d.nodeinfo.hostname; + el.appendChild(h2); - var attributes = document.createElement("table") - attributes.classList.add("attributes") + var attributes = document.createElement("table"); + attributes.classList.add("attributes"); - attributeEntry(attributes, "Status", showStatus(d)) - attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null) - attributeEntry(attributes, "Koordinaten", showGeoURI(d)) + attributeEntry(attributes, "Status", showStatus(d)); + attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null); + attributeEntry(attributes, "Koordinaten", showGeoURI(d)); if (config.showContact) - attributeEntry(attributes, "Kontakt", dictGet(d.nodeinfo, ["owner", "contact"])) + attributeEntry(attributes, "Kontakt", dictGet(d.nodeinfo, ["owner", "contact"])); - attributeEntry(attributes, "Hardware", dictGet(d.nodeinfo, ["hardware", "model"])) - attributeEntry(attributes, "Primäre MAC", dictGet(d.nodeinfo, ["network", "mac"])) - attributeEntry(attributes, "Node ID", dictGet(d.nodeinfo, ["node_id"])) - attributeEntry(attributes, "Firmware", showFirmware(d)) - attributeEntry(attributes, "Site", showSite(d, config)) - attributeEntry(attributes, "Uptime", showUptime(d)) - attributeEntry(attributes, "Teil des Netzes", showFirstseen(d)) - attributeEntry(attributes, "Systemlast", showLoad(d)) - attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)) - attributeEntry(attributes, "IP Adressen", showIPs(d)) - attributeEntry(attributes, "Webseite", showPages(d)) - attributeEntry(attributes, "Gewähltes Gateway", dictGet(d.statistics, ["gateway"])) - attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) - attributeEntry(attributes, "Clients", showClients(d)) + attributeEntry(attributes, "Hardware", dictGet(d.nodeinfo, ["hardware", "model"])); + attributeEntry(attributes, "Primäre MAC", dictGet(d.nodeinfo, ["network", "mac"])); + attributeEntry(attributes, "Node ID", dictGet(d.nodeinfo, ["node_id"])); + attributeEntry(attributes, "Firmware", showFirmware(d)); + attributeEntry(attributes, "Site", showSite(d, config)); + attributeEntry(attributes, "Uptime", showUptime(d)); + attributeEntry(attributes, "Teil des Netzes", showFirstseen(d)); + attributeEntry(attributes, "Systemlast", showLoad(d)); + attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)); + attributeEntry(attributes, "IP Adressen", showIPs(d)); + attributeEntry(attributes, "Webseite", showPages(d)); + attributeEntry(attributes, "Gewähltes Gateway", dictGet(d.statistics, ["gateway"])); + attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)); + attributeEntry(attributes, "Clients", showClients(d)); - el.appendChild(attributes) + el.appendChild(attributes); if (config.nodeInfos) config.nodeInfos.forEach( function (nodeInfo) { - var h4 = document.createElement("h4") - h4.textContent = nodeInfo.name - el.appendChild(h4) - el.appendChild(showStatImg(nodeInfo, d)) - }) + var h4 = document.createElement("h4"); + h4.textContent = nodeInfo.name; + el.appendChild(h4); + el.appendChild(showStatImg(nodeInfo, d)); + }); if (d.neighbours.length > 0) { - var h3 = document.createElement("h3") - h3.textContent = "Links (" + d.neighbours.length + ")" - el.appendChild(h3) + var h3 = document.createElement("h3"); + h3.textContent = "Links (" + d.neighbours.length + ")"; + el.appendChild(h3); - var table = document.createElement("table") - var thead = document.createElement("thead") + var table = document.createElement("table"); + var thead = document.createElement("thead"); - var tr = document.createElement("tr") - var th1 = document.createElement("th") - th1.textContent = " " - tr.appendChild(th1) + var tr = document.createElement("tr"); + var th1 = document.createElement("th"); + th1.textContent = " "; + tr.appendChild(th1); - var th2 = document.createElement("th") - th2.textContent = "Knoten" - th2.classList.add("sort-default") - tr.appendChild(th2) + var th2 = document.createElement("th"); + th2.textContent = "Knoten"; + th2.classList.add("sort-default"); + tr.appendChild(th2); - var th3 = document.createElement("th") - th3.textContent = "TQ" - tr.appendChild(th3) + var th3 = document.createElement("th"); + th3.textContent = "TQ"; + tr.appendChild(th3); - var th4 = document.createElement("th") - th4.textContent = "Typ" - tr.appendChild(th4) + var th4 = document.createElement("th"); + th4.textContent = "Typ"; + tr.appendChild(th4); - var th5 = document.createElement("th") - th5.textContent = "Entfernung" - tr.appendChild(th5) + var th5 = document.createElement("th"); + th5.textContent = "Entfernung"; + tr.appendChild(th5); - thead.appendChild(tr) - table.appendChild(thead) + thead.appendChild(tr); + table.appendChild(thead); - var tbody = document.createElement("tbody") + var tbody = document.createElement("tbody"); d.neighbours.forEach( function (d) { - var unknown = !(d.node) - var tr = document.createElement("tr") + var unknown = !(d.node); + var tr = document.createElement("tr"); - var td1 = document.createElement("td") - td1.appendChild(document.createTextNode(d.incoming ? " ← " : " → ")) - tr.appendChild(td1) + var td1 = document.createElement("td"); + td1.appendChild(document.createTextNode(d.incoming ? " ← " : " → ")); + tr.appendChild(td1); - var td2 = document.createElement("td") - var a1 = document.createElement("a") - a1.classList.add("hostname") - a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname + var td2 = document.createElement("td"); + var a1 = document.createElement("a"); + a1.classList.add("hostname"); + a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname; if (!unknown) - a1.href = "#" - a1.onclick = router.node(d.node) - td2.appendChild(a1) + a1.href = "#"; + a1.onclick = router.node(d.node); + td2.appendChild(a1); if (!unknown && has_location(d.node)) { - var span = document.createElement("span") - span.classList.add("icon") - span.classList.add("ion-location") - td2.appendChild(span) + var span = document.createElement("span"); + span.classList.add("icon"); + span.classList.add("ion-location"); + td2.appendChild(span); } - tr.appendChild(td2) + tr.appendChild(td2); - var td3 = document.createElement("td") - var a2 = document.createElement("a") - a2.href = "#" - a2.textContent = showTq(d.link) - a2.onclick = router.link(d.link) - td3.appendChild(a2) - tr.appendChild(td3) + var td3 = document.createElement("td"); + var a2 = document.createElement("a"); + a2.href = "#"; + a2.textContent = showTq(d.link); + a2.onclick = router.link(d.link); + td3.appendChild(a2); + tr.appendChild(td3); - var td4 = document.createElement("td") - var a3 = document.createElement("a") - a3.href = "#" - a3.textContent = d.link.type - a3.onclick = router.link(d.link) - td4.appendChild(a3) - tr.appendChild(td4) + var td4 = document.createElement("td"); + var a3 = document.createElement("a"); + a3.href = "#"; + a3.textContent = d.link.type; + a3.onclick = router.link(d.link); + td4.appendChild(a3); + tr.appendChild(td4); - var td5 = document.createElement("td") - var a4 = document.createElement("a") - a4.href = "#" - a4.textContent = showDistance(d.link) - a4.onclick = router.link(d.link) - td5.appendChild(a4) - td5.setAttribute("data-sort", d.link.distance !== undefined ? -d.link.distance : 1) - tr.appendChild(td5) + var td5 = document.createElement("td"); + var a4 = document.createElement("a"); + a4.href = "#"; + a4.textContent = showDistance(d.link); + a4.onclick = router.link(d.link); + td5.appendChild(a4); + td5.setAttribute("data-sort", d.link.distance !== undefined ? -d.link.distance : 1); + tr.appendChild(td5); - tbody.appendChild(tr) - }) + tbody.appendChild(tr); + }); - table.appendChild(tbody) - table.className = "node-links" + table.appendChild(tbody); + table.className = "node-links"; - new Tablesort(table) + new Tablesort(table); - el.appendChild(table) + el.appendChild(table); } - } -}) + }; +}); diff --git a/lib/legend.js b/lib/legend.js index bee87c3..b01782f 100644 --- a/lib/legend.js +++ b/lib/legend.js @@ -1,41 +1,41 @@ define(function () { return function () { - var self = this + var self = this; self.render = function (el) { - var p = document.createElement("p") - p.setAttribute("class", "legend") - el.appendChild(p) + var p = document.createElement("p"); + p.setAttribute("class", "legend"); + el.appendChild(p); - var spanNew = document.createElement("span") - spanNew.setAttribute("class", "legend-new") - var symbolNew = document.createElement("span") - symbolNew.setAttribute("class", "symbol") - var textNew = document.createTextNode(" Neuer Knoten") - spanNew.appendChild(symbolNew) - spanNew.appendChild(textNew) - p.appendChild(spanNew) + var spanNew = document.createElement("span"); + spanNew.setAttribute("class", "legend-new"); + var symbolNew = document.createElement("span"); + symbolNew.setAttribute("class", "symbol"); + var textNew = document.createTextNode(" Neuer Knoten"); + spanNew.appendChild(symbolNew); + spanNew.appendChild(textNew); + p.appendChild(spanNew); - var spanOnline = document.createElement("span") - spanOnline.setAttribute("class", "legend-online") - var symbolOnline = document.createElement("span") - symbolOnline.setAttribute("class", "symbol") - var textOnline = document.createTextNode(" Knoten ist online") - spanOnline.appendChild(symbolOnline) - spanOnline.appendChild(textOnline) - p.appendChild(spanOnline) + var spanOnline = document.createElement("span"); + spanOnline.setAttribute("class", "legend-online"); + var symbolOnline = document.createElement("span"); + symbolOnline.setAttribute("class", "symbol"); + var textOnline = document.createTextNode(" Knoten ist online"); + spanOnline.appendChild(symbolOnline); + spanOnline.appendChild(textOnline); + p.appendChild(spanOnline); - var spanOffline = document.createElement("span") - spanOffline.setAttribute("class", "legend-offline") - var symbolOffline = document.createElement("span") - symbolOffline.setAttribute("class", "symbol") - var textOffline = document.createTextNode(" Knoten ist offline") - spanOffline.appendChild(symbolOffline) - spanOffline.appendChild(textOffline) - p.appendChild(spanOffline) - } + var spanOffline = document.createElement("span"); + spanOffline.setAttribute("class", "legend-offline"); + var symbolOffline = document.createElement("span"); + symbolOffline.setAttribute("class", "symbol"); + var textOffline = document.createTextNode(" Knoten ist offline"); + spanOffline.appendChild(symbolOffline); + spanOffline.appendChild(textOffline); + p.appendChild(spanOffline); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/linklist.js b/lib/linklist.js index 1fc8574..c50194f 100644 --- a/lib/linklist.js +++ b/lib/linklist.js @@ -1,60 +1,60 @@ define(["sorttable", "virtual-dom"], function (SortTable, V) { function linkName(d) { - return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname + return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname; } var headings = [{ name: "Knoten", sort: function (a, b) { - return linkName(a).localeCompare(linkName(b)) + return linkName(a).localeCompare(linkName(b)); }, reverse: false }, { name: "TQ", - sort: function (a, b) { return a.tq - b.tq}, + sort: function (a, b) { return a.tq - b.tq; }, reverse: true }, { name: "Typ", sort: function (a, b) { - return a.type.localeCompare(b.type) + return a.type.localeCompare(b.type); }, reverse: false }, { name: "Entfernung", sort: function (a, b) { return (a.distance === undefined ? -1 : a.distance) - - (b.distance === undefined ? -1 : b.distance) + (b.distance === undefined ? -1 : b.distance); }, reverse: true - }] + }]; return function(linkScale, router) { - var table = new SortTable(headings, 2, renderRow) + var table = new SortTable(headings, 2, renderRow); function renderRow(d) { - var td1Content = [V.h("a", {href: "#", onclick: router.link(d)}, linkName(d))] + var td1Content = [V.h("a", {href: "#", onclick: router.link(d)}, linkName(d))]; - var td1 = V.h("td", td1Content) - var td2 = V.h("td", {style: {color: linkScale(d.tq).hex()}}, showTq(d)) - var td3 = V.h("td", d.type) - var td4 = V.h("td", showDistance(d)) + var td1 = V.h("td", td1Content); + var td2 = V.h("td", {style: {color: linkScale(d.tq).hex()}}, showTq(d)); + var td3 = V.h("td", d.type); + var td4 = V.h("td", showDistance(d)); - return V.h("tr", [td1, td2, td3, td4]) + return V.h("tr", [td1, td2, td3, td4]); } this.render = function (d) { - var el = document.createElement("div") - el.last = V.h("div") - d.appendChild(el) + var el = document.createElement("div"); + el.last = V.h("div"); + d.appendChild(el); - var h2 = document.createElement("h2") - h2.textContent = "Verbindungen" - el.appendChild(h2) + var h2 = document.createElement("h2"); + h2.textContent = "Verbindungen"; + el.appendChild(h2); - el.appendChild(table.el) - } + el.appendChild(table.el); + }; this.setData = function (d) { - table.setData(d.graph.links) - } - } -}) + table.setData(d.graph.links); + }; + }; +}); diff --git a/lib/locationmarker.js b/lib/locationmarker.js index 615eeef..97dad4d 100644 --- a/lib/locationmarker.js +++ b/lib/locationmarker.js @@ -30,30 +30,30 @@ define(["leaflet"], function (L) { }, initialize: function(latlng) { - this.accuracyCircle = L.circle(latlng, 0, this.accuracyCircle) - this.outerCircle = L.circleMarker(latlng, this.outerCircle) - L.CircleMarker.prototype.initialize.call(this, latlng, this.innerCircle) + this.accuracyCircle = L.circle(latlng, 0, this.accuracyCircle); + this.outerCircle = L.circleMarker(latlng, this.outerCircle); + L.CircleMarker.prototype.initialize.call(this, latlng, this.innerCircle); this.on("remove", function() { - this._map.removeLayer(this.accuracyCircle) - this._map.removeLayer(this.outerCircle) - }) + this._map.removeLayer(this.accuracyCircle); + this._map.removeLayer(this.outerCircle); + }); }, setLatLng: function(latlng) { - this.accuracyCircle.setLatLng(latlng) - this.outerCircle.setLatLng(latlng) - L.CircleMarker.prototype.setLatLng.call(this, latlng) + this.accuracyCircle.setLatLng(latlng); + this.outerCircle.setLatLng(latlng); + L.CircleMarker.prototype.setLatLng.call(this, latlng); }, setAccuracy: function(accuracy) { - this.accuracyCircle.setRadius(accuracy) + this.accuracyCircle.setRadius(accuracy); }, onAdd: function(map) { - this.accuracyCircle.addTo(map).bringToBack() - this.outerCircle.addTo(map) - L.CircleMarker.prototype.onAdd.call(this, map) + this.accuracyCircle.addTo(map).bringToBack(); + this.outerCircle.addTo(map); + L.CircleMarker.prototype.onAdd.call(this, map); } - }) -}) + }); +}); diff --git a/lib/main.js b/lib/main.js index 396aed1..e956e36 100644 --- a/lib/main.js +++ b/lib/main.js @@ -2,95 +2,95 @@ define(["moment", "router", "leaflet", "gui", "numeral"], function (moment, Router, L, GUI, numeral) { return function (config) { function handleData(data) { - var dataNodes = {} - dataNodes.nodes = [] - var dataGraph = {} - dataGraph.batadv = {} - dataGraph.batadv.nodes = [] - dataGraph.batadv.links = [] + var dataNodes = {}; + dataNodes.nodes = []; + var dataGraph = {}; + dataGraph.batadv = {}; + dataGraph.batadv.nodes = []; + dataGraph.batadv.links = []; function rearrangeLinks(d) { - d.source += dataGraph.batadv.nodes.length - d.target += dataGraph.batadv.nodes.length + d.source += dataGraph.batadv.nodes.length; + d.target += dataGraph.batadv.nodes.length; } for (var i = 0; i < data.length; ++i) { - var vererr + var vererr; if(i % 2) if (data[i].version !== 1) { - vererr = "Unsupported graph version: " + data[i].version - console.log(vererr) //silent fail + vererr = "Unsupported graph version: " + data[i].version; + console.log(vererr); //silent fail } else { - data[i].batadv.links.forEach(rearrangeLinks) - dataGraph.batadv.nodes = dataGraph.batadv.nodes.concat(data[i].batadv.nodes) - dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links) - dataGraph.timestamp = data[i].timestamp + data[i].batadv.links.forEach(rearrangeLinks); + dataGraph.batadv.nodes = dataGraph.batadv.nodes.concat(data[i].batadv.nodes); + dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links); + dataGraph.timestamp = data[i].timestamp; } else if (data[i].version !== 2) { - vererr = "Unsupported nodes version: " + data[i].version - console.log(vererr) //silent fail + vererr = "Unsupported nodes version: " + data[i].version; + console.log(vererr); //silent fail } else { - dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes) - dataNodes.timestamp = data[i].timestamp + dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes); + dataNodes.timestamp = data[i].timestamp; } } var nodes = dataNodes.nodes.filter( function (d) { - return "firstseen" in d && "lastseen" in d - }) + return "firstseen" in d && "lastseen" in d; + }); nodes.forEach( function(node) { - node.firstseen = moment.utc(node.firstseen).local() - node.lastseen = moment.utc(node.lastseen).local() - }) + node.firstseen = moment.utc(node.firstseen).local(); + node.lastseen = moment.utc(node.lastseen).local(); + }); - var now = moment() - var age = moment(now).subtract(config.maxAge, "days") + var now = moment(); + var age = moment(now).subtract(config.maxAge, "days"); - var newnodes = limit("firstseen", age, sortByKey("firstseen", nodes).filter(online)) - var lostnodes = limit("lastseen", age, sortByKey("lastseen", nodes).filter(offline)) + var newnodes = limit("firstseen", age, sortByKey("firstseen", nodes).filter(online)); + var lostnodes = limit("lastseen", age, sortByKey("lastseen", nodes).filter(offline)); - var graphnodes = {} + var graphnodes = {}; dataNodes.nodes.forEach( function (d) { - graphnodes[d.nodeinfo.node_id] = d - }) + graphnodes[d.nodeinfo.node_id] = d; + }); - var graph = dataGraph.batadv + var graph = dataGraph.batadv; graph.nodes.forEach( function (d) { if (d.node_id in graphnodes) { - d.node = graphnodes[d.node_id] + d.node = graphnodes[d.node_id]; if (d.unseen) { - d.node.flags.online = true - d.node.flags.unseen = true + d.node.flags.online = true; + d.node.flags.unseen = true; } } - }) + }); graph.links.forEach( function (d) { - d.source = graph.nodes[d.source] + d.source = graph.nodes[d.source]; if (graph.nodes[d.target].node) - d.target = graph.nodes[d.target] + d.target = graph.nodes[d.target]; else - d.target = undefined - }) + d.target = undefined; + }); var links = graph.links.filter( function (d) { - return d.target !== undefined - }) + return d.target !== undefined; + }); links.forEach( function (d) { - var unknown = (d.source.node === undefined) - var ids + var unknown = (d.source.node === undefined); + var ids; if (unknown) - ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id] + ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id]; else - ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id] - d.id = ids.join("-") + ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id]; + d.id = ids.join("-"); if (unknown || !d.source.node.nodeinfo.location || @@ -99,45 +99,45 @@ function (moment, Router, L, GUI, numeral) { isNaN(d.source.node.nodeinfo.location.longitude) || isNaN(d.target.node.nodeinfo.location.latitude) || isNaN(d.target.node.nodeinfo.location.longitude)) - return + return; - d.latlngs = [] - d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude)) - d.latlngs.push(L.latLng(d.target.node.nodeinfo.location.latitude, d.target.node.nodeinfo.location.longitude)) + d.latlngs = []; + d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude)); + d.latlngs.push(L.latLng(d.target.node.nodeinfo.location.latitude, d.target.node.nodeinfo.location.longitude)); - d.distance = d.latlngs[0].distanceTo(d.latlngs[1]) - }) + d.distance = d.latlngs[0].distanceTo(d.latlngs[1]); + }); nodes.forEach( function (d) { - d.neighbours = [] - }) + d.neighbours = []; + }); links.forEach( function (d) { if (d.type === "tunnel" || d.type === "fastd") - d.type = "fastd" + d.type = "fastd"; else if (d.type === "l2tp") { - d.type = "L2TP" - d.target.node.flags.uplink = true + d.type = "L2TP"; + d.target.node.flags.uplink = true; } else if (d.type === "wireless") - d.type = "Wifi" + d.type = "Wifi"; else if (d.type === "other") - d.type = "Kabel" + d.type = "Kabel"; else - d.type = "N/A" - var unknown = (d.source.node === undefined) + d.type = "N/A"; + var unknown = (d.source.node === undefined); if (unknown) { - d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }) - return + d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }); + return; } - d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }) - d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }) + d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }); + d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }); if (d.type !== "fastd" && d.type !== "L2TP") - d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1 - }) + d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1; + }); links.sort( function (a, b) { - return b.tq - a.tq - }) + return b.tq - a.tq; + }); return { now: now, timestamp: moment.utc(dataNodes.timestamp).local(), @@ -150,46 +150,46 @@ function (moment, Router, L, GUI, numeral) { links: links, nodes: graph.nodes } - } + }; } - numeral.language("de") - moment.locale("de") + numeral.language("de"); + moment.locale("de"); - var router = new Router() + var router = new Router(); - var urls = [] + var urls = []; if (typeof config.dataPath === "string" || config.dataPath instanceof String) - config.dataPath = [config.dataPath] + config.dataPath = [config.dataPath]; for (var i in config.dataPath) { - urls.push(config.dataPath[i] + "nodes.json") - urls.push(config.dataPath[i] + "graph.json") + urls.push(config.dataPath[i] + "nodes.json"); + urls.push(config.dataPath[i] + "graph.json"); } function update() { return Promise.all(urls.map(getJSON)) - .then(handleData) + .then(handleData); } update() .then(function (d) { - var gui = new GUI(config, router) - gui.setData(d) - router.setData(d) - router.start() + var gui = new GUI(config, router); + gui.setData(d); + router.setData(d); + router.start(); window.setInterval(function () { update().then(function (d) { - gui.setData(d) - router.setData(d) - }) - }, 60000) + gui.setData(d); + router.setData(d); + }); + }, 60000); }) .catch(function (e) { - document.body.textContent = e - console.log(e) - }) - } -}) + document.body.textContent = e; + console.log(e); + }); + }; +}); diff --git a/lib/map.js b/lib/map.js index aca0097..d5d4bdf 100644 --- a/lib/map.js +++ b/lib/map.js @@ -4,7 +4,7 @@ define(["map/clientlayer", "map/labelslayer", function (ClientLayer, LabelsLayer, d3, L, moment, LocationMarker, rbush) { var options = { worldCopyJump: true, zoomControl: false - } + }; var AddLayerButton = L.Control.extend({ options: { @@ -12,24 +12,24 @@ define(["map/clientlayer", "map/labelslayer", }, initialize: function (f, options) { - L.Util.setOptions(this, options) - this.f = f + L.Util.setOptions(this, options); + this.f = f; }, onAdd: function () { - var button = L.DomUtil.create("button", "add-layer") - button.textContent = "\uF2C7" + var button = L.DomUtil.create("button", "add-layer"); + button.textContent = "\uF2C7"; // L.DomEvent.disableClickPropagation(button) // Click propagation isn't disabled as this causes problems with the // location picking mode; instead propagation is stopped in onClick(). - L.DomEvent.addListener(button, "click", this.f, this) + L.DomEvent.addListener(button, "click", this.f, this); - this.button = button + this.button = button; - return button + return button; } - }) + }); var LocateButton = L.Control.extend({ options: { @@ -40,35 +40,35 @@ define(["map/clientlayer", "map/labelslayer", button: undefined, initialize: function (f, options) { - L.Util.setOptions(this, options) - this.f = f + L.Util.setOptions(this, options); + this.f = f; }, onAdd: function () { - var button = L.DomUtil.create("button", "locate-user") - button.textContent = "\uF2E9" + var button = L.DomUtil.create("button", "locate-user"); + button.textContent = "\uF2E9"; - L.DomEvent.disableClickPropagation(button) - L.DomEvent.addListener(button, "click", this.onClick, this) + L.DomEvent.disableClickPropagation(button); + L.DomEvent.addListener(button, "click", this.onClick, this); - this.button = button + this.button = button; - return button + return button; }, update: function() { - this.button.classList.toggle("active", this.active) + this.button.classList.toggle("active", this.active); }, set: function(v) { - this.active = v - this.update() + this.active = v; + this.update(); }, onClick: function () { - this.f(!this.active) + this.f(!this.active); } - }) + }); var CoordsPickerButton = L.Control.extend({ options: { @@ -79,470 +79,470 @@ define(["map/clientlayer", "map/labelslayer", button: undefined, initialize: function (f, options) { - L.Util.setOptions(this, options) - this.f = f + L.Util.setOptions(this, options); + this.f = f; }, onAdd: function () { - var button = L.DomUtil.create("button", "coord-picker") - button.textContent = "\uF2A6" + var button = L.DomUtil.create("button", "coord-picker"); + button.textContent = "\uF2A6"; // Click propagation isn't disabled as this causes problems with the // location picking mode; instead propagation is stopped in onClick(). - L.DomEvent.addListener(button, "click", this.onClick, this) + L.DomEvent.addListener(button, "click", this.onClick, this); - this.button = button + this.button = button; - return button + return button; }, update: function() { - this.button.classList.toggle("active", this.active) + this.button.classList.toggle("active", this.active); }, set: function(v) { - this.active = v - this.update() + this.active = v; + this.update(); }, onClick: function (e) { - L.DomEvent.stopPropagation(e) - this.f(!this.active) + L.DomEvent.stopPropagation(e); + this.f(!this.active); } - }) + }); function mkMarker(dict, iconFunc, router) { return function (d) { - var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], iconFunc(d)) + var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], iconFunc(d)); m.resetStyle = function () { - m.setStyle(iconFunc(d)) - } + m.setStyle(iconFunc(d)); + }; - m.on("click", router.node(d)) - m.bindLabel(d.nodeinfo.hostname) + m.on("click", router.node(d)); + m.bindLabel(d.nodeinfo.hostname); - dict[d.nodeinfo.node_id] = m + dict[d.nodeinfo.node_id] = m; - return m - } + return m; + }; } function addLinksToMap(dict, linkScale, graph, router) { graph = graph.filter( function (d) { - return "distance" in d && d.type !== "VPN" - }) + return "distance" in d && d.type !== "VPN"; + }); var lines = graph.map( function (d) { var opts = { color: d.type === "Kabel" ? "#50B0F0" : linkScale(d.tq).hex(), weight: 4, opacity: 0.5, dashArray: "none" - } + }; - var line = L.polyline(d.latlngs, opts) + var line = L.polyline(d.latlngs, opts); line.resetStyle = function () { - line.setStyle(opts) - } + line.setStyle(opts); + }; - line.bindLabel(d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname + "
" + showDistance(d) + " / " + showTq(d) + "") - line.on("click", router.link(d)) + line.bindLabel(d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname + "
" + showDistance(d) + " / " + showTq(d) + ""); + line.on("click", router.link(d)); - dict[d.id] = line + dict[d.id] = line; - return line - }) + return line; + }); - return lines + return lines; } - var iconOnline = { color: "#1566A9", fillColor: "#1566A9", radius: 6, fillOpacity: 0.5, opacity: 0.5, weight: 2, className: "stroke-first" } - var iconOffline = { color: "#D43E2A", fillColor: "#D43E2A", radius: 3, fillOpacity: 0.5, opacity: 0.5, weight: 1, className: "stroke-first" } - var iconLost = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 1, className: "stroke-first" } - var iconAlert = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 2, className: "stroke-first node-alert" } - var iconNew = { color: "#1566A9", fillColor: "#93E929", radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2 } + var iconOnline = { color: "#1566A9", fillColor: "#1566A9", radius: 6, fillOpacity: 0.5, opacity: 0.5, weight: 2, className: "stroke-first" }; + var iconOffline = { color: "#D43E2A", fillColor: "#D43E2A", radius: 3, fillOpacity: 0.5, opacity: 0.5, weight: 1, className: "stroke-first" }; + var iconLost = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 1, className: "stroke-first" }; + var iconAlert = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 2, className: "stroke-first node-alert" }; + var iconNew = { color: "#1566A9", fillColor: "#93E929", radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2 }; return function (config, linkScale, sidebar, router, buttons) { - var self = this - var barycenter - var groupOnline, groupOffline, groupNew, groupLost, groupLines - var savedView + var self = this; + var barycenter; + var groupOnline, groupOffline, groupNew, groupLost, groupLines; + var savedView; - var map, userLocation - var layerControl - var customLayers = {} - var baseLayers = {} + var map, userLocation; + var layerControl; + var customLayers = {}; + var baseLayers = {}; var locateUserButton = new LocateButton(function (d) { if (d) - enableTracking() + enableTracking(); else - disableTracking() - }) + disableTracking(); + }); - var mybuttons = [] + var mybuttons = []; function addButton(button) { - var el = button.onAdd() - mybuttons.push(el) - buttons.appendChild(el) + var el = button.onAdd(); + mybuttons.push(el); + buttons.appendChild(el); } function clearButtons() { mybuttons.forEach( function (d) { - buttons.removeChild(d) - }) + buttons.removeChild(d); + }); } var showCoordsPickerButton = new CoordsPickerButton(function (d) { if (d) - enableCoords() + enableCoords(); else - disableCoords() - }) + disableCoords(); + }); function saveView() { savedView = {center: map.getCenter(), - zoom: map.getZoom()} + zoom: map.getZoom()}; } function enableTracking() { map.locate({watch: true, enableHighAccuracy: true, setView: true - }) - locateUserButton.set(true) + }); + locateUserButton.set(true); } function disableTracking() { - map.stopLocate() - locationError() - locateUserButton.set(false) + map.stopLocate(); + locationError(); + locateUserButton.set(false); } function enableCoords() { - map.getContainer().classList.add("pick-coordinates") - map.on("click", showCoordinates) - showCoordsPickerButton.set(true) + map.getContainer().classList.add("pick-coordinates"); + map.on("click", showCoordinates); + showCoordsPickerButton.set(true); } function disableCoords() { - map.getContainer().classList.remove("pick-coordinates") - map.off("click", showCoordinates) - showCoordsPickerButton.set(false) + map.getContainer().classList.remove("pick-coordinates"); + map.off("click", showCoordinates); + showCoordsPickerButton.set(false); } function showCoordinates(e) { - router.gotoLocation(e.latlng) + router.gotoLocation(e.latlng); // window.prompt("Koordinaten (Lat, Lng)", e.latlng.lat.toFixed(9) + ", " + e.latlng.lng.toFixed(9)) - disableCoords() + disableCoords(); } function locationFound(e) { if (!userLocation) - userLocation = new LocationMarker(e.latlng).addTo(map) + userLocation = new LocationMarker(e.latlng).addTo(map); - userLocation.setLatLng(e.latlng) - userLocation.setAccuracy(e.accuracy) + userLocation.setLatLng(e.latlng); + userLocation.setAccuracy(e.accuracy); } function locationError() { if (userLocation) { - map.removeLayer(userLocation) - userLocation = null + map.removeLayer(userLocation); + userLocation = null; } } function addLayer(layerName) { if (layerName in baseLayers) - return + return; if (layerName in customLayers) - return + return; try { - var layer = L.tileLayer.provider(layerName) - layerControl.addBaseLayer(layer, layerName) - customLayers[layerName] = layer + var layer = L.tileLayer.provider(layerName); + layerControl.addBaseLayer(layer, layerName); + customLayers[layerName] = layer; if (localStorageTest()) - localStorage.setItem("map/customLayers", JSON.stringify(Object.keys(customLayers))) + localStorage.setItem("map/customLayers", JSON.stringify(Object.keys(customLayers))); } catch (e) { - return + console.log(e); } } function contextMenuGotoLocation(e) { - router.gotoLocation(e.latlng) + router.gotoLocation(e.latlng); } - var el = document.createElement("div") - el.classList.add("map") + var el = document.createElement("div"); + el.classList.add("map"); - map = L.map(el, options) + map = L.map(el, options); var layers = config.mapLayers.map( function (d) { return { "name": d.name, "layer": "url" in d ? L.tileLayer(d.url, d.config) : L.tileLayer.provider(d.name) - } - }) + }; + }); - layers[0].layer.addTo(map) + layers[0].layer.addTo(map); layers.forEach( function (d) { - baseLayers[d.name] = d.layer - }) + baseLayers[d.name] = d.layer; + }); - map.on("locationfound", locationFound) - map.on("locationerror", locationError) - map.on("dragend", saveView) - map.on("contextmenu", contextMenuGotoLocation) + map.on("locationfound", locationFound); + map.on("locationerror", locationError); + map.on("dragend", saveView); + map.on("contextmenu", contextMenuGotoLocation); - addButton(locateUserButton) - addButton(showCoordsPickerButton) + addButton(locateUserButton); + addButton(showCoordsPickerButton); addButton(new AddLayerButton(function () { /*eslint no-alert:0*/ - var layerName = prompt("Leaflet Provider:") - addLayer(layerName) - })) + var layerName = prompt("Leaflet Provider:"); + addLayer(layerName); + })); - layerControl = L.control.layers(baseLayers, [], {position: "bottomright"}) - layerControl.addTo(map) + layerControl = L.control.layers(baseLayers, [], {position: "bottomright"}); + layerControl.addTo(map); if (localStorageTest()) { - var d = JSON.parse(localStorage.getItem("map/customLayers")) + var d = JSON.parse(localStorage.getItem("map/customLayers")); if (d) - d.forEach(addLayer) + d.forEach(addLayer); - d = JSON.parse(localStorage.getItem("map/selectedLayer")) - d = d && d.name in baseLayers ? baseLayers[d.name] : d && d.name in customLayers ? customLayers[d.name] : false + d = JSON.parse(localStorage.getItem("map/selectedLayer")); + d = d && d.name in baseLayers ? baseLayers[d.name] : d && d.name in customLayers ? customLayers[d.name] : false; if (d) { - map.removeLayer(layers[0].layer) - map.addLayer(d) + map.removeLayer(layers[0].layer); + map.addLayer(d); } } - var clientLayer = new ClientLayer({minZoom: 15}) - clientLayer.addTo(map) - clientLayer.setZIndex(5) + var clientLayer = new ClientLayer({minZoom: 15}); + clientLayer.addTo(map); + clientLayer.setZIndex(5); - var labelsLayer = new LabelsLayer({}) - labelsLayer.addTo(map) - labelsLayer.setZIndex(6) + var labelsLayer = new LabelsLayer({}); + labelsLayer.addTo(map); + labelsLayer.setZIndex(6); map.on("baselayerchange", function(e) { - map.options.maxZoom = e.layer.options.maxZoom - clientLayer.options.maxZoom = map.options.maxZoom - labelsLayer.options.maxZoom = map.options.maxZoom - if (map.getZoom() > map.options.maxZoom) map.setZoom(map.options.maxZoom) + map.options.maxZoom = e.layer.options.maxZoom; + clientLayer.options.maxZoom = map.options.maxZoom; + labelsLayer.options.maxZoom = map.options.maxZoom; + if (map.getZoom() > map.options.maxZoom) map.setZoom(map.options.maxZoom); if (localStorageTest()) - localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})) - }) + localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})); + }); - var nodeDict = {} - var linkDict = {} - var highlight + var nodeDict = {}; + var linkDict = {}; + var highlight; function resetMarkerStyles(nodes, links) { Object.keys(nodes).forEach( function (d) { - nodes[d].resetStyle() - }) + nodes[d].resetStyle(); + }); Object.keys(links).forEach( function (d) { - links[d].resetStyle() - }) + links[d].resetStyle(); + }); } function setView(bounds) { - map.fitBounds(bounds, {paddingTopLeft: [sidebar(), 0]}) + map.fitBounds(bounds, {paddingTopLeft: [sidebar(), 0]}); } function resetZoom() { if (barycenter) - setView(barycenter.getBounds()) + setView(barycenter.getBounds()); } function goto(m) { - var bounds + var bounds; if ("getBounds" in m) - bounds = m.getBounds() + bounds = m.getBounds(); else - bounds = L.latLngBounds([m.getLatLng()]) + bounds = L.latLngBounds([m.getLatLng()]); - setView(bounds) + setView(bounds); - return m + return m; } function updateView(nopanzoom) { - resetMarkerStyles(nodeDict, linkDict) - var m + resetMarkerStyles(nodeDict, linkDict); + var m; if (highlight !== undefined) if (highlight.type === "node") { - m = nodeDict[highlight.o.nodeinfo.node_id] + m = nodeDict[highlight.o.nodeinfo.node_id]; if (m) - m.setStyle({ color: "orange", weight: 20, fillOpacity: 1, opacity: 0.7, className: "stroke-first" }) + m.setStyle({ color: "orange", weight: 20, fillOpacity: 1, opacity: 0.7, className: "stroke-first" }); } else if (highlight.type === "link") { - m = linkDict[highlight.o.id] + m = linkDict[highlight.o.id]; if (m) - m.setStyle({ weight: 7, opacity: 1, dashArray: "10, 10" }) + m.setStyle({ weight: 7, opacity: 1, dashArray: "10, 10" }); } if (!nopanzoom) if (m) - goto(m) + goto(m); else if (savedView) - map.setView(savedView.center, savedView.zoom) + map.setView(savedView.center, savedView.zoom); else - resetZoom() + resetZoom(); } function calcBarycenter(nodes) { - nodes = nodes.map(function (d) { return d.nodeinfo.location }) + nodes = nodes.map(function (d) { return d.nodeinfo.location; }); if (nodes.length === 0) - return undefined + return undefined; - var lats = nodes.map(function (d) { return d.latitude }) - var lngs = nodes.map(function (d) { return d.longitude }) + var lats = nodes.map(function (d) { return d.latitude; }); + var lngs = nodes.map(function (d) { return d.longitude; }); - var barycenter = L.latLng(d3.median(lats), d3.median(lngs)) - var barycenterDev = [d3.deviation(lats), d3.deviation(lngs)] + var barycenter = L.latLng(d3.median(lats), d3.median(lngs)); + var barycenterDev = [d3.deviation(lats), d3.deviation(lngs)]; if (barycenterDev[0] === undefined) - barycenterDev[0] = 0 + barycenterDev[0] = 0; if (barycenterDev[1] === undefined) - barycenterDev[1] = 0 + barycenterDev[1] = 0; var barycenterCircle = L.latLng(barycenter.lat + barycenterDev[0], - barycenter.lng + barycenterDev[1]) + barycenter.lng + barycenterDev[1]); - var r = barycenter.distanceTo(barycenterCircle) + var r = barycenter.distanceTo(barycenterCircle); - return L.circle(barycenter, r * config.mapSigmaScale) + return L.circle(barycenter, r * config.mapSigmaScale); } function mapRTree(d) { var o = [ d.nodeinfo.location.latitude, d.nodeinfo.location.longitude, - d.nodeinfo.location.latitude, d.nodeinfo.location.longitude] + d.nodeinfo.location.latitude, d.nodeinfo.location.longitude]; - o.node = d + o.node = d; - return o + return o; } self.setData = function (data) { - nodeDict = {} - linkDict = {} + nodeDict = {}; + linkDict = {}; if (groupOffline) - groupOffline.clearLayers() + groupOffline.clearLayers(); if (groupOnline) - groupOnline.clearLayers() + groupOnline.clearLayers(); if (groupNew) - groupNew.clearLayers() + groupNew.clearLayers(); if (groupLost) - groupLost.clearLayers() + groupLost.clearLayers(); if (groupLines) - groupLines.clearLayers() + groupLines.clearLayers(); - var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router) - groupLines = L.featureGroup(lines).addTo(map) + var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router); + groupLines = L.featureGroup(lines).addTo(map); if (typeof config.fixedCenter === "undefined") - barycenter = calcBarycenter(data.nodes.all.filter(has_location)) + barycenter = calcBarycenter(data.nodes.all.filter(has_location)); else - barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000) + barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000); - var nodesOnline = subtract(data.nodes.all.filter(online), data.nodes.new) - var nodesOffline = subtract(data.nodes.all.filter(offline), data.nodes.lost) + var nodesOnline = subtract(data.nodes.all.filter(online), data.nodes.new); + var nodesOffline = subtract(data.nodes.all.filter(offline), data.nodes.lost); var markersOnline = nodesOnline.filter(has_location) - .map(mkMarker(nodeDict, function () { return iconOnline }, router)) + .map(mkMarker(nodeDict, function () { return iconOnline; }, router)); var markersOffline = nodesOffline.filter(has_location) - .map(mkMarker(nodeDict, function () { return iconOffline }, router)) + .map(mkMarker(nodeDict, function () { return iconOffline; }, router)); var markersNew = data.nodes.new.filter(has_location) - .map(mkMarker(nodeDict, function () { return iconNew }, router)) + .map(mkMarker(nodeDict, function () { return iconNew; }, router)); var markersLost = data.nodes.lost.filter(has_location) .map(mkMarker(nodeDict, function (d) { if (d.lastseen.isAfter(moment(data.now).subtract(3, "days"))) - return iconAlert + return iconAlert; - return iconLost - }, router)) + return iconLost; + }, router)); - groupOffline = L.featureGroup(markersOffline).addTo(map) - groupOnline = L.featureGroup(markersOnline).addTo(map) - groupLost = L.featureGroup(markersLost).addTo(map) - groupNew = L.featureGroup(markersNew).addTo(map) + groupOffline = L.featureGroup(markersOffline).addTo(map); + groupOnline = L.featureGroup(markersOnline).addTo(map); + groupLost = L.featureGroup(markersLost).addTo(map); + groupNew = L.featureGroup(markersNew).addTo(map); - var rtreeOnlineAll = rbush(9) + var rtreeOnlineAll = rbush(9); - rtreeOnlineAll.load(data.nodes.all.filter(online).filter(has_location).map(mapRTree)) + rtreeOnlineAll.load(data.nodes.all.filter(online).filter(has_location).map(mapRTree)); - clientLayer.setData(rtreeOnlineAll) + clientLayer.setData(rtreeOnlineAll); labelsLayer.setData({online: nodesOnline.filter(has_location), offline: nodesOffline.filter(has_location), new: data.nodes.new.filter(has_location), lost: data.nodes.lost.filter(has_location) - }) + }); - updateView(true) - } + updateView(true); + }; self.resetView = function () { - disableTracking() - highlight = undefined - updateView() - } + disableTracking(); + highlight = undefined; + updateView(); + }; self.gotoNode = function (d) { - disableTracking() - highlight = {type: "node", o: d} - updateView() - } + disableTracking(); + highlight = {type: "node", o: d}; + updateView(); + }; self.gotoLink = function (d) { - disableTracking() - highlight = {type: "link", o: d} - updateView() - } + disableTracking(); + highlight = {type: "link", o: d}; + updateView(); + }; self.gotoLocation = function () { //ignore - } + }; self.destroy = function () { - clearButtons() - map.remove() + clearButtons(); + map.remove(); if (el.parentNode) - el.parentNode.removeChild(el) - } + el.parentNode.removeChild(el); + }; self.render = function (d) { - d.appendChild(el) - map.invalidateSize() - } + d.appendChild(el); + map.invalidateSize(); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/map/clientlayer.js b/lib/map/clientlayer.js index c3fb439..06fd784 100644 --- a/lib/map/clientlayer.js +++ b/lib/map/clientlayer.js @@ -1,76 +1,76 @@ define(["leaflet", "jshashes"], function (L, jsHashes) { - var MD5 = new jsHashes.MD5() + var MD5 = new jsHashes.MD5(); return L.TileLayer.Canvas.extend({ setData: function (d) { - this.data = d + this.data = d; //pre-calculate start angles this.data.all().forEach(function (d) { - var hash = MD5.hex(d.node.nodeinfo.node_id) - d.startAngle = (parseInt(hash.substr(0, 2), 16) / 255) * 2 * Math.PI - }) - this.redraw() + var hash = MD5.hex(d.node.nodeinfo.node_id); + d.startAngle = (parseInt(hash.substr(0, 2), 16) / 255) * 2 * Math.PI; + }); + this.redraw(); }, drawTile: function (canvas, tilePoint) { function getTileBBox(s, map, tileSize, margin) { - var tl = map.unproject([s.x - margin, s.y - margin]) - var br = map.unproject([s.x + margin + tileSize, s.y + margin + tileSize]) + var tl = map.unproject([s.x - margin, s.y - margin]); + var br = map.unproject([s.x + margin + tileSize, s.y + margin + tileSize]); - return [br.lat, tl.lng, tl.lat, br.lng] + return [br.lat, tl.lng, tl.lat, br.lng]; } if (!this.data) - return + return; - var tileSize = this.options.tileSize - var s = tilePoint.multiplyBy(tileSize) - var map = this._map + var tileSize = this.options.tileSize; + var s = tilePoint.multiplyBy(tileSize); + var map = this._map; - var margin = 50 - var bbox = getTileBBox(s, map, tileSize, margin) + var margin = 50; + var bbox = getTileBBox(s, map, tileSize, margin); - var nodes = this.data.search(bbox) + var nodes = this.data.search(bbox); if (nodes.length === 0) - return + return; - var ctx = canvas.getContext("2d") + var ctx = canvas.getContext("2d"); - var radius = 3 - var a = 1.2 - var startDistance = 12 + var radius = 3; + var a = 1.2; + var startDistance = 12; - ctx.beginPath() + ctx.beginPath(); nodes.forEach(function (d) { - var p = map.project([d.node.nodeinfo.location.latitude, d.node.nodeinfo.location.longitude]) - var clients = d.node.statistics.clients + var p = map.project([d.node.nodeinfo.location.latitude, d.node.nodeinfo.location.longitude]); + var clients = d.node.statistics.clients; if (clients === 0) - return + return; - p.x -= s.x - p.y -= s.y + p.x -= s.x; + p.y -= s.y; for (var orbit = 0, i = 0; i < clients; orbit++) { - var distance = startDistance + orbit * 2 * radius * a - var n = Math.floor((Math.PI * distance) / (a * radius)) - var delta = clients - i + var distance = startDistance + orbit * 2 * radius * a; + var n = Math.floor((Math.PI * distance) / (a * radius)); + var delta = clients - i; for (var j = 0; j < Math.min(delta, n); i++, j++) { - var angle = 2 * Math.PI / n * j - var x = p.x + distance * Math.cos(angle + d.startAngle) - var y = p.y + distance * Math.sin(angle + d.startAngle) + var angle = 2 * Math.PI / n * j; + var x = p.x + distance * Math.cos(angle + d.startAngle); + var y = p.y + distance * Math.sin(angle + d.startAngle); - ctx.moveTo(x, y) - ctx.arc(x, y, radius, 0, 2 * Math.PI) + ctx.moveTo(x, y); + ctx.arc(x, y, radius, 0, 2 * Math.PI); } } - }) + }); - ctx.fillStyle = "rgba(220, 0, 103, 0.7)" - ctx.fill() + ctx.fillStyle = "rgba(220, 0, 103, 0.7)"; + ctx.fill(); } - }) -}) + }); +}); diff --git a/lib/map/labelslayer.js b/lib/map/labelslayer.js index 2912c10..fe5a94c 100644 --- a/lib/map/labelslayer.js +++ b/lib/map/labelslayer.js @@ -7,29 +7,29 @@ define(["leaflet", "rbush"], ["left", "ideographic", 1 / 8], ["right", "top", 5 / 8], ["center", "ideographic", 2 / 8], - ["right", "ideographic", 3 / 8]] + ["right", "ideographic", 3 / 8]]; - var fontFamily = "Roboto" - var nodeRadius = 4 + var fontFamily = "Roboto"; + var nodeRadius = 4; - var ctx = document.createElement("canvas").getContext("2d") + var ctx = document.createElement("canvas").getContext("2d"); function measureText(font, text) { - ctx.font = font - return ctx.measureText(text) + ctx.font = font; + return ctx.measureText(text); } function mapRTree(d) { - var o = [d.position.lat, d.position.lng, d.position.lat, d.position.lng] + var o = [d.position.lat, d.position.lng, d.position.lat, d.position.lng]; - o.label = d + o.label = d; - return o + return o; } function prepareLabel(fillStyle, fontSize, offset, stroke, minZoom) { return function (d) { - var font = fontSize + "px " + fontFamily + var font = fontSize + "px " + fontFamily; return { position: L.latLng(d.nodeinfo.location.latitude, d.nodeinfo.location.longitude), label: d.nodeinfo.hostname, offset: offset, @@ -39,50 +39,50 @@ define(["leaflet", "rbush"], stroke: stroke, minZoom: minZoom, width: measureText(font, d.nodeinfo.hostname).width - } - } + }; + }; } function calcOffset(offset, loc) { return [ offset * Math.cos(loc[2] * 2 * Math.PI), - -offset * Math.sin(loc[2] * 2 * Math.PI)] + -offset * Math.sin(loc[2] * 2 * Math.PI)]; } function labelRect(p, offset, anchor, label, minZoom, maxZoom, z) { - var margin = 1 + 1.41 * (1 - (z - minZoom) / (maxZoom - minZoom)) + var margin = 1 + 1.41 * (1 - (z - minZoom) / (maxZoom - minZoom)); - var width = label.width * margin - var height = label.height * margin + var width = label.width * margin; + var height = label.height * margin; var dx = { left: 0, right: -width, center: -width / 2 - } + }; var dy = { top: 0, ideographic: -height, middle: -height / 2 - } + }; - var x = p.x + offset[0] + dx[anchor[0]] - var y = p.y + offset[1] + dy[anchor[1]] + var x = p.x + offset[0] + dx[anchor[0]]; + var y = p.y + offset[1] + dy[anchor[1]]; - return [x, y, x + width, y + height] + return [x, y, x + width, y + height]; } var c = L.TileLayer.Canvas.extend({ onAdd: function (map) { - L.TileLayer.Canvas.prototype.onAdd.call(this, map) + L.TileLayer.Canvas.prototype.onAdd.call(this, map); if (this.data) - this.prepareLabels() + this.prepareLabels(); }, setData: function (d) { - this.data = d + this.data = d; if (this._map) - this.prepareLabels() + this.prepareLabels(); }, prepareLabels: function () { - var d = this.data + var d = this.data; // label: // - position (WGS84 coords) @@ -92,137 +92,137 @@ define(["leaflet", "rbush"], // - label (string) // - color (string) - var labelsOnline = d.online.map(prepareLabel("rgba(0, 0, 0, 0.9)", 10, 8, true, 13)) - var labelsOffline = d.offline.map(prepareLabel("rgba(212, 62, 42, 0.9)", 9, 5, false, 16)) - var labelsNew = d.new.map(prepareLabel("rgba(48, 99, 20, 0.9)", 11, 8, true, 0)) - var labelsLost = d.lost.map(prepareLabel("rgba(212, 62, 42, 0.9)", 11, 8, true, 0)) + var labelsOnline = d.online.map(prepareLabel("rgba(0, 0, 0, 0.9)", 10, 8, true, 13)); + var labelsOffline = d.offline.map(prepareLabel("rgba(212, 62, 42, 0.9)", 9, 5, false, 16)); + var labelsNew = d.new.map(prepareLabel("rgba(48, 99, 20, 0.9)", 11, 8, true, 0)); + var labelsLost = d.lost.map(prepareLabel("rgba(212, 62, 42, 0.9)", 11, 8, true, 0)); var labels = [] .concat(labelsNew) .concat(labelsLost) .concat(labelsOnline) - .concat(labelsOffline) + .concat(labelsOffline); - var minZoom = this.options.minZoom - var maxZoom = this.options.maxZoom + var minZoom = this.options.minZoom; + var maxZoom = this.options.maxZoom; - var trees = [] + var trees = []; - var map = this._map + var map = this._map; function nodeToRect(z) { return function (d) { - var p = map.project(d.position, z) + var p = map.project(d.position, z); return [p.x - nodeRadius, p.y - nodeRadius, - p.x + nodeRadius, p.y + nodeRadius] - } + p.x + nodeRadius, p.y + nodeRadius]; + }; } for (var z = minZoom; z <= maxZoom; z++) { - trees[z] = rbush(9) - trees[z].load(labels.map(nodeToRect(z))) + trees[z] = rbush(9); + trees[z].load(labels.map(nodeToRect(z))); } labels = labels.map(function (d) { var best = labelLocations.map(function (loc) { - var offset = calcOffset(d.offset, loc) - var z + var offset = calcOffset(d.offset, loc); + var z; for (z = maxZoom; z >= d.minZoom; z--) { - var p = map.project(d.position, z) - var rect = labelRect(p, offset, loc, d, minZoom, maxZoom, z) - var candidates = trees[z].search(rect) + var p = map.project(d.position, z); + var rect = labelRect(p, offset, loc, d, minZoom, maxZoom, z); + var candidates = trees[z].search(rect); if (candidates.length > 0) - break + break; } - return {loc: loc, z: z + 1} + return {loc: loc, z: z + 1}; }).filter(function (d) { - return d.z <= maxZoom + return d.z <= maxZoom; }).sort(function (a, b) { - return a.z - b.z - })[0] + return a.z - b.z; + })[0]; if (best !== undefined) { - d.offset = calcOffset(d.offset, best.loc) - d.minZoom = best.z - d.anchor = best.loc + d.offset = calcOffset(d.offset, best.loc); + d.minZoom = best.z; + d.anchor = best.loc; for (var z = maxZoom; z >= best.z; z--) { - var p = map.project(d.position, z) - var rect = labelRect(p, d.offset, best.loc, d, minZoom, maxZoom, z) - trees[z].insert(rect) + var p = map.project(d.position, z); + var rect = labelRect(p, d.offset, best.loc, d, minZoom, maxZoom, z); + trees[z].insert(rect); } - return d + return d; } else - return undefined - }).filter(function (d) { return d !== undefined }) + return undefined; + }).filter(function (d) { return d !== undefined; }); - this.margin = 16 + this.margin = 16; if (labels.length > 0) this.margin += labels.map(function (d) { - return d.width - }).sort().reverse()[0] + return d.width; + }).sort().reverse()[0]; - this.labels = rbush(9) - this.labels.load(labels.map(mapRTree)) + this.labels = rbush(9); + this.labels.load(labels.map(mapRTree)); - this.redraw() + this.redraw(); }, drawTile: function (canvas, tilePoint, zoom) { function getTileBBox(s, map, tileSize, margin) { - var tl = map.unproject([s.x - margin, s.y - margin]) - var br = map.unproject([s.x + margin + tileSize, s.y + margin + tileSize]) + var tl = map.unproject([s.x - margin, s.y - margin]); + var br = map.unproject([s.x + margin + tileSize, s.y + margin + tileSize]); - return [br.lat, tl.lng, tl.lat, br.lng] + return [br.lat, tl.lng, tl.lat, br.lng]; } if (!this.labels) - return + return; - var tileSize = this.options.tileSize - var s = tilePoint.multiplyBy(tileSize) - var map = this._map + var tileSize = this.options.tileSize; + var s = tilePoint.multiplyBy(tileSize); + var map = this._map; function projectNodes(d) { - var p = map.project(d.label.position) + var p = map.project(d.label.position); - p.x -= s.x - p.y -= s.y + p.x -= s.x; + p.y -= s.y; - return {p: p, label: d.label} + return {p: p, label: d.label}; } - var bbox = getTileBBox(s, map, tileSize, this.margin) + var bbox = getTileBBox(s, map, tileSize, this.margin); - var labels = this.labels.search(bbox).map(projectNodes) + var labels = this.labels.search(bbox).map(projectNodes); - var ctx = canvas.getContext("2d") + var ctx = canvas.getContext("2d"); - ctx.lineWidth = 5 - ctx.strokeStyle = "rgba(255, 255, 255, 0.8)" - ctx.miterLimit = 2 + ctx.lineWidth = 5; + ctx.strokeStyle = "rgba(255, 255, 255, 0.8)"; + ctx.miterLimit = 2; function drawLabel(d) { - ctx.font = d.label.font - ctx.textAlign = d.label.anchor[0] - ctx.textBaseline = d.label.anchor[1] - ctx.fillStyle = d.label.fillStyle + ctx.font = d.label.font; + ctx.textAlign = d.label.anchor[0]; + ctx.textBaseline = d.label.anchor[1]; + ctx.fillStyle = d.label.fillStyle; if (d.label.stroke) - ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]) + ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]); - ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]) + ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]); } labels.filter(function (d) { - return zoom >= d.label.minZoom - }).forEach(drawLabel) + return zoom >= d.label.minZoom; + }).forEach(drawLabel); } - }) + }); - return c -}) + return c; +}); diff --git a/lib/meshstats.js b/lib/meshstats.js index 3174eee..119b37c 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -1,49 +1,49 @@ define(function () { return function (config) { - var self = this - var stats, timestamp + var self = this; + var stats, timestamp; self.setData = function (d) { - var totalNodes = sum(d.nodes.all.map(one)) - var totalOnlineNodes = sum(d.nodes.all.filter(online).map(one)) - var totalNewNodes = sum(d.nodes.new.map(one)) - var totalLostNodes = sum(d.nodes.lost.map(one)) + var totalNodes = sum(d.nodes.all.map(one)); + var totalOnlineNodes = sum(d.nodes.all.filter(online).map(one)); + var totalNewNodes = sum(d.nodes.new.map(one)); + var totalLostNodes = sum(d.nodes.lost.map(one)); var totalClients = sum(d.nodes.all.filter(online).map( function (d) { - return d.statistics.clients ? d.statistics.clients : 0 - })) + return d.statistics.clients ? d.statistics.clients : 0; + })); var totalGateways = sum(d.nodes.all.filter(online).filter( function (d) { - return d.flags.gateway - }).map(one)) + return d.flags.gateway; + }).map(one)); var nodetext = [{ count: totalOnlineNodes, label: "online" }, { count: totalNewNodes, label: "neu" }, { count: totalLostNodes, label: "verschwunden" } - ].filter( function (d) { return d.count > 0 } ) - .map( function (d) { return [d.count, d.label].join(" ") } ) - .join(", ") + ].filter( function (d) { return d.count > 0; } ) + .map( function (d) { return [d.count, d.label].join(" "); } ) + .join(", "); stats.textContent = totalNodes + " Knoten " + "(" + nodetext + "), " + totalClients + " Client" + ( totalClients === 1 ? ", " : "s, " ) + - totalGateways + " Gateways" + totalGateways + " Gateways"; - timestamp.textContent = "Diese Daten sind von " + d.timestamp.format("LLLL") + "." - } + timestamp.textContent = "Diese Daten sind von " + d.timestamp.format("LLLL") + "."; + }; self.render = function (el) { - var h2 = document.createElement("h2") - h2.textContent = config.siteName - el.appendChild(h2) + var h2 = document.createElement("h2"); + h2.textContent = config.siteName; + el.appendChild(h2); - var p = document.createElement("p") - el.appendChild(p) - stats = document.createTextNode("") - p.appendChild(stats) - p.appendChild(document.createElement("br")) - timestamp = document.createTextNode("") - p.appendChild(timestamp) - } + var p = document.createElement("p"); + el.appendChild(p); + stats = document.createTextNode(""); + p.appendChild(stats); + p.appendChild(document.createElement("br")); + timestamp = document.createTextNode(""); + p.appendChild(timestamp); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/nodelist.js b/lib/nodelist.js index efcaf80..e154919 100644 --- a/lib/nodelist.js +++ b/lib/nodelist.js @@ -1,93 +1,93 @@ define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral) { function getUptime(now, d) { if (d.flags.online && "uptime" in d.statistics) - return Math.round(d.statistics.uptime) + return Math.round(d.statistics.uptime); else if (!d.flags.online && "lastseen" in d) - return Math.round(-(now.unix() - d.lastseen.unix())) + return Math.round(-(now.unix() - d.lastseen.unix())); } function showUptime(uptime) { - var s = "" - uptime /= 3600 + var s = ""; + uptime /= 3600; if (uptime !== undefined) if (Math.abs(uptime) >= 24) - s = Math.round(uptime / 24) + "d" + s = Math.round(uptime / 24) + "d"; else - s = Math.round(uptime) + "h" + s = Math.round(uptime) + "h"; - return s + return s; } var headings = [{ name: "Knoten", sort: function (a, b) { - return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname) + return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname); }, reverse: false }, { name: "Uptime", sort: function (a, b) { - return a.uptime - b.uptime + return a.uptime - b.uptime; }, reverse: true }, { name: "#Links", sort: function (a, b) { - return a.meshlinks - b.meshlinks + return a.meshlinks - b.meshlinks; }, reverse: true }, { name: "Clients", sort: function (a, b) { return ("clients" in a.statistics ? a.statistics.clients : -1) - - ("clients" in b.statistics ? b.statistics.clients : -1) + ("clients" in b.statistics ? b.statistics.clients : -1); }, reverse: true - }] + }]; return function(router) { function renderRow(d) { - var td1Content = [] - var aClass = ["hostname", d.flags.online ? "online" : "offline"] + var td1Content = []; + var aClass = ["hostname", d.flags.online ? "online" : "offline"]; td1Content.push(V.h("a", { className: aClass.join(" "), onclick: router.node(d), href: "#" - }, d.nodeinfo.hostname)) + }, d.nodeinfo.hostname)); if (has_location(d)) - td1Content.push(V.h("span", {className: "icon ion-location"})) + td1Content.push(V.h("span", {className: "icon ion-location"})); - var td1 = V.h("td", td1Content) - var td2 = V.h("td", showUptime(d.uptime)) - var td3 = V.h("td", d.meshlinks.toString()) - var td4 = V.h("td", numeral("clients" in d.statistics ? d.statistics.clients : "").format("0,0")) + var td1 = V.h("td", td1Content); + var td2 = V.h("td", showUptime(d.uptime)); + var td3 = V.h("td", d.meshlinks.toString()); + var td4 = V.h("td", numeral("clients" in d.statistics ? d.statistics.clients : "").format("0,0")); - return V.h("tr", [td1, td2, td3, td4]) + return V.h("tr", [td1, td2, td3, td4]); } - var table = new SortTable(headings, 0, renderRow) + var table = new SortTable(headings, 0, renderRow); this.render = function (d) { - var el = document.createElement("div") - d.appendChild(el) + var el = document.createElement("div"); + d.appendChild(el); - var h2 = document.createElement("h2") - h2.textContent = "Alle Knoten" - el.appendChild(h2) + var h2 = document.createElement("h2"); + h2.textContent = "Alle Knoten"; + el.appendChild(h2); - el.appendChild(table.el) - } + el.appendChild(table.el); + }; this.setData = function (d) { var data = d.nodes.all.map(function (e) { - var n = Object.create(e) - n.uptime = getUptime(d.now, e) || 0 - n.meshlinks = e.meshlinks || 0 - return n - }) + var n = Object.create(e); + n.uptime = getUptime(d.now, e) || 0; + n.meshlinks = e.meshlinks || 0; + return n; + }); - table.setData(data) - } - } -}) + table.setData(data); + }; + }; +}); diff --git a/lib/proportions.js b/lib/proportions.js index f1bbb7d..40f3292 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -2,223 +2,223 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc function (Chroma, V, numeral, Filter, vercomp) { return function (config, filterManager) { - var self = this - var scale = Chroma.scale("YlGnBu").mode("lab") + var self = this; + var scale = Chroma.scale("YlGnBu").mode("lab"); - var statusTable = document.createElement("table") - statusTable.classList.add("proportion") + var statusTable = document.createElement("table"); + statusTable.classList.add("proportion"); - var fwTable = document.createElement("table") - fwTable.classList.add("proportion") + var fwTable = document.createElement("table"); + fwTable.classList.add("proportion"); - var hwTable = document.createElement("table") - hwTable.classList.add("proportion") + var hwTable = document.createElement("table"); + hwTable.classList.add("proportion"); - var geoTable = document.createElement("table") - geoTable.classList.add("proportion") + var geoTable = document.createElement("table"); + geoTable.classList.add("proportion"); - var autoTable = document.createElement("table") - autoTable.classList.add("proportion") + var autoTable = document.createElement("table"); + autoTable.classList.add("proportion"); - var uplinkTable = document.createElement("table") - uplinkTable.classList.add("proportion") + var uplinkTable = document.createElement("table"); + uplinkTable.classList.add("proportion"); - var gwNodesTable = document.createElement("table") - gwNodesTable.classList.add("proportion") + var gwNodesTable = document.createElement("table"); + gwNodesTable.classList.add("proportion"); - var gwClientsTable = document.createElement("table") - gwClientsTable.classList.add("proportion") + var gwClientsTable = document.createElement("table"); + gwClientsTable.classList.add("proportion"); - var siteTable = document.createElement("table") - siteTable.classList.add("proportion") + var siteTable = document.createElement("table"); + siteTable.classList.add("proportion"); function showStatGlobal(o) { - return showStat(o) + return showStat(o); } function count(nodes, key, f) { - var dict = {} + var dict = {}; nodes.forEach( function (d) { - var v = dictGet(d, key.slice(0)) + var v = dictGet(d, key.slice(0)); if (f !== undefined) - v = f(v) + v = f(v); if (v === null) - return + return; - dict[v] = 1 + (v in dict ? dict[v] : 0) - }) + dict[v] = 1 + (v in dict ? dict[v] : 0); + }); - return Object.keys(dict).map(function (d) { return [d, dict[d], key, f] }) + return Object.keys(dict).map(function (d) { return [d, dict[d], key, f]; }); } function countClients(nodes, key, f) { - var dict = {} + var dict = {}; nodes.forEach( function (d) { - var v = dictGet(d, key.slice(0)) + var v = dictGet(d, key.slice(0)); if (f !== undefined) - v = f(v) + v = f(v); if (v === null) - return + return; - dict[v] = d.statistics.clients + (v in dict ? dict[v] : 0) - }) + dict[v] = d.statistics.clients + (v in dict ? dict[v] : 0); + }); - return Object.keys(dict).map(function (d) { return [d, dict[d], key, f] }) + return Object.keys(dict).map(function (d) { return [d, dict[d], key, f]; }); } function addFilter(filter) { return function () { - filterManager.addFilter(filter) + filterManager.addFilter(filter); - return false - } + return false; + }; } function fillTable(name, table, data) { if (!table.last) - table.last = V.h("table") + table.last = V.h("table"); - var max = 0 + var max = 0; data.forEach(function (d) { if (d[1] > max) - max = d[1] - }) + max = d[1]; + }); var items = data.map(function (d) { - var v = d[1] / max - var c1 = Chroma.contrast(scale(v), "white") - var c2 = Chroma.contrast(scale(v), "black") + var v = d[1] / max; + var c1 = Chroma.contrast(scale(v), "white"); + var c2 = Chroma.contrast(scale(v), "black"); - var filter = new Filter(name, d[2], d[0], d[3]) + var filter = new Filter(name, d[2], d[0], d[3]); - var a = V.h("a", { href: "#", onclick: addFilter(filter) }, d[0]) + var a = V.h("a", { href: "#", onclick: addFilter(filter) }, d[0]); - var th = V.h("th", a) + var th = V.h("th", a); var td = V.h("td", V.h("span", {style: { width: Math.round(v * 100) + "%", backgroundColor: scale(v).hex(), color: c1 > c2 ? "white" : "black" - }}, numeral(d[1]).format("0,0"))) + }}, numeral(d[1]).format("0,0"))); - return V.h("tr", [th, td]) - }) + return V.h("tr", [th, td]); + }); - var tableNew = V.h("table", items) - table = V.patch(table, V.diff(table.last, tableNew)) - table.last = tableNew + var tableNew = V.h("table", items); + table = V.patch(table, V.diff(table.last, tableNew)); + table.last = tableNew; } self.setData = function (data) { - var onlineNodes = data.nodes.all.filter(online) - var nodes = onlineNodes.concat(data.nodes.lost) - var nodeDict = {} + var onlineNodes = data.nodes.all.filter(online); + var nodes = onlineNodes.concat(data.nodes.lost); + var nodeDict = {}; data.nodes.all.forEach(function (d) { - nodeDict[d.nodeinfo.node_id] = d - }) + nodeDict[d.nodeinfo.node_id] = d; + }); var statusDict = count(nodes, ["flags", "online"], function (d) { - return d ? "online" : "offline" - }) - var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"]) - var hwDict = count(nodes, ["nodeinfo", "hardware", "model"]) + return d ? "online" : "offline"; + }); + var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"]); + var hwDict = count(nodes, ["nodeinfo", "hardware", "model"]); var geoDict = count(nodes, ["nodeinfo", "location"], function (d) { - return d && d.longitude && d.latitude ? "ja" : "nein" - }) + return d && d.longitude && d.latitude ? "ja" : "nein"; + }); var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) { if (d === null) - return null + return null; else if (d.enabled) - return d.branch + return d.branch; else - return "(deaktiviert)" - }) + return "(deaktiviert)"; + }); var uplinkDict = count(nodes, ["flags", "uplink"], function (d) { - return d ? "ja" : "nein" - }) + return d ? "ja" : "nein"; + }); var gwNodesDict = count(onlineNodes, ["statistics", "gateway"], function (d) { if (d === null) - return null + return null; if (d in nodeDict) - return nodeDict[d].nodeinfo.hostname + return nodeDict[d].nodeinfo.hostname; - return d - }) + return d; + }); var gwClientsDict = countClients(onlineNodes, ["statistics", "gateway"], function (d) { if (d === null) - return null + return null; if (d in nodeDict) - return nodeDict[d].nodeinfo.hostname + return nodeDict[d].nodeinfo.hostname; - return d - }) + return d; + }); var siteDict = count(nodes, ["nodeinfo", "system", "site_code"], function (d) { - var rt = d + var rt = d; if (config.siteNames) config.siteNames.forEach( function (t) { if(d === t.site) - rt = t.name - }) - return rt - }) + rt = t.name; + }); + return rt; + }); - fillTable("Status", statusTable, statusDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Firmware", fwTable, fwDict.sort(function (a, b) { return vercomp(b[0], a[0]) })) - fillTable("Hardware", hwTable, hwDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Nodes an Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Clients an Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Site", siteTable, siteDict.sort(function (a, b) { return b[1] - a[1] })) - } + fillTable("Status", statusTable, statusDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Firmware", fwTable, fwDict.sort(function (a, b) { return vercomp(b[0], a[0]); })); + fillTable("Hardware", hwTable, hwDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Nodes an Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Clients an Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1]; })); + fillTable("Site", siteTable, siteDict.sort(function (a, b) { return b[1] - a[1]; })); + }; self.render = function (el) { - var h2 - self.renderSingle(el, "Status", statusTable) - self.renderSingle(el, "Nodes an Gateway", gwNodesTable) - self.renderSingle(el, "Clients an Gateway", gwClientsTable) - self.renderSingle(el, "Firmwareversionen", fwTable) - self.renderSingle(el, "Uplink", uplinkTable) - self.renderSingle(el, "Hardwaremodelle", hwTable) - self.renderSingle(el, "Auf der Karte sichtbar", geoTable) - self.renderSingle(el, "Autoupdater", autoTable) - self.renderSingle(el, "Site", siteTable) + var h2; + self.renderSingle(el, "Status", statusTable); + self.renderSingle(el, "Nodes an Gateway", gwNodesTable); + self.renderSingle(el, "Clients an Gateway", gwClientsTable); + self.renderSingle(el, "Firmwareversionen", fwTable); + self.renderSingle(el, "Uplink", uplinkTable); + self.renderSingle(el, "Hardwaremodelle", hwTable); + self.renderSingle(el, "Auf der Karte sichtbar", geoTable); + self.renderSingle(el, "Autoupdater", autoTable); + self.renderSingle(el, "Site", siteTable); if (config.globalInfos) config.globalInfos.forEach(function (globalInfo) { - h2 = document.createElement("h2") - h2.textContent = globalInfo.name - el.appendChild(h2) - el.appendChild(showStatGlobal(globalInfo)) - }) - } + h2 = document.createElement("h2"); + h2.textContent = globalInfo.name; + el.appendChild(h2); + el.appendChild(showStatGlobal(globalInfo)); + }); + }; self.renderSingle = function (el, heading, table) { - var h2 - h2 = document.createElement("h2") - h2.textContent = heading + var h2; + h2 = document.createElement("h2"); + h2.textContent = heading; h2.onclick = function () { - table.classList.toggle("hidden") - } - el.appendChild(h2) - el.appendChild(table) - } - return self - } -}) + table.classList.toggle("hidden"); + }; + el.appendChild(h2); + el.appendChild(table); + }; + return self; + }; +}); diff --git a/lib/router.js b/lib/router.js index fb56bb1..c737673 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1,214 +1,214 @@ define(function () { return function () { - var self = this - var objects = { nodes: {}, links: {} } - var targets = [] - var views = {} - var currentView - var currentObject - var running = false + var self = this; + var objects = { nodes: {}, links: {} }; + var targets = []; + var views = {}; + var currentView; + var currentObject; + var running = false; function saveState() { - var e = [] + var e = []; if (currentView) - e.push("v:" + currentView) + e.push("v:" + currentView); if (currentObject) { if ("node" in currentObject) - e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id)) + e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id)); if ("link" in currentObject) - e.push("l:" + encodeURIComponent(currentObject.link.id)) + e.push("l:" + encodeURIComponent(currentObject.link.id)); } - var s = "#!" + e.join(";") + var s = "#!" + e.join(";"); - window.history.pushState(s, undefined, s) + window.history.pushState(s, undefined, s); } function resetView(push) { - push = trueDefault(push) + push = trueDefault(push); targets.forEach( function (t) { - t.resetView() - }) + t.resetView(); + }); if (push) { - currentObject = undefined - saveState() + currentObject = undefined; + saveState(); } } function gotoNode(d) { if (!d) - return false + return false; targets.forEach( function (t) { - t.gotoNode(d) - }) + t.gotoNode(d); + }); - return true + return true; } function gotoLink(d) { if (!d) - return false + return false; targets.forEach( function (t) { - t.gotoLink(d) - }) + t.gotoLink(d); + }); - return true + return true; } function gotoLocation(d) { if (!d) - return false + return false; targets.forEach( function (t) { - if(!t.gotoLocation)console.warn("has no gotoLocation", t) - t.gotoLocation(d) - }) + if(!t.gotoLocation)console.warn("has no gotoLocation", t); + t.gotoLocation(d); + }); - return true + return true; } function loadState(s) { if (!s) - return false + return false; - s = decodeURIComponent(s) + s = decodeURIComponent(s); if (!s.startsWith("#!")) - return false + return false; - var targetSet = false + var targetSet = false; s.slice(2).split(";").forEach(function (d) { - var args = d.split(":") + var args = d.split(":"); if (args[0] === "v" && args[1] in views) { - currentView = args[1] - views[args[1]]() + currentView = args[1]; + views[args[1]](); } - var id + var id; if (args[0] === "n") { - id = args[1] + id = args[1]; if (id in objects.nodes) { - currentObject = { node: objects.nodes[id] } - gotoNode(objects.nodes[id]) - targetSet = true + currentObject = { node: objects.nodes[id] }; + gotoNode(objects.nodes[id]); + targetSet = true; } } if (args[0] === "l") { - id = args[1] + id = args[1]; if (id in objects.links) { - currentObject = { link: objects.links[id] } - gotoLink(objects.links[id]) - targetSet = true + currentObject = { link: objects.links[id] }; + gotoLink(objects.links[id]); + targetSet = true; } } - }) + }); - return targetSet + return targetSet; } self.start = function () { - running = true + running = true; if (!loadState(window.location.hash)) - resetView(false) + resetView(false); window.onpopstate = function (d) { if (!loadState(d.state)) - resetView(false) - } - } + resetView(false); + }; + }; self.view = function (d) { if (d in views) { - views[d]() + views[d](); if (!currentView || running) - currentView = d + currentView = d; if (!running) - return + return; - saveState() + saveState(); if (!currentObject) { - resetView(false) - return + resetView(false); + return; } if ("node" in currentObject) - gotoNode(currentObject.node) + gotoNode(currentObject.node); if ("link" in currentObject) - gotoLink(currentObject.link) + gotoLink(currentObject.link); } - } + }; self.node = function (d) { return function () { if (gotoNode(d)) { - currentObject = { node: d } - saveState() + currentObject = { node: d }; + saveState(); } - return false - } - } + return false; + }; + }; self.link = function (d) { return function () { if (gotoLink(d)) { - currentObject = { link: d } - saveState() + currentObject = { link: d }; + saveState(); } - return false - } - } + return false; + }; + }; - self.gotoLocation = gotoLocation + self.gotoLocation = gotoLocation; self.reset = function () { - resetView() - } + resetView(); + }; self.addTarget = function (d) { - targets.push(d) - } + targets.push(d); + }; self.removeTarget = function (d) { targets = targets.filter( function (e) { - return d !== e - }) - } + return d !== e; + }); + }; self.addView = function (k, d) { - views[k] = d - } + views[k] = d; + }; self.setData = function (data) { - objects.nodes = {} - objects.links = {} + objects.nodes = {}; + objects.links = {}; data.nodes.all.forEach( function (d) { - objects.nodes[d.nodeinfo.node_id] = d - }) + objects.nodes[d.nodeinfo.node_id] = d; + }); data.graph.links.forEach( function (d) { - objects.links[d.id] = d - }) - } + objects.links[d.id] = d; + }); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/sidebar.js b/lib/sidebar.js index 464c0fa..7150f7e 100644 --- a/lib/sidebar.js +++ b/lib/sidebar.js @@ -1,49 +1,49 @@ define([], function () { return function (el) { - var self = this + var self = this; - var sidebar = document.createElement("div") - sidebar.classList.add("sidebar") - el.appendChild(sidebar) + var sidebar = document.createElement("div"); + sidebar.classList.add("sidebar"); + el.appendChild(sidebar); - var button = document.createElement("button") - sidebar.appendChild(button) + var button = document.createElement("button"); + sidebar.appendChild(button); - button.classList.add("sidebarhandle") + button.classList.add("sidebarhandle"); button.onclick = function () { - sidebar.classList.toggle("hidden") - } + sidebar.classList.toggle("hidden"); + }; - var container = document.createElement("div") - container.classList.add("container") - sidebar.appendChild(container) + var container = document.createElement("div"); + container.classList.add("container"); + sidebar.appendChild(container); self.getWidth = function () { if (sidebar.classList.contains("hidden")) - return 0 + return 0; - var small = window.matchMedia("(max-width: 630pt)") - return small.matches ? 0 : sidebar.offsetWidth - } + var small = window.matchMedia("(max-width: 630pt)"); + return small.matches ? 0 : sidebar.offsetWidth; + }; self.add = function (d) { - d.render(container) - } + d.render(container); + }; self.ensureVisible = function () { - sidebar.classList.remove("hidden") - } + sidebar.classList.remove("hidden"); + }; self.hide = function () { - container.classList.add("hidden") - } + container.classList.add("hidden"); + }; self.reveal = function () { - container.classList.remove("hidden") - } + container.classList.remove("hidden"); + }; - self.container = sidebar + self.container = sidebar; - return self - } -}) + return self; + }; +}); diff --git a/lib/simplenodelist.js b/lib/simplenodelist.js index 3a7e548..d7be3e8 100644 --- a/lib/simplenodelist.js +++ b/lib/simplenodelist.js @@ -1,63 +1,63 @@ define(["moment", "virtual-dom"], function (moment, V) { return function(nodes, field, router, title) { - var self = this - var el, tbody + var self = this; + var el, tbody; self.render = function (d) { - el = document.createElement("div") - d.appendChild(el) - } + el = document.createElement("div"); + d.appendChild(el); + }; self.setData = function (data) { - var list = data.nodes[nodes] + var list = data.nodes[nodes]; if (list.length === 0) { while (el.firstChild) - el.removeChild(el.firstChild) + el.removeChild(el.firstChild); - tbody = null + tbody = null; - return + return; } if (!tbody) { - var h2 = document.createElement("h2") - h2.textContent = title - el.appendChild(h2) + var h2 = document.createElement("h2"); + h2.textContent = title; + el.appendChild(h2); - var table = document.createElement("table") - el.appendChild(table) + var table = document.createElement("table"); + el.appendChild(table); - tbody = document.createElement("tbody") - tbody.last = V.h("tbody") - table.appendChild(tbody) + tbody = document.createElement("tbody"); + tbody.last = V.h("tbody"); + table.appendChild(tbody); } var items = list.map( function (d) { - var time = moment(d[field]).from(data.now) - var td1Content = [] + var time = moment(d[field]).from(data.now); + var td1Content = []; - var aClass = ["hostname", d.flags.online ? "online" : "offline"] + var aClass = ["hostname", d.flags.online ? "online" : "offline"]; td1Content.push(V.h("a", { className: aClass.join(" "), onclick: router.node(d), href: "#" - }, d.nodeinfo.hostname)) + }, d.nodeinfo.hostname)); if (has_location(d)) - td1Content.push(V.h("span", {className: "icon ion-location"})) + td1Content.push(V.h("span", {className: "icon ion-location"})); - var td1 = V.h("td", td1Content) - var td2 = V.h("td", time) + var td1 = V.h("td", td1Content); + var td2 = V.h("td", time); - return V.h("tr", [td1, td2]) - }) + return V.h("tr", [td1, td2]); + }); - var tbodyNew = V.h("tbody", items) - tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew)) - tbody.last = tbodyNew - } + var tbodyNew = V.h("tbody", items); + tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew)); + tbody.last = tbodyNew; + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/sorttable.js b/lib/sorttable.js index d6a39a1..4419243 100644 --- a/lib/sorttable.js +++ b/lib/sorttable.js @@ -1,57 +1,57 @@ define(["virtual-dom"], function (V) { return function(headings, sortIndex, renderRow) { - var data - var sortReverse = false - var el = document.createElement("table") - var elLast = V.h("table") + var data; + var sortReverse = false; + var el = document.createElement("table"); + var elLast = V.h("table"); function sortTable(i) { - sortReverse = i === sortIndex ? !sortReverse : false - sortIndex = i + sortReverse = i === sortIndex ? !sortReverse : false; + sortIndex = i; - updateView() + updateView(); } function sortTableHandler(i) { - return function () { sortTable(i) } + return function () { sortTable(i); }; } function updateView() { - var children = [] + var children = []; if (data.length !== 0) { var th = headings.map(function (d, i) { var properties = { onclick: sortTableHandler(i), className: "sort-header" - } + }; if (sortIndex === i) - properties.className += sortReverse ? " sort-up" : " sort-down" + properties.className += sortReverse ? " sort-up" : " sort-down"; - return V.h("th", properties, d.name) - }) + return V.h("th", properties, d.name); + }); - var links = data.slice(0).sort(headings[sortIndex].sort) + var links = data.slice(0).sort(headings[sortIndex].sort); if (headings[sortIndex].reverse ? !sortReverse : sortReverse) - links = links.reverse() + links = links.reverse(); - children.push(V.h("thead", V.h("tr", th))) - children.push(V.h("tbody", links.map(renderRow))) + children.push(V.h("thead", V.h("tr", th))); + children.push(V.h("tbody", links.map(renderRow))); } - var elNew = V.h("table", children) - el = V.patch(el, V.diff(elLast, elNew)) - elLast = elNew + var elNew = V.h("table", children); + el = V.patch(el, V.diff(elLast, elNew)); + elLast = elNew; } this.setData = function (d) { - data = d - updateView() - } + data = d; + updateView(); + }; - this.el = el + this.el = el; - return this - } -}) + return this; + }; +}); diff --git a/lib/tabs.js b/lib/tabs.js index 7605742..63eaea8 100644 --- a/lib/tabs.js +++ b/lib/tabs.js @@ -1,57 +1,57 @@ define([], function () { return function () { - var self = this + var self = this; - var tabs = document.createElement("ul") - tabs.classList.add("tabs") + var tabs = document.createElement("ul"); + tabs.classList.add("tabs"); - var container = document.createElement("div") + var container = document.createElement("div"); function gotoTab(li) { for (var i = 0; i < tabs.children.length; i++) - tabs.children[i].classList.remove("visible") + tabs.children[i].classList.remove("visible"); while (container.firstChild) - container.removeChild(container.firstChild) + container.removeChild(container.firstChild); - li.classList.add("visible") + li.classList.add("visible"); - var tab = document.createElement("div") - tab.classList.add("tab") - container.appendChild(tab) - li.child.render(tab) + var tab = document.createElement("div"); + tab.classList.add("tab"); + container.appendChild(tab); + li.child.render(tab); } function switchTab() { - gotoTab(this) + gotoTab(this); - return false + return false; } self.add = function (title, d) { - var li = document.createElement("li") - li.textContent = title - li.onclick = switchTab - li.child = d - tabs.appendChild(li) + var li = document.createElement("li"); + li.textContent = title; + li.onclick = switchTab; + li.child = d; + tabs.appendChild(li); - var anyVisible = false + var anyVisible = false; for (var i = 0; i < tabs.children.length; i++) if (tabs.children[i].classList.contains("visible")) { - anyVisible = true - break + anyVisible = true; + break; } if (!anyVisible) - gotoTab(li) - } + gotoTab(li); + }; self.render = function (el) { - el.appendChild(tabs) - el.appendChild(container) - } + el.appendChild(tabs); + el.appendChild(container); + }; - return self - } -}) + return self; + }; +}); diff --git a/lib/title.js b/lib/title.js index e9377a4..7585c82 100644 --- a/lib/title.js +++ b/lib/title.js @@ -1,35 +1,35 @@ define(function () { return function (config) { function setTitle(d) { - var title = [config.siteName] + var title = [config.siteName]; if (d !== undefined) - title.push(d) + title.push(d); - document.title = title.join(": ") + document.title = title.join(": "); } this.resetView = function () { - setTitle() - } + setTitle(); + }; this.gotoNode = function (d) { if (d) - setTitle(d.nodeinfo.hostname) - } + setTitle(d.nodeinfo.hostname); + }; this.gotoLink = function (d) { if (d) - setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname) - } + setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname); + }; this.gotoLocation = function() { //ignore - } + }; this.destroy = function () { - } + }; - return this - } -}) + return this; + }; +}); diff --git a/lib/vercomp.js b/lib/vercomp.js index 428f258..b829b94 100644 --- a/lib/vercomp.js +++ b/lib/vercomp.js @@ -1,60 +1,60 @@ define([], function () { function order(c) { if (/^\d$/.test(c)) - return 0 + return 0; else if (/^[a-z]$/i.test(c)) - return c.charCodeAt(0) + return c.charCodeAt(0); else if (c === "~") - return -1 + return -1; else if (c) - return c.charCodeAt(0) + 256 + return c.charCodeAt(0) + 256; else - return 0 + return 0; } // Based on dpkg code function vercomp(a, b) { - var apos = 0, bpos = 0 + var apos = 0, bpos = 0; while (apos < a.length || bpos < b.length) { - var firstDiff = 0 + var firstDiff = 0; while ((apos < a.length && !/^\d$/.test(a[apos])) || (bpos < b.length && !/^\d$/.test(b[bpos]))) { - var ac = order(a[apos]) - var bc = order(b[bpos]) + var ac = order(a[apos]); + var bc = order(b[bpos]); if (ac !== bc) - return ac - bc + return ac - bc; - apos++ - bpos++ + apos++; + bpos++; } while (a[apos] === "0") - apos++ + apos++; while (b[bpos] === "0") - bpos++ + bpos++; while (/^\d$/.test(a[apos]) && /^\d$/.test(b[bpos])) { if (firstDiff === 0) - firstDiff = a.charCodeAt(apos) - b.charCodeAt(bpos) + firstDiff = a.charCodeAt(apos) - b.charCodeAt(bpos); - apos++ - bpos++ + apos++; + bpos++; } if (/^\d$/.test(a[apos])) - return 1 + return 1; if (/^\d$/.test(b[bpos])) - return -1 + return -1; if (firstDiff !== 0) - return firstDiff + return firstDiff; } - return 0 + return 0; } - return vercomp -}) + return vercomp; +}); diff --git a/tasks/build.js b/tasks/build.js index 5a8c918..d4f4a45 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -5,7 +5,7 @@ module.exports = function(grunt) { html: { options: { process: function (content) { - return content.replace("#revision#", grunt.option("gitRevision")) + return content.replace("#revision#", grunt.option("gitRevision")); } }, src: ["*.html"], @@ -115,11 +115,11 @@ module.exports = function(grunt) { } } } - }) + }); - grunt.loadNpmTasks("grunt-bower-install-simple") - grunt.loadNpmTasks("grunt-contrib-copy") - grunt.loadNpmTasks("grunt-contrib-requirejs") - grunt.loadNpmTasks("grunt-sass") - grunt.loadNpmTasks("grunt-postcss") -} + grunt.loadNpmTasks("grunt-bower-install-simple"); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-contrib-requirejs"); + grunt.loadNpmTasks("grunt-sass"); + grunt.loadNpmTasks("grunt-postcss"); +}; diff --git a/tasks/clean.js b/tasks/clean.js index 989ef08..ed0e234 100644 --- a/tasks/clean.js +++ b/tasks/clean.js @@ -3,7 +3,7 @@ module.exports = function (grunt) { clean: { build: ["build/**/*", "node_modules/grunt-newer/.cache"] } - }) + }); - grunt.loadNpmTasks("grunt-contrib-clean") -} + grunt.loadNpmTasks("grunt-contrib-clean"); +}; diff --git a/tasks/development.js b/tasks/development.js index 6c799d2..2c00cd7 100644 --- a/tasks/development.js +++ b/tasks/development.js @@ -24,8 +24,8 @@ module.exports = function (grunt) { tasks: [] } } - }) + }); - grunt.loadNpmTasks("grunt-contrib-connect") - grunt.loadNpmTasks("grunt-contrib-watch") -} + grunt.loadNpmTasks("grunt-contrib-connect"); + grunt.loadNpmTasks("grunt-contrib-watch"); +}; diff --git a/tasks/linting.js b/tasks/linting.js index a05bce0..716e838 100644 --- a/tasks/linting.js +++ b/tasks/linting.js @@ -14,7 +14,6 @@ module.exports = function (grunt) { eslint: { options: { rules: { - "semi": [2, "never"], "curly": [2, "multi"], "strict": [2, "never"], "no-multi-spaces": 0, @@ -31,8 +30,8 @@ module.exports = function (grunt) { src: ["Gruntfile.js", "tasks/*.js"] } } - }) + }); - grunt.loadNpmTasks("grunt-check-dependencies") - grunt.loadNpmTasks("grunt-eslint") -} + grunt.loadNpmTasks("grunt-check-dependencies"); + grunt.loadNpmTasks("grunt-eslint"); +};