norstalgia/norsecorp/js/app.min.js

1392 lines
43 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @param {Object} data
* @param {Object} o
* @return {?}
*/
function Mover(data, o) {
if (this.created = data.created, this.x = data.x, this.y = data.y, this.offset = data.offset, this.destination = data.destination, this.layer = o.el, this.color = "hsl(" + data.port % 360 + ", 100%, 70%)", this.hit = data.onMoverHit, this.x === this.destination.x && this.y === this.destination.y) {
return void this.hit();
}
/** @type {string} */
var _tmp = "clippath-" + Math.random();
this.clipPath = o._defs.append("clipPath").attr("id", _tmp);
this.cliprect = this.clipPath.append("rect").attr({
x: -trail.radius,
y: -trail.radius,
width: trail.height,
height: trail.base
});
this.obj = this.layer.append("polygon").datum(this).classed("animating", true).attr("points", trail.points).attr("clip-path", "url(#" + _tmp + ")").attr("fill", this.color);
var vector = this.destination;
return this.dx = vector.lx - this.x, this.dy = vector.ly - this.y, this.distance = Math.sqrt(this.dx * this.dx + this.dy * this.dy), this.update(), data.zerg && this.distance > 3 * trail.height ? this.startCurve() : this.start(), this;
}
/**
* @param {?} dataAndEvents
* @param {?} position
* @return {undefined}
*/
function Floater(dataAndEvents, position) {
if (!num) {
/** @type {number} */
num = 1;
}
this.position = position;
this.addOne();
}
/**
* @return {undefined}
*/
function Anchor() {}
/**
* @param {Object} options
* @return {undefined}
*/
function Ping(options) {
this.position = options.position;
}
var ipv = {
version: "0"
};
/** @type {number} */
var ZERO = 1E-6;
/** @type {number} */
var TWO_PI = 2 * Math.PI;
var ipv_helpers = {
/**
* @param {Object} b
* @param {Object} a
* @return {?}
*/
sort_descCountAscCountry: function(b, a) {
return a.count > b.count ? 1 : a.count < b.count ? -1 : b.country < a.country ? 1 : a.country < b.country ? -1 : 0;
},
/**
* @param {Object} b
* @param {Object} a
* @return {?}
*/
sort_descCountAscService: function(b, a) {
return a.count > b.count ? 1 : a.count < b.count ? -1 : b.service < a.service ? 1 : a.service < b.service ? -1 : 0;
},
/**
* @param {Object} srv
* @return {?}
*/
return_cx: function(srv) {
return srv.cx;
},
/**
* @param {Object} o2
* @return {?}
*/
return_cy: function(o2) {
return o2.cy;
},
/**
* @param {MessageEvent} params
* @return {?}
*/
return_data: function(params) {
return params.data;
},
/**
* @param {?} dataAndEvents
* @return {?}
*/
d3_identity: function(dataAndEvents) {
return dataAndEvents;
}
};
ipv.hash = {
args: {},
/**
* @param {string} query
* @return {?}
*/
parse: function(query) {
query = (query || window.location.search).replace(/^\?/, "");
var args = {};
return query.split("&").forEach(function(pair) {
pair = pair.split("=");
args[pair[0]] = pair[1];
}), this.args = args, args;
},
/**
* @return {undefined}
*/
set: function() {}
},
ipv.stream = {
timestamp: d3.time.format("%Y-%m-%d %H:%M:%S.%L"),
active: null,
backlog: [],
timeout: 1e3
},
ipv.stream.socket = function(options, callback) {
/** @type {WebSocket} */
var self = new WebSocket(options.host);
return self.onopen = function() {
setInterval(function () {
self.send(options.psk);
}, 1000);
},
self.onmessage = callback,
self.onclose = function() {
var client = ipv.stream;
setTimeout(function() {
self = client.socket(options, callback);
}, client.timeout);
},
self.onerror = function() {
console.log("socket error");
},
ipv.stream.active = self,
self;
},
// Todo
ipv.stream.json = function(obj, files) {
/** @type {number} */
var frequency = 3000;
d3.json(obj, function(dataAndEvents, results) {
if (dataAndEvents) {
throw dataAndEvents;
}
results = results.map(function(data) {
return {
data: JSON.stringify(data),
timestamp: data.timestamp
};
});
var data = d3.nest().key(function(data) {
return "string" == typeof data.timestamp && (data.timestamp = +ipv.stream.timestamp(data.timestamp)), Math.round(data.timestamp / frequency) * frequency;
}).map(results);
var values = d3.keys(data).map(Number);
values.sort(d3.ascending);
var value = values[0];
/** @type {number} */
var id = setInterval(function() {
if (values.length) {
if (values[0] === value) {
data["" + values.shift()].forEach(files);
}
value += frequency;
} else {
clearInterval(id);
}
}, frequency);
});
},
// 暂停
ipv.stream.pause = function() {
if (ipv.stream.active) {
/** @type {boolean} */
ipv.stream.paused = true;
/** @type {number} */
ipv.stream.backlog.length = 0;
ipv.stream.msgHandler = ipv.stream.active.onmessage.bind({});
/**
* @param {?} m
* @return {undefined}
*/
ipv.stream.active.onmessage = function(m) {
if (ipv.stream.backlog.length >= 5E3) {
ipv.stream.backlog.shift();
}
ipv.stream.backlog.push(m);
};
}
},
// 播放
ipv.stream.play = function() {
if (ipv.stream.active) {
/** @type {boolean} */
ipv.stream.paused = false;
ipv.stream.active.onmessage = ipv.stream.msgHandler.bind(ipv.stream.active);
ipv.stream.backlog.forEach(function(msg) {
ipv.stream.active.onmessage(msg);
});
/** @type {number} */
ipv.stream.backlog.length = 0;
}
},
// 经纬度和坐标映射
ipv.map = function(obj) {
var map = L.map(obj.container, obj.options);
return map._proj = function(lng, lat) {
var offsetCoordinate = map.latLngToLayerPoint(new L.LatLng(lat, lng));
return [offsetCoordinate.x, offsetCoordinate.y];
}, map;
};
var trail = function() {
/** @type {number} */
var size = 2;
/** @type {number} */
var length = 2 * size;
/** @type {number} */
var x = 40 * length;
/** @type {number} */
var totalFiles = 6;
var logo_center = {
x: size,
y: size
};
/** @type {number} */
var b = Math.PI / 2;
/** @type {number} */
var a = 3 * Math.PI / 2;
/** @type {Array} */
var points = [];
/** @type {number} */
var filesSent = 0;
for (; totalFiles >= filesSent; ++filesSent) {
/** @type {number} */
var theta2 = b + (a - b) * (filesSent / totalFiles);
/** @type {number} */
var frame_temp = logo_center.x + size * Math.cos(theta2);
/** @type {number} */
var gutterTop = logo_center.y + size * Math.sin(theta2);
points.push([frame_temp - size, gutterTop - size]);
}
return points.push([x, length / 2], points[0]), {
points: points,
base: length,
height: size + x,
radius: size,
center: {
x: x / 2,
y: length / 2
}
};
}();
Mover.prototype.startCurve = function() {
/**
* @return {?}
*/
function _init() {
return function(weight) {
/** @type {number} */
var column = 1 - weight;
/** @type {number} */
var i = column * column;
/** @type {number} */
var r = 2 * column * weight;
/** @type {number} */
var g = weight * weight;
/** @type {number} */
var x = i * self.x + r * area.x + g * other.lx;
/** @type {number} */
var y = i * self.y + r * area.y + g * other.ly;
/** @type {number} */
var CIRCLE_AREA_TO_SCREEN_REL = Math.atan2(dest[1] - y, dest[0] - x);
return dest[0] = x, dest[1] = y, "translate(" + [x, y] + ") rotate(" + [180 * CIRCLE_AREA_TO_SCREEN_REL / Math.PI, 0, 0] + ")";
};
}
var other = this.destination;
this.dx;
dy = this.dy;
distance = this.distance;
/** @type {number} */
radius = distance / 2 * (Math.random() - 0.5);
height = trail.height;
/** @type {number} */
var y = height / distance;
var h = height;
/** @type {number} */
var duration = 750;
var self = this;
/** @type {number} */
var startAngle = Math.atan2(this.y - other.ly, this.x - other.lx);
/** @type {number} */
var angle = startAngle + Math.PI / 2;
var area = {
x: (this.x + other.lx) / 2 + radius * Math.cos(angle),
y: (this.y + other.ly) / 2 + radius * Math.sin(angle)
};
/** @type {Array} */
var dest = [this.x, this.y];
/** @type {number} */
var temp2 = duration * y;
this.cliprect.attr("width", 0).transition().duration(temp2).ease("linear").attr("width", h);
this.obj.transition().duration(temp2).ease("linear").attr("transform", _init()(y)).each("end", function() {
y = 1 === y ? 0 : y;
/** @type {number} */
_1mpos = 1 - y;
/**
* @param {number} x
* @return {?}
*/
var easing = function(x) {
return x >= 1 ? 1 : x * _1mpos + y;
};
self.obj.transition().duration(duration).ease(easing).attrTween("transform", _init).each("end", function() {
self.cliprect.transition().duration(temp2).ease("linear").attr("width", 0).each("end", function() {
/** @type {boolean} */
self.animating = false;
self.x = other.lx;
self.y = other.ly;
self.die();
});
});
});
},
Mover.prototype.start = function() {
var position = this.destination;
/** @type {number} */
var x = position.lx - this.x;
/** @type {number} */
var y = position.ly - this.y;
/** @type {number} */
var b = Math.sqrt(x * x + y * y);
var a = trail.height;
/** @type {string} */
var arc = "translate(" + [position.lx + this.offset.x, position.ly + this.offset.y] + ") rotate(" + this.svgRotation() + ")";
if (a > b) {
/** @type {number} */
var cos = 1;
/** @type {number} */
var key = b;
/** @type {number} */
var duration = 50;
} else {
/** @type {number} */
cos = a / b;
key = a;
/** @type {number} */
duration = 750;
}
/** @type {Array} */
var j = [x * cos + this.x, y * cos + this.y];
var self = this;
/** @type {number} */
var complicated = duration * cos;
this.cliprect.attr("width", 0).transition().duration(complicated).ease("linear").attr("width", key);
this.obj.transition().duration(complicated).ease("linear").attr("transform", "translate(" + j + ") rotate(" + this.svgRotation() + ")").each("end", function() {
self.obj.transition().duration(duration).ease("linear").attr("transform", arc).each("end", function() {
self.cliprect.transition().duration(complicated).ease("linear").attr("width", 0).each("end", function() {
/** @type {boolean} */
self.animating = false;
self.x = position.lx;
self.y = position.ly;
self.die();
});
});
});
},
Mover.prototype.theta = function(pointer) {
return 180 * Math.atan2(this.y - pointer.ly, this.x - pointer.lx) / Math.PI;
},
Mover.prototype.svgRotation = function() {
return [this.theta(this.destination), 0, 0];
},
Mover.prototype.update = function() {
this.obj.attr("transform", "translate(" + [this.x, this.y] + ") rotate(" + this.svgRotation() + ")");
},
Mover.prototype.setPosition = function(point, opt_arg2) {
/** @type {Object} */
this.destination = opt_arg2;
this.obj.attr("transform", "translate(" + [this.x = point.x, this.y = point.y] + ") rotate(" + this.svgRotation() + ")");
},
Mover.prototype.die = function() {
this.obj.remove();
this.clipPath.remove();
this.hit();
return this.layer.append("circle").classed("animating", true).attr({
cx: this.x + this.offset.x,
cy: this.y + this.offset.y,
fill: "none",
stroke: this.color,
"stroke-width": 5,
r: 1E-6
}).style({
opacity: 1
}).transition().duration(2600).ease("cubic-out").style("opacity", 1E-6).attr("r", 100).remove(), false;
},
Floater.prototype.addOne = function() {}, ipv.ui = function() {
/**
* @param {Function} body
* @return {undefined}
*/
function init(body) {
var path = body.selectAll(".module").data(d3.values(data), function(keyOrObj) {
return keyOrObj.key;
});
var scene = path.enter().append("div").classed("module", true).attr("id", function(keyOrObj) {
return "ui-datatable-" + keyOrObj.key;
}).style("width", function($slide) {
return $slide.width;
});
var table = (scene.append("div").classed("title", true).text(function(c) {
return c.name.toUpperCase();
}), scene.append("table").classed("table", true));
var cursor = path.select("table").datum(function(transition) {
return transition;
});
table.append("tr").classed("header", true).selectAll("td").data(function(row) {
return row.columns;
}).enter().append("td").attr("class", function(list) {
return "count" === list.attr || "timestamp" === list.attr ? "number" : "";
}).style("width", function($slide) {
return $slide.width;
}).text(function(result) {
return result.display;
});
cursor.each(function(index) {
self.datatables[index.key] = d3.select(this);
});
self.minibar = path.select(".title").append("div").classed("minibar", true);
self.minibar.each(function(v) {
if (!v.viz) {
this.parentNode.removeChild(this);
}
});
var update = ipv.ui.widgets.clock();
self.clock = {
update: update,
el: body.append("div").datum([]).attr({
id: "ui-clock",
"class": "module"
})
};
self.clock.el.call(update);
self.minimizebutton = body.call(ipv.ui.widgets.minimizebutton);
}
var data;
var self = {
datatables: {},
minibar: {}
};
var managedListeners = ipv.ui.cellfmt;
return init.layout = function(size) {
return arguments.length ? (data = {}, size.forEach(function(element) {
/** @type {Object} */
data[element.key] = element;
}), init) : data;
}, init.widgets = function(str) {
/**
* @param {Array} last
* @param {?} data
* @return {?}
*/
function process(last, data) {
if (data = data || self, !last.length) {
return data;
}
var tmp = data[last.shift()];
return tmp ? (data = tmp, process(last, data)) : data;
}
return str && "string" == typeof str ? process(str.split(".")) : self;
}, init.center = null, init.update = function(obj) {
var chart = self.minibar.data(obj.datatables, function(statement) {
return statement.type;
});
var node = chart.selectAll(".bar").data(function(messageEvent) {
return messageEvent.data;
});
node.enter().append("div").classed("bar", true).style("width", "3px");
/** @type {number} */
var height = 30;
node.style("height", function(v) {
return v.parent = this.parentNode.__data__, v.height = ~~(v.count / v.parent.data[0].count * (height - 5)) + 5, v.height + "px";
}).style("background-color", function(state) {
return "service" === state.parent.type ? state.color : "#ccc";
}).style("margin-top", function(line) {
return height - line.height + "px";
});
/** @type {number} */
var i = 0;
for (; i < obj.datatables.length; i++) {
var event = obj.datatables[i];
var div = self.datatables[event.type].selectAll(".row").data(event.data);
var args = (div.enter().append("tr").classed("row", true), div.selectAll("td").data(managedListeners[event.type]));
args.html(String);
args.enter().append("td").attr("class", function(dataAndEvents, b) {
return "cell " + this.parentNode.parentNode.firstChild.children[b].className;
});
}
self.clock.el.datum(obj.clock).call(self.clock.update);
if (!init.center) {
if (!("events" !== event.type)) {
if (!(10 !== event.data.length)) {
init.center = self.clock.update.center();
self.clock.el.select("#chevron").style("visibility", "visible").attr("transform", "translate(" + [init.center.x, init.center.y] + ")");
}
}
}
}, init;
},
ipv.ui.widgets = {
/**
* @return {?}
*/
minibar: function() {
/**
* @param {?} vals
* @return {undefined}
*/
function reduce(vals) {
vals.each(function() {});
}
return reduce;
},
/**
* @return {?}
*/
clock: function() {
/**
* @param {HTMLElement} element
* @return {?}
*/
function init(element) {
var width = element.clientWidth;
var olen = element.parentNode.clientHeight;
/** @type {number} */
var max = Math.min(width, olen);
return i !== max ? (i = max, j = i / 3, value = {
x: i / 2,
y: i / 1.5
}, x2 = j / 4, y = x2 / 2, d3.select(element).select("svg").attr("width", i + "px").attr("height", i + "px"), t = {
x1: 0,
y1: y,
x2: x2,
y2: y
}, true) : void 0;
}
/**
* @param {?} _
* @return {undefined}
*/
function chart(_) {
_.each(function(data) {
if (!p) {
init(this);
/** @type {boolean} */
p = true;
var groups = d3.select(this).selectAll("svg").data([data]);
var element = groups.enter().append("svg").append("g");
element.each(animate);
layer = groups.select("g");
}
if (data.length < 10) {
if (init(this)) {
/** @type {Array} */
data = [];
}
}
/** @type {number} */
var now = Date.now();
var div = layer.selectAll("line").data(data.filter(function(b) {
return now - b.meta.created < updateTimer;
}), function(dataAndEvents) {
return dataAndEvents.$loki;
});
div.style("opacity", function(b) {
return 1 - (now - b.meta.created) / millisecondsPerSecond;
});
div.enter().append("line").classed("ticker-line", true).attr(t).style("stroke", function(entry) {
return entry.service.color;
}).attr("transform", function() {
/** @type {number} */
var theta2 = -rot * Math.PI / 180;
var h = value.x + j * Math.cos(theta2);
var dy1 = value.y + j * Math.sin(theta2);
return "translate(" + [h - y, dy1 - y] + ") rotate(" + [-rot, y, y] + ")";
});
div.exit().remove();
});
}
/**
* @return {?}
*/
function start() {
return function(dataAndEvents) {
return rot = 360 * dataAndEvents, "rotate(" + [rot, value.x, value.y] + ")";
};
}
/**
* @return {undefined}
*/
function animate() {
d3.select(this).interrupt().transition();
d3.select(this).attr("transform", "rotate(0," + [value.x, value.y] + ")").transition().duration(duration).ease("linear").attrTween("transform", start).each("end", animate);
}
var rot;
var i;
var j;
var value;
var x2;
var y;
var layer;
var t;
/** @type {number} */
var duration = 3E4;
/** @type {number} */
var updateTimer = duration - 0.1 * duration;
/** @type {number} */
var millisecondsPerSecond = duration + 0.01 * duration;
/** @type {boolean} */
var p = false;
return chart.center = function(x) {
return arguments.length ? (value = x, chart) : value;
}, chart;
},
/**
* @return {?}
*/
minimizebutton: function() {
/** @type {boolean} */
var perm = false;
/** @type {Array} */
var items = ["+", "_"];
var c = this.append("div").classed("minimize-button minimize", true).text("_");
var event = c.style("height");
return c.on("mousedown", function() {
c.text(items[+perm]);
var type = perm ? "" : event;
d3.select(this.parentNode).transition().duration(1E3).style("height", type);
/** @type {boolean} */
perm = !perm;
}), c;
}
}, ipv.ui.cellfmt = {
/**
* @param {Object} response
* @return {?}
*/
source: function(response) {
return [response.count, response.display];
},
/**
* @param {Object} result
* @return {?}
*/
target: function(result) {
return [result.count, result.display];
},
/**
* @param {Object} defaults
* @return {?}
*/
service: function(defaults) {
return [defaults.count, defaults.port, defaults.display];
},
/**
* @param {Object} entry
* @return {?}
*/
events: function(entry) {
var value = entry.service;
return [entry.timestamp, entry.org, entry.ip, entry.source, entry.target, '<span style="color: ' + value.color + '">' + value.service + "</span>", value.port];
}
},
// 自运行
function() {
/**
* @param {Array} id
* @return {?}
*/
function load(id) {
/** @type {boolean} */
var b = false;
return id.forEach(function(jQuery) {
var count = jQuery.data[0].count;
if (count > event[jQuery.type].domain()[1]) {
event[jQuery.type].domain([1, count]);
/** @type {boolean} */
b = true;
}
}), b;
}
/**
* @param {?} query
* @return {?}
*/
function init(query) {
var rows = col.find(query);
var data = {
meta: {
totalLinks: rows.length,
maxFreq: 0
},
data: {}
};
return rows.forEach(function(inEvent) {
var d = inEvent.sourceObj;
var bounds = inEvent.targetObj;
var name = d.key + bounds.key;
var self = data.data[name] || (data.data[name] = {
count: 0,
max: {
port: "unknown",
count: 0
},
source: [d.lx, d.ly],
target: [bounds.lx, bounds.ly],
ports: {}
});
if (++self.count > data.meta.maxFreq) {
data.meta.maxFreq = self.count;
}
var options = inEvent.service;
port = options.port;
var count = self.ports[port] = (self.ports[port] || 0) + 1;
if (count > self.max.count) {
self.max.color = options.color;
self.max.port = port;
self.max.count = count;
}
}), data.data = d3.values(data.data), data;
}
/**
* @param {Object} msg
* @return {undefined}
*/
function enter(msg) {
var linkItems = chart.selectAll(".links").data(msg.data);
linkItems.enter().append("path").classed("links", true);
linkItems.attr("d", function(d) {
return "M" + [d.source] + "L" + [d.target];
}).style("stroke", function(element) {
return element.max.color;
}).style("stroke-width", function(collection) {
return Math.max(1, collection.count / msg.meta.maxFreq * 5);
}).style("opacity", function(collection) {
return collection.count / msg.meta.totalLinks + 0.5;
});
linkItems.exit().remove();
}
/**
* @return {undefined}
*/
function transition() {
var a = chart.selectAll(".links").remove();
/** @type {null} */
a = null;
}
/**
* @param {number} backoff
* @return {undefined}
*/
function ping(backoff) {
console.log("expire");
/** @type {number} */
var chipsFor = Date.now();
/** @type {number} */
var viewPortRight = chipsFor - backoff;
col.removeWhere(function(req) {
/** @type {boolean} */
var enoughRoomOnRight = req.meta.created <= viewPortRight;
if (enoughRoomOnRight) {
var node = req.sourceObj;
var p = req.targetObj;
node.count--;
p.count--;
node.countryObj.count--;
p.countryObj.count--;
req.serviceObj.count--;
}
return enoughRoomOnRight;
});
}
/**
* 开始渲染页面
* @param {boolean} delegate 是否异常
* @param {Object} json_config json_config 配置项
* @param {Array} nmap_services 协议端口映射表
* @param {?} country_codes 国家(地区)简写与全称映射表
* @param {Object} layout 页面布局配置
* @param {?} dotCanvas particle-inverse.png图片对象
* @return {undefined}
*/
function show(delegate, json_config, nmap_services, country_codes, layout, dotCanvas) {
/**
* @param {Element} node
* @return {undefined}
*/
function init(node) {
/** @type {(Element|null)} */
var frag = document.querySelector("#ui-clock svg");
frag.appendChild(node);
var docFrag = d3.select("#chevron-container").append("svg").node();
d3.select("#svg-toggle-info").on("mousedown", function() {
d3.select("#infobox").transition().duration(1E3).style({
display: "block",
left: "0%"
});
});
d3.select("#infobox .close").on("mousedown", function() {
d3.select("#infobox").transition().duration(1E3).style({
left: "100%"
});
});
d3.select("#svg-zoom-in").on("mousedown", function() {
map.zoomIn();
});
d3.select("#svg-zoom-out").on("mousedown", function() {
map.zoomOut();
});
d3.select("#svg-toggle-play").on("mousedown", function() {
if (ipv.stream.paused) {
ipv.stream.play();
} else {
ipv.stream.pause();
}
var status = ipv.stream.paused;
d3.select(this.parentNode).select("text").style("font-size", status ? "12px" : "12px").html(status ? "&#9654;" : "&#9616;");
});
/** @type {boolean} */
var perm = false;
d3.select(".minimize-button").on("mousedown.toggle", function() {
if (perm) {
node.setAttribute("transform", "translate(" + [o.center.x, o.center.y] + ")");
frag.appendChild(node);
} else {
node.setAttribute("transform", "translate(40, 40)");
docFrag.appendChild(node);
}
/** @type {boolean} */
perm = !perm;
});
}
if (delegate) {
throw delegate;
}
if (_dotCanvas = dotCanvas, nmap_services.forEach(function(s) {
/** @type {number} */
s.count = 0;
/** @type {number} */
s.port = +s.port;
/** @type {string} */
s.type = "service";
/** @type {string} */
s.color = "hsl(" + +s.port % 360 + ", 100%, 70%)";
/** @type {string} */
console.log(s.port, s.service, s.color);
s.display = '<span style="color: ' + s.color + '">&bigcirc;</span> ' + s.service;
self.insert(s);
}), result = country_codes, draw(json_config.map), !args.embed) {
if (o = ipv.ui().layout(layout), ifn = d3.select("body").append("div").attr("id", "ui").call(o), document.getElementById("ui").appendChild(document.getElementById("infobox")), isInline) {
var cb = d3.select(document.getElementById("chevronHiddenDiv")).select("g").node();
init(cb);
} else {
d3.select("#controls #logo").attr("src", json_config.ui.logo);
d3.xml("assets/chevron.svg", "image/svg+xml", function(data) {
var cb = d3.select(data.documentElement).select("g").node();
init(cb);
});
}
}
copied = ipv.stream.socket(json_config.stream, update);
}
/**
* @param {Element} params
* @return {undefined}
*/
function draw(params) {
/**
* @return {undefined}
*/
function drawLine() {
transition();
t = map.getZoom();
}
/**
* 更新页面内容
* @return {undefined}
*/
function update() {
var codeSegments = store.data;
/** @type {number} */
var i = 0;
for (; i < codeSegments.length; i++) {
var o = codeSegments[i];
var p = map.latLngToContainerPoint(o.latLng);
newLayerPos = map.latLngToLayerPoint(o.latLng);
o.cx = p.x;
o.cy = p.y;
o.lx = newLayerPos.x;
o.ly = newLayerPos.y;
}
/** @type {Array} */
var minPage = [2, map.getScaleZoom(map.getZoom()) * map.getZoom() + 2];
["source", "target", "service"].forEach(function(target) {
event[target].range(minPage);
});
that.redraw();
if (!y) {
chart.selectAll(".animating").style("visibility", "hidden").interrupt().transition().remove();
}
/** @type {boolean} */
y = false;
}
var vudata = {
tiles: {
toner: "http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png",
watercolor: "http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg",
mars: "https://{s}.tiles.mapbox.com/v3/herwig.map-tly29w1z/{z}/{x}/{y}.png",
dm: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
positron: "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png"
}
};
params.tileUrl = args.tiles ? vudata.tiles[args.tiles] : params.tileUrl ? params.tileUrl : null;
if (data) {
map = ipv.map(params);
L.geoJson(topojson.feature(data, data.objects.countries).features, {
style: {
fillColor: "#000",
weight: 1,
color: "#4bffff"
}
}).addTo(map);
} else {
map = ipv.map(params);
map.addLayer(params.tileUrl ? new L.TileLayer(params.tileUrl, {
noWrap: true
}) : new L.TileLayer("norse-basemap-v1_1/{z}/{x}/{y}.png", {
noWrap: true
}));
}
/**
* @param {?} rows
* @param {Object} context
* @return {undefined}
*/
render = function(rows, context) {
var ctx = context.context;
ctx.clearRect(0, 0, context.canvas.width, context.canvas.height);
/** @type {number} */
ctx.globalAlpha = 0.5;
/** @type {string} */
ctx.globalCompositeOperation = "lighter";
[me.data(), row.data()].forEach(function(ca, isToday) {
/** @type {string} */
ctx.fillStyle = isToday ? "white" : "hsl(0, 100%, 70%)";
ctx.beginPath();
/** @type {number} */
var i = 0;
var l = ca.length;
for (; l > i; i++) {
var c = ca[i];
if (context.bounds.contains(c.latLng)) {
/** @type {number} */
var x = 0 | c.cx;
/** @type {number} */
var y = 0 | c.cy;
ctx.moveTo(x, y);
ctx.arc(x, y, c.displayRadius = event[c.type](c.count) / 16, 0, TWO_PI);
}
}
ctx.fill();
ctx.closePath();
});
currentSet = d3.geom.quadtree().x(ipv_helpers.return_cx).y(ipv_helpers.return_cy)(store.data.slice());
};
that = L.canvasOverlay().drawing(render).addTo(map);
d3.select(that._canvas).classed("anchor-layer", true);
/** @type {Element} */
var canvas = document.createElement("canvas");
var _ctx = canvas.getContext("2d");
/** @type {number} */
canvas.width = canvas.height = 16;
/**
* @return {undefined}
*/
showbuffer.showbuffer = function() {
window.open(canvas.toDataURL("image/jpeg", 1));
};
state = L.canvasOverlay().drawing(function(dataAndEvents, jaws) {
jaws.context.clearRect(0, 0, jaws.canvas.width, jaws.canvas.height);
}).addTo(map);
var context = state._context;
/** @type {string} */
context.globalCompositeOperation = "lighter";
/** @type {number} */
var tileSize = 24;
/** @type {number} */
var container_border_width = tileSize / 2;
/** @type {null} */
var lastColor = null;
/**
* @return {undefined}
*/
clear = function() {
if (_dotCanvas) {
var color = this.color;
if (color !== lastColor) {
_ctx.clearRect(0, 0, tileSize, tileSize);
_ctx.save();
_ctx.drawImage(_dotCanvas, 0, 0, tileSize, tileSize);
_ctx.fillStyle = color;
/** @type {string} */
_ctx.globalCompositeOperation = "source-atop";
_ctx.fillRect(0, 0, tileSize, tileSize);
_ctx.restore();
lastColor = color;
}
var box = this.destination;
var height = box.displayRadius;
/** @type {number} */
var scrollTop = 2 * (Math.random() - 0.5) * height - container_border_width;
/** @type {number} */
var scrollLeft = 2 * (Math.random() - 0.5) * height - container_border_width;
context.drawImage(canvas, box.cx + scrollTop | 0, box.cy + scrollLeft | 0);
if (Math.random() > 0.7) {
/** @type {string} */
context.globalCompositeOperation = "destination-out";
/** @type {string} */
context.fillStyle = "rgba(255, 255, 255, 0.1)";
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
/** @type {string} */
context.globalCompositeOperation = "lighter";
}
}
};
start(that._canvas);
svgLayer = new SVGOverlay(params.options);
map.addLayer(svgLayer);
chart = svgLayer.el;
/** @type {boolean} */
var y = true;
map.on("viewreset", update);
update();
map.on("zoomstart", drawLine);
map.on("moveend", update);
}
/**
* @return {undefined}
*/
function start() {
var row = {
key: false
};
document.getElementById("map").addEventListener("mousemove", function(touch) {
var self;
/** @type {number} */
var x = touch.pageX;
/** @type {number} */
var y = touch.pageY;
if (currentSet.visit(function(t, minlength, y3, maxX, maxY) {
if (self) {
return true;
}
if (x >= minlength && (maxX >= x && (y >= y3 && maxY >= y))) {
var p = t.point;
if (p) {
/** @type {number} */
var z0 = x - p.cx;
/** @type {number} */
var z1 = y - p.cy;
/** @type {number} */
var R = Math.sqrt(z0 * z0 + z1 * z1);
if (R <= p.r) {
return self = p, true;
}
}
}
}), self && self.key !== row.key) {
var params = {};
/** @type {string} */
var key = self.type + "Key";
params[key] = self.key;
enter(init(params));
} else {
transition();
}
});
}
/**
* 更新网页
* @param {Object} params
* @return {undefined}
*/
function update(params) {
if(!!ipv.stream.paused) return;
if (params = JSON.parse(params.data), "O1" !== params.source.country && "O1" !== params.destination.country2) {
console.log(params);
var data = {
source: {
key: (lat = params.source.latitude) + "_" + (lng = params.source.longitude),
latLng: [+lat, +lng],
country: params.cn,
// TODO: CITY
locString: (params.cn ? params.cn + ", " : "") + params.cn
},
target: {
key: (lat = params.destination.latitude) + "_" + (lng = params.destination.longitude),
latLng: [+lat, +lng],
country: params.destination.country,
locString: (params.destination.city ? params.destination.city + ", " : "") + params.destination.country
}
};
console.log(data)
/** @type {number} */
var _port = 21;
/** @type {string} */
var lc = "hsl(" + +_port % 360 + ", 100%, 70%)";
var values = self.findOne({
port: _port
}) || self.insert({
type: "service",
port: _port,
color: lc,
service: "unknown",
count: 0,
display: '<span style="color: ' + lc + '">&bigcirc;</span> unknown'
});
++values.count;
self.update(values);
["target", "source"].forEach(function(i, dataAndEvents) {
var node;
var event = data[i];
if (!(node = store.findOne({
key: event.key,
type: i
}))) {
var pt = map.latLngToContainerPoint(event.latLng);
var coords = map.latLngToLayerPoint(event.latLng);
node = store.insert({
key: event.key,
cx: pt.x,
cy: pt.y,
lx: coords.x,
ly: coords.y,
latLng: event.latLng,
location: event.locString,
country: event.country,
type: i,
count: 0,
r: 20
});
/** @type {Array} */
v[params.key + params.type] = [];
}
data[i].document = node;
++node.count;
var results;
var country = event.country;
if (!(results = query.findOne({
$and: [{
type: i
}, {
country: country
}]
}))) {
/** @type {string} */
var type = "<";
type += 'img class="flag" src="img/flags/' + country + '.png"> ' + result[country];
if (isInline) {
type = result[country];
}
results = query.insert({
type: i,
country: country,
countryName: result[country],
display: type,
count: 0
});
}
++results.count;
node.countryObj = results;
query.update(results);
});
var bounds = data.source.document;
var i = data.target.document;
var created = moment().format("DD.MM.YYYY HH:mm:ss");
var event = {
timestamp: created,
org: params.org,
ip: params.md5,
source: data.source.locString,
target: data.target.locString,
sourceKey: data.source.key,
targetKey: data.target.key,
sourceCountry: params.country,
targetCountry: params.country2,
sourceObj: bounds,
targetObj: i,
serviceObj: values,
service: values,
type: "events"
};
col.insert(event);
/** @type {({x: number, y: number})} */
var pos = params.zerg ? {
x: 20 * (Math.random() - 0.5),
y: 20 * (Math.random() - 0.5)
} : {
x: 0,
y: 0
};
chart.append("circle").classed("animating", true).attr({
cx: bounds.lx + pos.x,
cy: bounds.ly + pos.y,
fill: "none",
stroke: values.color,
"stroke-width": 5,
r: 1E-6
}).style({
opacity: 1
}).transition().duration(4E3).ease("cubic-out").style("opacity", 1E-6).attr("r", 80).remove();
/** @type {Array} */
var net = (new Mover({
zerg: params.zerg,
created: created,
x: bounds.lx,
y: bounds.ly,
destination: i,
dk: i.key,
targetIdx: i.$loki,
latLng: bounds.latLng,
lastLatLng: bounds.latLng,
fixed: false,
port: _port,
offset: pos,
onMoverHit: clear
}, svgLayer), [{
type: "source",
data: service.data().slice(0, 10)
}, {
type: "service",
data: socket.data().slice(0, 10)
}, {
type: "target",
data: options.data().slice(0, 10)
}]);
if (!params.zerg) {
if (load(net)) {
that.redraw();
}
}
if (!args.embed) {
net.push({
type: "events",
data: col.data.slice(-10)
});
o.update({
datatables: net,
clock: col.data.slice()
});
}
}
}
var showbuffer = {};
var args = ipv.hash.parse();
if (args.pew) {
d3.select("body").append("audio").attr({
src: "assets/pew.mp3",
preload: "auto"
}).text("");
document.getElementsByTagName("audio")[0];
}
var copied;
var map;
var chart;
var data;
var that;
var render;
var state;
var clear;
var t;
var currentSet;
var v = {};
var event = {
counts: {
source: 0,
target: 0,
service: 0
},
source: d3.scale.sqrt().domain([0, 1]).range([2, 16]),
target: d3.scale.sqrt().domain([0, 1]).range([2, 16]),
service: d3.scale.sqrt().domain([0, 1]).range([2, 16])
};
var $ = new loki("attacks");
var col = $.addCollection("timeline", {
indices: ["source", "target", "service"]
});
var store = $.addCollection("anchors", {
indices: ["key", "country"]
});
var self = $.addCollection("services", {
indices: ["port"]
});
var query = $.addCollection("countries", {
indices: ["country", "type"]
});
var service = query.addDynamicView("source_countries");
service.applyFind({
type: "source"
});
service.applySort(ipv_helpers.sort_descCountAscCountry);
var options = query.addDynamicView("target_countries");
options.applyFind({
type: "target"
});
options.applySort(ipv_helpers.sort_descCountAscCountry);
var socket = self.addDynamicView("sorted_services");
socket.applyFind({
count: {
$gt: 0
}
});
socket.applySort(ipv_helpers.sort_descCountAscService);
var me = store.addDynamicView("anchor_sources");
me.applyFind({
type: "source"
});
me.applySimpleSort("count", true);
var row = store.addDynamicView("anchor_targets");
row.applyFind({
type: "target"
});
row.applySimpleSort("count", true);
/** @type {number} */
var backoff = 48E4;
setTimeout(function() {
setInterval(function() {
ping(backoff);
}, 6E4);
}, backoff);
var result;
var o;
var ifn;
var _dotCanvas;
d3.select("#preload");
// 判断是否页面内联设置
if (isInline) {
document.getElementById("particleHiddenDiv").innerHTML += '<img src="assets/particle-inverse.png" id="particleHidden" style="visibility:hidden">';
show(false, json_config, nmap_services_1500, country_codes, json_layout, document.getElementById("particleHidden"));
} else {
queue().defer(d3.json, "config.json").defer(d3.csv, "data/nmap-services-1500.csv").defer(d3.json, "data/country_codes.json").defer(d3.json, "layout.json").defer(function(path, pCallback) {
/** @type {Image} */
var image = new Image(0, 0);
image.onload = function() {
pCallback(null, this);
};
image.onerror = function() {
pCallback("error loading particle image");
};
image.src = path;
}, "assets/particle-inverse.png").await(show);
}
}();