diff --git a/Gruntfile.js b/Gruntfile.js index ecfa6f9..1552a92 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -37,23 +37,20 @@ var src_lite = 'src-lite/'; var dest_lite = 'dist-lite/'; var scripts_lite = [ - 'scr-lite/js/app.js', - 'scr-lite/js/controllers.js', - 'scr-lite/js/filters.js', - 'scr-lite/js/directives.js', - 'scr-lite/js/script.js' + 'src-lite/js/app.js', + 'src-lite/js/controllers.js', + 'src-lite/js/filters.js', + 'src-lite/js/directives.js', + 'src-lite/js/script.js' ]; var vendor_lite = [ 'dist-lite/js/lib/jquery-1.11.3.min.js', 'dist-lite/js/lib/bootstrap.min.js', 'dist-lite/js/lib/angular.min.js', - 'dist-lite/js/lib/ngStorage.min.js', 'dist-lite/js/lib/lodash.min.js', 'dist-lite/js/lib/d3.min.js', 'dist-lite/js/lib/d3.tip.min.js', - 'dist-lite/js/lib/topojson.min.js', - 'dist-lite/js/lib/datamaps.min.js', 'dist-lite/js/lib/moment.min.js', 'dist-lite/js/lib/moment.en.min.js', 'dist-lite/js/lib/toastr.min.js', diff --git a/lib/express.js b/lib/express.js index d8feedf..bd37f5f 100644 --- a/lib/express.js +++ b/lib/express.js @@ -4,14 +4,14 @@ var path = require('path'); var bodyParser = require('body-parser'); // view engine setup -app.set('views', path.join(__dirname, '../src/views')); +app.set('views', path.join(__dirname, (process.env.LITE === 'true' ? '../src-lite/views' : '../src/views'))); app.set('view engine', 'jade'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); -app.use(express.static(path.join(__dirname, '../dist'))); +app.use(express.static(path.join(__dirname, (process.env.LITE === 'true' ? '../dist-lite' : '../dist')))); app.get('/', function(req, res) { - res.render((process.env.LITE === true ? 'index-lite' : 'index')); + res.render('index'); }); // catch 404 and forward to error handler diff --git a/lib/history.js b/lib/history.js index 621a8bc..0975634 100644 --- a/lib/history.js +++ b/lib/history.js @@ -23,7 +23,7 @@ History.prototype.add = function(block, id, trusted, addingHistory) if( !_.isUndefined(block) && !_.isUndefined(block.number) && !_.isUndefined(block.uncles) && !_.isUndefined(block.transactions) && !_.isUndefined(block.difficulty) && block.number > 0 ) { - trusted = (process.env.LITE === true ? true : trusted); + trusted = (process.env.LITE === 'true' ? true : trusted); var historyBlock = this.search(block.number); var forkIndex = -1; diff --git a/lib/node.js b/lib/node.js index c412124..46a09e5 100644 --- a/lib/node.js +++ b/lib/node.js @@ -81,7 +81,7 @@ Node.prototype.setInfo = function(data, callback) if( !_.isUndefined(data.ip) ) { - if( trusted.indexOf(data.ip) >= 0 || process.env.LITE === true) + if( trusted.indexOf(data.ip) >= 0 || process.env.LITE === 'true') { this.trusted = true; } diff --git a/src-lite/js/app.js b/src-lite/js/app.js index 74fcb3b..a4b7769 100644 --- a/src-lite/js/app.js +++ b/src-lite/js/app.js @@ -2,7 +2,7 @@ /* Init Angular App */ -var netStatsApp = angular.module('netStatsApp', ['netStatsApp.filters', 'netStatsApp.directives', 'ngStorage']); +var netStatsApp = angular.module('netStatsApp', ['netStatsApp.filters', 'netStatsApp.directives']); /* Services */ diff --git a/src-lite/js/controllers.js b/src-lite/js/controllers.js index eb7c4b4..fe6bd93 100644 --- a/src-lite/js/controllers.js +++ b/src-lite/js/controllers.js @@ -1,7 +1,7 @@ /* Controllers */ -netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, socket, _, toastr) { +netStatsApp.controller('StatsCtrl', function($scope, $filter, socket, _, toastr) { var MAX_BINS = 40; @@ -37,9 +37,9 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc $scope.currentApiVersion = "0.0.16"; - $scope.predicate = $localStorage.predicate || ['-pinned', '-stats.active', '-stats.block.number', 'stats.block.propagation']; - $scope.reverse = $localStorage.reverse || false; - $scope.pinned = $localStorage.pinned || []; + $scope.predicate = ['-pinned', '-stats.active', '-stats.block.number', 'stats.block.propagation']; + $scope.reverse = false; + $scope.pinned = []; $scope.prefixPredicate = ['-pinned', '-stats.active']; $scope.originalPredicate = ['-stats.block.number', 'stats.block.propagation']; @@ -64,9 +64,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc $scope.predicate = _.union($scope.prefixPredicate, predicate); } - - $localStorage.predicate = $scope.predicate; - $localStorage.reverse = $scope.reverse; } $scope.pinNode = function(id) @@ -86,8 +83,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc $scope.pinned.splice($scope.pinned.indexOf(id), 1); } } - - $localStorage.pinned = $scope.pinned; } var timeout = setInterval(function () @@ -329,14 +324,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc if( !_.isEqual($scope.lastBlocksTime, data.blocktime) && data.blocktime.length >= MAX_BINS ) $scope.lastBlocksTime = data.blocktime; - if( !_.isEqual($scope.difficultyChart, data.difficulty) && data.difficulty.length >= MAX_BINS ) - $scope.difficultyChart = data.difficulty; - - if( !_.isEqual($scope.blockPropagationChart, data.propagation.histogram) ) { - $scope.blockPropagationChart = data.propagation.histogram; - $scope.blockPropagationAvg = data.propagation.avg; - } - data.uncleCount.reverse(); if( !_.isEqual($scope.uncleCountChart, data.uncleCount) && data.uncleCount.length >= MAX_BINS ) { @@ -344,17 +331,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc $scope.uncleCountChart = data.uncleCount; } - if( !_.isEqual($scope.transactionDensity, data.transactions) && data.transactions.length >= MAX_BINS ) - $scope.transactionDensity = data.transactions; - - if( !_.isEqual($scope.gasSpending, data.gasSpending) && data.gasSpending.length >= MAX_BINS ) - $scope.gasSpending = data.gasSpending; - - if( !_.isEqual($scope.miners, data.miners) ) { - $scope.miners = data.miners; - getMinersNames(); - } - break; case "inactive": @@ -399,8 +375,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc break; } - - // $scope.$apply(); } function findIndex(search) @@ -408,26 +382,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc return _.findIndex($scope.nodes, search); } - function getMinersNames() - { - if( $scope.miners.length > 0 ) - { - _.forIn($scope.miners, function (value, key) - { - if(value.name !== false) - return; - - if(value.miner === "0x0000000000000000000000000000000000000000") - return; - - var name = _.result(_.find(_.pluck($scope.nodes, 'info'), 'coinbase', value.miner), 'name'); - - if( !_.isUndefined(name) ) - $scope.miners[key].name = name; - }); - } - } - function addNewNode(data) { var index = findIndex({id: data.id}); @@ -476,30 +430,6 @@ netStatsApp.controller('StatsCtrl', function($scope, $filter, $localStorage, soc forkFilter(node); return node.stats.active == true; }).length; - - $scope.upTimeTotal = _.reduce($scope.nodes, function (total, node) { - return total + node.stats.uptime; - }, 0) / $scope.nodes.length; - - $scope.map = _.map($scope.nodes, function (node) { - var fill = $filter('bubbleClass')(node.stats, $scope.bestBlock); - - if(node.geo != null) - return { - radius: 3, - latitude: node.geo.ll[0], - longitude: node.geo.ll[1], - nodeName: node.info.name, - fillClass: "text-" + fill, - fillKey: fill, - }; - else - return { - radius: 0, - latitude: 0, - longitude: 0 - }; - }); } function updateBestBlock() diff --git a/src-lite/js/directives.js b/src-lite/js/directives.js index 6ef7632..c178f36 100644 --- a/src-lite/js/directives.js +++ b/src-lite/js/directives.js @@ -1,4 +1,3 @@ - /* Directives */ angular.module('netStatsApp.directives', []) @@ -6,417 +5,4 @@ angular.module('netStatsApp.directives', []) return function(scope, elm, attrs) { elm.text(version); }; -}]) -// .directive('timeAgo', ['$interval', function($interval) { -// function link (scope, element, attrs) -// { -// var timestamp, -// timeoutId; - -// function updateTime() { -// element.text(timeAgo()) -// } - -// function timeAgo() -// { -// if(timestamp === 0) -// return '∞'; - -// var time = (new Date()).getTime(); -// var diff = Math.floor((time - timestamp)/1000); - -// if(diff < 60) -// return Math.round(diff) + ' s ago'; - -// return moment.duration(Math.round(diff), 's').humanize() + ' ago'; -// }; - -// scope.$watch(attrs.timeAgo, function(value) { -// timestamp = value; -// updateTime(); -// }); - -// element.on('$destroy', function() { -// $interval.cancel(timeoutId); -// }); - -// timeoutId = $interval(function () { -// updateTime(); -// }, 200); -// }; - -// return { -// link: link -// }; -// }]) - - .directive('minerblock', function ($compile) { - return { - restrict: 'E', - template: '
', - replace: true, - link: function (scope, element, attrs) - { - var makeClass = function (value) - { - if(value <= 6) - return 'success'; - - if(value <= 12) - return 'info'; - - if(value <= 18) - return 'warning'; - - if(value <= 24) - return 'orange'; - - return 'danger'; - } - - attrs.$observe("blocks", function (newValue) - { - var content = ''; - var blockClass = 'bg-' + makeClass(newValue); - - for(var i = 0; i < newValue; i++) - { - content += '
'; - } - - element.empty(); - element.html(content); - }); - } - }; -}) - .directive('sparkchart', function () { - return { - restrict: 'E', - scope: { - data: '@' - }, - compile: function (tElement, tAttrs, transclude) - { - tElement.replaceWith('' + tAttrs.data + ""); - - return function(scope, element, attrs) - { - attrs.$observe("data", function (newValue) - { - element.html(newValue); - element.addClass("big-details"); - element.sparkline('html', { - type: 'bar', - tooltipSuffix: (attrs.tooltipsuffix || '') - }); - }); - }; - } - }; -}) - .directive('nodepropagchart', function() { - return { - restrict: 'E', - scope: { - data: '@' - }, - compile: function (tElement, tAttrs, transclude) - { - tElement.replaceWith('' + tAttrs.data + ""); - - function formatTime (ms) { - var result = 0; - - if(ms < 1000) { - return ms + " ms"; - } - - if(ms < 1000*60) { - result = ms/1000; - return result.toFixed(1) + " s"; - } - - if(ms < 1000*60*60) { - result = ms/1000/60; - return Math.round(result) + " min"; - } - - if(ms < 1000*60*60*24) { - result = ms/1000/60/60; - return Math.round(result) + " h"; - } - - result = ms/1000/60/60/24; - return Math.round(result) + " days"; - }; - - return function(scope, element, attrs) - { - attrs.$observe("data", function (newValue) - { - element.html(newValue); - element.sparkline('html', { - type: 'bar', - negBarColor: '#7f7f7f', - zeroAxis: false, - height: 20, - barWidth : 2, - barSpacing : 1, - tooltipSuffix: '', - chartRangeMax: 8000, - colorMap: jQuery.range_map({ - '0:1': '#10a0de', - '1:1000': '#7bcc3a', - '1001:3000': '#FFD162', - '3001:7000': '#ff8a00', - '7001:': '#F74B4B' - }), - tooltipFormatter: function (spark, opt, ms) { - var tooltip = '
'; - tooltip += formatTime(ms[0].value); - tooltip += '
'; - - return tooltip; - } - }); - }); - }; - } - }; -}) - .directive('nodemap', ['$compile', function($compile) { - return { - restrict: 'EA', - scope: { - data: '=' - }, - link: function(scope, element, attrs) { - var bubbleConfig = { - borderWidth: 0, - highlightOnHover: false, - popupOnHover: true, - popupTemplate: function(geo, data) { - return ['
', - '
', - '
', - '', - data.nodeName, - '', - '
'].join(''); - } - }; - - scope.init = function() { - element.empty(); - - var width = 628, - height = 244; - - scope.map = new Datamap({ - element: element[0], - scope: 'world', - width: width, - height: 300, - fills: { - success: '#7BCC3A', - info: '#10A0DE', - warning: '#FFD162', - orange: '#FF8A00', - danger: '#F74B4B', - defaultFill: '#282828' - }, - geographyConfig: { - borderWidth: 0, - borderColor: '#000', - highlightOnHover: false, - popupOnHover: false - }, - bubblesConfig: { - borderWidth: 0, - highlightOnHover: false, - popupOnHover: true - }, - done: function(datamap) { - var ev; - - var zoomListener = d3.behavior.zoom() - .size([width, height]) - .scaleExtent([1, 3]) - .on("zoom", redraw) - .on("zoomend", animadraw); - - function redraw() { - datamap.svg.select(".datamaps-subunits").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); - datamap.svg.select(".bubbles").selectAll("circle") - .attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")") - .attr("r", 3/d3.event.scale); - - ev = d3.event; - } - - zoomListener(datamap.svg); - - function animadraw() { - var x = Math.min(0, Math.max(ev.translate[0], (-1) * width * (ev.scale-1))); - var y = Math.min(0, Math.max(ev.translate[1], (-1) * height * (ev.scale-1))); - - datamap.svg.select(".datamaps-subunits") - .transition() - .delay(150) - .duration(750) - .attr("transform", "translate(" + x + "," + y + ")scale(" + ev.scale + ")"); - - datamap.svg.select(".bubbles").selectAll("circle") - .transition() - .delay(150) - .duration(750) - .attr("transform", "translate(" + x + "," + y + ")scale(" + ev.scale + ")") - .attr("r", 3/ev.scale); - - zoomListener.translate([x,y]); - } - } - }); - - scope.map.bubbles(scope.data, bubbleConfig); - } - - scope.init(); - - scope.$watch('data', function() { - scope.map.bubbles(scope.data, bubbleConfig); - }, true); - } - }; -}]) - .directive('histogram', ['$compile', function($compile) { - return { - restrict: 'EA', - scope: { - data: '=' - }, - link: function(scope, element, attrs) - { - var margin = {top: 0, right: 0, bottom: 0, left: 0}; - var width = 280 - margin.left - margin.right, - height = 63 - margin.top - margin.bottom; - - var TICKS = 40; - - var x = d3.scale.linear() - .domain([0, 10000]) - .rangeRound([0, width]) - .interpolate(d3.interpolateRound); - - var y = d3.scale.linear() - .range([height, 0]) - .interpolate(d3.interpolateRound); - - var color = d3.scale.linear() - .domain([1000, 3000, 7000, 10000]) - .range(["#7bcc3a", "#FFD162", "#ff8a00", "#F74B4B"]); - - var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom") - .ticks(4, ",.1s") - .tickFormat(function(t){ return t/1000 + "s"}); - - var yAxis = d3.svg.axis() - .scale(y) - .orient("left") - .ticks(3) - .tickFormat(d3.format("%")); - - var line = d3.svg.line() - .x(function(d) { return x(d.x + d.dx/2) - 1; }) - .y(function(d) { return y(d.y) - 2; }) - .interpolate('basis'); - - var tip = d3.tip() - .attr('class', 'd3-tip') - .offset([10, 0]) - .direction('s') - .html(function(d) { - return '
' + (d.x/1000) + 's - ' + ((d.x + d.dx)/1000) + 's
Percent: ' + Math.round(d.y * 100) + '%' + '
Frequency: ' + d.frequency + '
Cumulative: ' + Math.round(d.cumpercent*100) + '%
'; - }) - - scope.init = function() - { - var data = scope.data; - - // Adjust y axis - y.domain([0, d3.max(data, function(d) { return d.y; })]); - - // Delete previous histogram - element.empty(); - - /* Start drawing */ - var svg = d3.select(".d3-blockpropagation").append("svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - svg.call(tip); - - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") - .call(xAxis) - .selectAll("text") - .attr("y", 6); - - svg.append("g") - .attr("class", "y axis") - .attr("transform", "translate(" + width + ", 0)") - .call(yAxis); - - - var bar = svg.append("g") - .attr("class", "bars") - .selectAll("g") - .data(data) - .enter().append("g") - .attr("transform", function(d) { return "translate(" + x(d.x) + ",0)"; }) - .on('mouseover', function(d) { tip.show(d, d3.select(this).select('.bar').node()); }) - .on('mouseout', tip.hide); - - bar.insert("rect") - .attr("class", "handle") - .attr("y", 0) - .attr("width", x(data[0].dx + data[0].x) - x(data[0].x)) - .attr("height", function(d) { return height; }); - - bar.insert("rect") - .attr("class", "bar") - .attr("y", function(d) { return y(d.y); }) - .attr("rx", 1) - .attr("ry", 1) - .attr("fill", function(d) { return color(d.x); }) - .attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1) - .attr("height", function(d) { return height - y(d.y) + 1; }); - - bar.insert("rect") - .attr("class", "highlight") - .attr("y", function(d) { return y(d.y); }) - .attr("fill", function(d) { return d3.rgb(color(d.x)).brighter(.7).toString(); }) - .attr("rx", 1) - .attr("ry", 1) - .attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1) - .attr("height", function(d) { return height - y(d.y) + 1; }); - - svg.append("path") - .attr("class", "line") - .attr("d", line(data)); - } - - scope.$watch('data', function() { - if(scope.data.length > 0) { - scope.init(); - } - }, true); - } - }; - }]); \ No newline at end of file +}]); \ No newline at end of file diff --git a/src-lite/js/filters.js b/src-lite/js/filters.js index 08e00b6..8541882 100644 --- a/src-lite/js/filters.js +++ b/src-lite/js/filters.js @@ -36,27 +36,6 @@ angular.module('netStatsApp.filters', []) return peerClass(peers, active); }; }) -.filter('miningClass', function() { - return function(mining, active) { - if(! active) - return 'text-gray'; - - return (! mining ? 'text-danger' : 'text-success'); - }; -}) -.filter('miningIconClass', function() { - return function(mining) { - return (! mining ? 'icon-cancel' : 'icon-check'); - }; -}) -.filter('hashrateClass', function() { - return function(mining, active) { - if(! mining || ! active) - return 'text-gray'; - - return 'text-success'; - }; -}) .filter('hashrateFilter', ['$sce', '$filter', function($sce, filter) { return function(hashes, isMining) { var result = 0; @@ -544,7 +523,7 @@ angular.module('netStatsApp.filters', []) .filter('consensusClass', function() { return function(nodes, bestBlock) { var status = 'success'; - var now = _.now(); + var now = (new Date()).getTime(); for(var x = 0; x < nodes.length; x++) { diff --git a/src-lite/js/lib/datamaps.min.js b/src-lite/js/lib/datamaps.min.js deleted file mode 100644 index 8b5d932..0000000 --- a/src-lite/js/lib/datamaps.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(){function a(a,b,c){return this.svg=m.select(a).append("svg").attr("width",c||a.offsetWidth).attr("data-width",c||a.offsetWidth).attr("class","datamap").attr("height",b||a.offsetHeight).style("overflow","hidden"),this.options.responsive&&(m.select(this.options.element).style({position:"relative","padding-bottom":"60%"}),m.select(this.options.element).select("svg").style({position:"absolute",width:"100%",height:"100%"}),m.select(this.options.element).select("svg").select("g").selectAll("path").style("vector-effect","non-scaling-stroke")),this.svg}function b(a,b){var c,d,e=b.width||a.offsetWidth,f=b.height||a.offsetHeight,g=this.svg;return b&&"undefined"==typeof b.scope&&(b.scope="world"),"usa"===b.scope?c=m.geo.albersUsa().scale(e).translate([e/2,f/2]):"world"===b.scope&&(c=m.geo[b.projection]().scale((e+1)/2/Math.PI).translate([e/2,f/("mercator"===b.projection?1.45:1.8)])),"orthographic"===b.projection&&(g.append("defs").append("path").datum({type:"Sphere"}).attr("id","sphere").attr("d",d),g.append("use").attr("class","stroke").attr("xlink:href","#sphere"),g.append("use").attr("class","fill").attr("xlink:href","#sphere"),c.scale(250).clipAngle(90).rotate(b.projectionConfig.rotation)),d=m.geo.path().projection(c),{path:d,projection:c}}function c(){m.select(".datamaps-style-block").empty()&&m.select("head").append("style").attr("class","datamaps-style-block").html('.datamap path.datamaps-graticule { fill: none; stroke: #777; stroke-width: 0.5px; stroke-opacity: .5; pointer-events: none; } .datamap .labels {pointer-events: none;} .datamap path {stroke: #FFFFFF; stroke-width: 1px;} .datamaps-legend dt, .datamaps-legend dd { float: left; margin: 0 3px 0 0;} .datamaps-legend dd {width: 20px; margin-right: 6px; border-radius: 3px;} .datamaps-legend {padding-bottom: 20px; z-index: 1001; position: absolute; left: 4px; font-size: 12px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;} .datamaps-hoverover {display: none; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .hoverinfo {padding: 4px; border-radius: 1px; background-color: #FFF; box-shadow: 1px 1px 5px #CCC; font-size: 12px; border: 1px solid #CCC; } .hoverinfo hr {border:1px dotted #CCC; }')}function d(a){var b=this.options.fills,c=this.options.data||{},d=this.options.geographyConfig,e=this.svg.select("g.datamaps-subunits");e.empty()&&(e=this.addLayer("datamaps-subunits",null,!0));var f=n.feature(a,a.objects[this.options.scope]).features;d.hideAntarctica&&(f=f.filter(function(a){return"ATA"!==a.id}));var g=e.selectAll("path.datamaps-subunit").data(f);g.enter().append("path").attr("d",this.path).attr("class",function(a){return"datamaps-subunit "+a.id}).attr("data-info",function(a){return JSON.stringify(c[a.id])}).style("fill",function(a){var d;return c[a.id]&&(d=b[c[a.id].fillKey]),d||b.defaultFill}).style("stroke-width",d.borderWidth).style("stroke",d.borderColor)}function e(){function a(){this.parentNode.appendChild(this)}var b=this.svg,c=this,d=this.options.geographyConfig;(d.highlightOnHover||d.popupOnHover)&&b.selectAll(".datamaps-subunit").on("mouseover",function(e){var f=m.select(this);if(d.highlightOnHover){var g={fill:f.style("fill"),stroke:f.style("stroke"),"stroke-width":f.style("stroke-width"),"fill-opacity":f.style("fill-opacity")};f.style("fill",d.highlightFillColor).style("stroke",d.highlightBorderColor).style("stroke-width",d.highlightBorderWidth).style("fill-opacity",d.highlightFillOpacity).attr("data-previousAttributes",JSON.stringify(g)),/((MSIE)|(Trident))/.test||a.call(this)}d.popupOnHover&&c.updatePopup(f,e,d,b)}).on("mouseout",function(){var a=m.select(this);if(d.highlightOnHover){var b=JSON.parse(a.attr("data-previousAttributes"));for(var c in b)a.style(c,b[c])}a.on("mousemove",null),m.selectAll(".datamaps-hoverover").style("display","none")})}function f(a,b){if(b=b||{},this.options.fills){var c="
",d="";b.legendTitle&&(c="

"+b.legendTitle+"

"+c);for(var e in this.options.fills){if("defaultFill"===e){if(!b.defaultFillName)continue;d=b.defaultFillName}else d=b.labels&&b.labels[e]?b.labels[e]:e+": ";c+="
"+d+"
",c+='
 
'}c+="
",m.select(this.options.element).append("div").attr("class","datamaps-legend").html(c)}}function g(){var a=m.geo.graticule();this.svg.insert("path",".datamaps-subunits").datum(a).attr("class","datamaps-graticule").attr("d",this.path)}function h(a,b,c){var d=this;if(this.svg,!b||b&&!b.slice)throw"Datamaps Error - arcs must be an array";"undefined"==typeof c&&(c=o.arcConfig);var e=a.selectAll("path.datamaps-arc").data(b,JSON.stringify),f=m.geo.path().projection(d.projection),g=m.geo.greatArc().source(function(a){return[a.origin.longitude,a.origin.latitude]}).target(function(a){return[a.destination.longitude,a.destination.latitude]});e.enter().append("svg:path").attr("class","datamaps-arc").style("stroke-linecap","round").style("stroke",function(a){return a.options&&a.options.strokeColor?a.options.strokeColor:c.strokeColor}).style("fill","none").style("stroke-width",function(a){return a.options&&a.options.strokeWidth?a.options.strokeWidth:c.strokeWidth}).attr("d",function(a){var b=d.latLngToXY(a.origin.latitude,a.origin.longitude),e=d.latLngToXY(a.destination.latitude,a.destination.longitude),h=[(b[0]+e[0])/2,(b[1]+e[1])/2];return c.greatArc?f(g(a)):"M"+b[0]+","+b[1]+"S"+(h[0]+50*c.arcSharpness)+","+(h[1]-75*c.arcSharpness)+","+e[0]+","+e[1]}).transition().delay(100).style("fill",function(){var a=this.getTotalLength();return this.style.transition=this.style.WebkitTransition="none",this.style.strokeDasharray=a+" "+a,this.style.strokeDashoffset=a,this.getBoundingClientRect(),this.style.transition=this.style.WebkitTransition="stroke-dashoffset "+c.animationSpeed+"ms ease-out",this.style.strokeDashoffset="0","none"}),e.exit().transition().style("opacity",0).remove()}function i(a,b){var c=this;b=b||{};var d=this.projection([-67.707617,42.722131]);this.svg.selectAll(".datamaps-subunit").attr("data-foo",function(e){var f=c.path.centroid(e),g=7.5,h=5;["FL","KY","MI"].indexOf(e.id)>-1&&(g=-2.5),"NY"===e.id&&(g=-1),"MI"===e.id&&(h=18),"LA"===e.id&&(g=13);var i,j;i=f[0]-g,j=f[1]+h;var k=["VT","NH","MA","RI","CT","NJ","DE","MD","DC"].indexOf(e.id);if(k>-1){var l=d[1];i=d[0],j=l+k*(2+(b.fontSize||12)),a.append("line").attr("x1",i-3).attr("y1",j-5).attr("x2",f[0]).attr("y2",f[1]).style("stroke",b.labelColor||"#000").style("stroke-width",b.lineWidth||1)}return a.append("text").attr("x",i).attr("y",j).style("font-size",(b.fontSize||10)+"px").style("font-family",b.fontFamily||"Verdana").style("fill",b.labelColor||"#000").text(e.id),"bar"})}function j(a,b,c){function d(a){return"undefined"!=typeof a&&"undefined"!=typeof a.latitude&&"undefined"!=typeof a.longitude}var e=this,f=this.options.fills,g=this.svg;if(!b||b&&!b.slice)throw"Datamaps Error - bubbles must be an array";var h=a.selectAll("circle.datamaps-bubble").data(b,JSON.stringify);h.enter().append("svg:circle").attr("class","datamaps-bubble").attr("cx",function(a){var b;return d(a)?b=e.latLngToXY(a.latitude,a.longitude):a.centered&&(b=e.path.centroid(g.select("path."+a.centered).data()[0])),b?b[0]:void 0}).attr("cy",function(a){var b;return d(a)?b=e.latLngToXY(a.latitude,a.longitude):a.centered&&(b=e.path.centroid(g.select("path."+a.centered).data()[0])),b?b[1]:void 0}).attr("r",0).attr("data-info",function(a){return JSON.stringify(a)}).style("stroke",function(a){return"undefined"!=typeof a.borderColor?a.borderColor:c.borderColor}).style("stroke-width",function(a){return"undefined"!=typeof a.borderWidth?a.borderWidth:c.borderWidth}).style("fill-opacity",function(a){return"undefined"!=typeof a.fillOpacity?a.fillOpacity:c.fillOpacity}).style("fill",function(a){var b=f[a.fillKey];return b||f.defaultFill}).on("mouseover",function(a){var b=m.select(this);if(c.highlightOnHover){var d={fill:b.style("fill"),stroke:b.style("stroke"),"stroke-width":b.style("stroke-width"),"fill-opacity":b.style("fill-opacity")};b.style("fill",c.highlightFillColor).style("stroke",c.highlightBorderColor).style("stroke-width",c.highlightBorderWidth).style("fill-opacity",c.highlightFillOpacity).attr("data-previousAttributes",JSON.stringify(d))}c.popupOnHover&&e.updatePopup(b,a,c,g)}).on("mouseout",function(){var a=m.select(this);if(c.highlightOnHover){var b=JSON.parse(a.attr("data-previousAttributes"));for(var d in b)a.style(d,b[d])}m.selectAll(".datamaps-hoverover").style("display","none")}).transition().duration(400).attr("r",function(a){return a.radius}),h.exit().transition().delay(c.exitDelay).attr("r",0).remove()}function k(a){return Array.prototype.slice.call(arguments,1).forEach(function(b){if(b)for(var c in b)null==a[c]&&(a[c]=b[c])}),a}function l(b){if("undefined"==typeof m||"undefined"==typeof n)throw new Error("Include d3.js (v3.0.3 or greater) and topojson on this page before creating a new map");return this.options=k(b,o),this.options.geographyConfig=k(b.geographyConfig,o.geographyConfig),this.options.projectionConfig=k(b.projectionConfig,o.projectionConfig),this.options.bubblesConfig=k(b.bubblesConfig,o.bubblesConfig),this.options.arcConfig=k(b.arcConfig,o.arcConfig),m.select(this.options.element).select("svg").length>0&&a.call(this,this.options.element,this.options.height,this.options.width),this.addPlugin("bubbles",j),this.addPlugin("legend",f),this.addPlugin("arc",h),this.addPlugin("labels",i),this.addPlugin("graticule",g),this.options.disableDefaultStyles||c(),this.draw()}var m=window.d3,n=window.topojson,o={scope:"world",responsive:!1,setProjection:b,projection:"equirectangular",dataType:"json",done:function(){},fills:{defaultFill:"#ABDDA4"},geographyConfig:{dataUrl:null,hideAntarctica:!0,borderWidth:1,borderColor:"#FDFDFD",popupTemplate:function(a){return'
'+a.properties.name+"
"},popupOnHover:!0,highlightOnHover:!0,highlightFillColor:"#FC8D59",highlightBorderColor:"rgba(250, 15, 160, 0.2)",highlightBorderWidth:2},projectionConfig:{rotation:[97,0]},bubblesConfig:{borderWidth:2,borderColor:"#FFFFFF",popupOnHover:!0,popupTemplate:function(a,b){return'
'+b.name+"
"},fillOpacity:.75,animate:!0,highlightOnHover:!0,highlightFillColor:"#FC8D59",highlightBorderColor:"rgba(250, 15, 160, 0.2)",highlightBorderWidth:2,highlightFillOpacity:.85,exitDelay:100},arcConfig:{strokeColor:"#DD1C77",strokeWidth:1,arcSharpness:1,animationSpeed:600}};l.prototype.resize=function(){var a=this,b=a.options;if(b.responsive){var c="-webkit-transform"in document.body.style?"-webkit-":"-moz-transform"in document.body.style?"-moz-":"-ms-transform"in document.body.style?"-ms-":"",d=b.element.clientWidth,e=m.select(b.element).select("svg").attr("data-width");m.select(b.element).select("svg").selectAll("g").style(c+"transform","scale("+d/e+")")}},l.prototype.draw=function(){function a(a){b.options.dataUrl&&m[b.options.dataType](b.options.dataUrl,function(a){if("csv"===b.options.dataType&&a&&a.slice){for(var c={},d=0;dn;n++)(m=j.key(n))&&"ngStorage-"===m.slice(0,10)&&(k[m.slice(10)]=a.fromJson(j.getItem(m)));return h=a.copy(k),c.$watch(function(){var b;i||(i=f(function(){if(i=null,!a.equals(k,h)){b=a.copy(h),a.forEach(k,function(c,d){a.isDefined(c)&&"$"!==d[0]&&j.setItem("ngStorage-"+d,a.toJson(c)),delete b[d]});for(var c in b)j.removeItem("ngStorage-"+c);h=a.copy(k)}},100,!1))}),"localStorage"===b&&d.addEventListener&&d.addEventListener("storage",function(b){"ngStorage-"===b.key.slice(0,10)&&(b.newValue?k[b.key.slice(10)]=a.fromJson(b.newValue):delete k[b.key.slice(10)],h=a.copy(k),c.$apply())}),k}]}a.module("ngStorage",[]).factory("$localStorage",b("localStorage")).factory("$sessionStorage",b("sessionStorage"))}); \ No newline at end of file diff --git a/src-lite/js/lib/topojson.min.js b/src-lite/js/lib/topojson.min.js deleted file mode 100644 index 865f8d3..0000000 --- a/src-lite/js/lib/topojson.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){function t(n,t){function r(t){var r,e=n.arcs[0>t?~t:t],o=e[0];return n.transform?(r=[0,0],e.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=e[e.length-1],0>t?[r,o]:[o,r]}function e(n,t){for(var r in n){var e=n[r];delete t[e.start],delete e.start,delete e.end,e.forEach(function(n){o[0>n?~n:n]=1}),f.push(e)}}var o={},i={},u={},f=[],c=-1;return t.forEach(function(r,e){var o,i=n.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++c],t[c]=r,t[e]=o)}),t.forEach(function(n){var t,e,o=r(n),f=o[0],c=o[1];if(t=u[f])if(delete u[t.end],t.push(n),t.end=c,e=i[c]){delete i[e.start];var a=e===t?t:t.concat(e);i[a.start=t.start]=u[a.end=e.end]=a}else i[t.start]=u[t.end]=t;else if(t=i[c])if(delete i[t.start],t.unshift(n),t.start=f,e=u[f]){delete u[e.end];var s=e===t?t:e.concat(t);i[s.start=e.start]=u[s.end=t.end]=s}else i[t.start]=u[t.end]=t;else t=[n],i[t.start=f]=u[t.end=c]=t}),e(u,i),e(i,u),t.forEach(function(n){o[0>n?~n:n]||f.push([n])}),f}function r(n,r,e){function o(n){var t=0>n?~n:n;(s[t]||(s[t]=[])).push({i:n,g:a})}function i(n){n.forEach(o)}function u(n){n.forEach(i)}function f(n){"GeometryCollection"===n.type?n.geometries.forEach(f):n.type in l&&(a=n,l[n.type](n.arcs))}var c=[];if(arguments.length>1){var a,s=[],l={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(n){n.forEach(u)}};f(r),s.forEach(arguments.length<3?function(n){c.push(n[0].i)}:function(n){e(n[0].g,n[n.length-1].g)&&c.push(n[0].i)})}else for(var h=0,p=n.arcs.length;p>h;++h)c.push(h);return{type:"MultiLineString",arcs:t(n,c)}}function e(r,e){function o(n){n.forEach(function(t){t.forEach(function(t){(f[t=0>t?~t:t]||(f[t]=[])).push(n)})}),c.push(n)}function i(n){return l(u(r,{type:"Polygon",arcs:[n]}).coordinates[0])>0}var f={},c=[],a=[];return e.forEach(function(n){"Polygon"===n.type?o(n.arcs):"MultiPolygon"===n.type&&n.arcs.forEach(o)}),c.forEach(function(n){if(!n._){var t=[],r=[n];for(n._=1,a.push(t);n=r.pop();)t.push(n),n.forEach(function(n){n.forEach(function(n){f[0>n?~n:n].forEach(function(n){n._||(n._=1,r.push(n))})})})}}),c.forEach(function(n){delete n._}),{type:"MultiPolygon",arcs:a.map(function(e){var o=[];if(e.forEach(function(n){n.forEach(function(n){n.forEach(function(n){f[0>n?~n:n].length<2&&o.push(n)})})}),o=t(r,o),(n=o.length)>1)for(var u,c=i(e[0][0]),a=0;n>a;++a)if(c===i(o[a])){u=o[0],o[0]=o[a],o[a]=u;break}return o})}}function o(n,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return i(n,t)})}:i(n,t)}function i(n,t){var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:u(n,t)};return null==t.id&&delete r.id,r}function u(n,t){function r(n,t){t.length&&t.pop();for(var r,e=s[0>n?~n:n],o=0,i=e.length;i>o;++o)t.push(r=e[o].slice()),a(r,o);0>n&&f(t,i)}function e(n){return n=n.slice(),a(n,0),n}function o(n){for(var t=[],e=0,o=n.length;o>e;++e)r(n[e],t);return t.length<2&&t.push(t[0].slice()),t}function i(n){for(var t=o(n);t.length<4;)t.push(t[0].slice());return t}function u(n){return n.map(i)}function c(n){var t=n.type;return"GeometryCollection"===t?{type:t,geometries:n.geometries.map(c)}:t in l?{type:t,coordinates:l[t](n)}:null}var a=v(n.transform),s=n.arcs,l={Point:function(n){return e(n.coordinates)},MultiPoint:function(n){return n.coordinates.map(e)},LineString:function(n){return o(n.arcs)},MultiLineString:function(n){return n.arcs.map(o)},Polygon:function(n){return u(n.arcs)},MultiPolygon:function(n){return n.arcs.map(u)}};return c(t)}function f(n,t){for(var r,e=n.length,o=e-t;o<--e;)r=n[o],n[o++]=n[e],n[e]=r}function c(n,t){for(var r=0,e=n.length;e>r;){var o=r+e>>>1;n[o]n&&(n=~n);var r=o[n];r?r.push(t):o[n]=[t]})}function r(n,r){n.forEach(function(n){t(n,r)})}function e(n,t){"GeometryCollection"===n.type?n.geometries.forEach(function(n){e(n,t)}):n.type in u&&u[n.type](n.arcs,t)}var o={},i=n.map(function(){return[]}),u={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(n,t){n.forEach(function(n){r(n,t)})}};n.forEach(e);for(var f in o)for(var a=o[f],s=a.length,l=0;s>l;++l)for(var h=l+1;s>h;++h){var p,g=a[l],v=a[h];(p=i[g])[f=c(p,v)]!==v&&p.splice(f,0,v),(p=i[v])[f=c(p,g)]!==g&&p.splice(f,0,g)}return i}function s(n,t){function r(n){i.remove(n),n[1][2]=t(n),i.push(n)}var e=v(n.transform),o=m(n.transform),i=g();return t||(t=h),n.arcs.forEach(function(n){for(var u,f,c=[],a=0,s=0,l=n.length;l>s;++s)f=n[s],e(n[s]=[f[0],f[1],1/0],s);for(var s=1,l=n.length-1;l>s;++s)u=n.slice(s-1,s+2),u[1][2]=t(u),c.push(u),i.push(u);for(var s=0,l=c.length;l>s;++s)u=c[s],u.previous=c[s-1],u.next=c[s+1];for(;u=i.pop();){var h=u.previous,p=u.next;u[1][2]0;){var r=(t+1>>1)-1,o=e[r];if(p(n,o)>=0)break;e[o._=t]=o,e[n._=t=r]=n}}function t(n,t){for(;;){var r=t+1<<1,i=r-1,u=t,f=e[u];if(o>i&&p(e[i],f)<0&&(f=e[u=i]),o>r&&p(e[r],f)<0&&(f=e[u=r]),u===t)break;e[f._=t]=f,e[n._=t=u]=n}}var r={},e=[],o=0;return r.push=function(t){return n(e[t._=o]=t,o++),o},r.pop=function(){if(!(0>=o)){var n,r=e[0];return--o>0&&(n=e[o],t(e[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(e[u]===r)return u!==--o&&(i=e[o],(p(i,r)<0?n:t)(e[i._=u]=i,u)),u},r}function v(n){if(!n)return y;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0),n[0]=(t+=n[0])*e+i,n[1]=(r+=n[1])*o+u}}function m(n){if(!n)return y;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0);var c=(n[0]-i)/e|0,a=(n[1]-u)/o|0;n[0]=c-t,n[1]=a-r,t=c,r=a}}function y(){}var d={version:"1.6.18",mesh:function(n){return u(n,r.apply(this,arguments))},meshArcs:r,merge:function(n){return u(n,e.apply(this,arguments))},mergeArcs:e,feature:o,neighbors:a,presimplify:s};"function"==typeof define&&define.amd?define(d):"object"==typeof module&&module.exports?module.exports=d:this.topojson=d}(); \ No newline at end of file diff --git a/src-lite/views/index.jade b/src-lite/views/index.jade index 8433a7f..7a078d0 100644 --- a/src-lite/views/index.jade +++ b/src-lite/views/index.jade @@ -88,21 +88,13 @@ block content i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type", ng-click="orderTable(['info.node'], false)") th.th-latency i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency", ng-click="orderTable(['stats.latency'], false)") - //- th - i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining", ng-click="orderTable(['-stats.hashrate'], false)") //- th i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers", ng-click="orderTable(['-stats.peers'], false)") - //- th - i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions", ng-click="orderTable(['-stats.pending'], false)") th i.icon-block(data-toggle="tooltip", data-placement="top", title="Last block", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)") th.th-blockhash   th.th-blockhash i.icon-difficulty(data-toggle="tooltip", data-placement="top", title="Total difficulty", ng-click="orderTable(['-stats.block.totalDifficulty'], false)") - //- th - i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions", ng-click="orderTable(['-stats.block.transactions.length'], false)") - //- th - i.icon-uncle(data-toggle="tooltip", data-placement="top", title="Uncles", ng-click="orderTable(['-stats.block.uncles.length'], false)") th.th-blocktime i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time", ng-click="orderTable(['-stats.block.received'], false)") th.th-peerPropagationTime @@ -110,8 +102,6 @@ block content //- th.th-peerPropagationChart //- th.th-peerPropagationAvg i.icon-gas(data-toggle="tooltip", data-placement="top", title="Average propagation time", ng-click="orderTable(['stats.propagationAvg'], false)") - //- th - i.icon-bulb(data-toggle="tooltip", data-placement="top", title="Up-time", ng-click="orderTable(['-stats.uptime'], false)") tbody(ng-cloak) tr(ng-repeat='node in nodes | orderBy:predicate track by node.id', class="{{ node.stats | mainClass : bestBlock }}", id="node_{{node.id}}") td.td-nodecheck @@ -125,9 +115,7 @@ block content div.small(ng-bind-html="node.info.node | nodeVersion") td(class="{{ node.readable.latencyClass }}") span.small {{ node.readable.latency }} - //- td(class="{{ node.stats.mining | hashrateClass : node.stats.active }}", ng-bind-html="node.stats.hashrate | hashrateFilter : node.stats.mining") //- td(class="{{ node.stats.peers | peerClass : node.stats.active }}", style="padding-left: 11px;") {{node.stats.peers}} - //- td(style="padding-left: 15px;") {{node.stats.pending}} td(class="{{ node.stats | blockClass : bestBlock }}") span(class="{{ node.readable.forkMessage ? node.readable.forkClass : '' }}") {{'#'}}{{ node.stats.block.number | number }} a.small(data-toggle="tooltip", data-placement="top", data-html="true", data-original-title="{{ node.readable.forkMessage }}", class="{{ node.readable.forkClass }}") @@ -136,8 +124,6 @@ block content span.small {{node.stats.block.hash | hashFilter}} td(class="{{ node.stats | blockClass : bestBlock }}") span.small {{node.stats.block.totalDifficulty | number}} - //- td(style="padding-left: 14px;") {{node.stats.block.transactions.length || 0}} - //- td(style="padding-left: 14px;") {{node.stats.block.uncles.length || 0}} td(class="{{ node.stats.block.received | timeClass : node.stats.active }}") {{node.stats.block.received | blockTimeFilter }} td(class="{{ node.stats | propagationTimeClass : bestBlock }}") div.propagationBox @@ -145,4 +131,3 @@ block content //- td.peerPropagationChart(class="{{node.id}}") nodepropagchart(data="{{node.history.join(',')}}") //- td(class="{{ node.stats | propagationNodeAvgTimeClass : bestBlock }}") {{ node.stats | blockPropagationAvgFilter : bestBlock }} - //- td(class="{{ node.stats.uptime | upTimeClass : node.stats.active }}") {{ node.stats.uptime | upTimeFilter }} diff --git a/src-lite/views/layout.jade b/src-lite/views/layout.jade index 4822caa..2171047 100644 --- a/src-lite/views/layout.jade +++ b/src-lite/views/layout.jade @@ -1,13 +1,13 @@ //- layout.jade doctype html -html(ng-app="netStatsApp") +html head meta(name="viewport", content="width=device-width, initial-scale=1.0, maximum-scale=1.0") title Ethereum Network Status style(type="text/css") [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; } link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700') link(rel='stylesheet', href='/css/netstats.min.css') - body + body(ng-app="netStatsApp") block content script(src="/js/netstats.min.js") \ No newline at end of file