extends layout block headContent title Peers link(rel="stylesheet", href="/css/dataTables.bootstrap4.min.css", integrity="sha384-EkHEUZ6lErauT712zSr0DZ2uuCmi3DoQj6ecNdHQXpMpFNGAQ48WjfXCE5n20W+R") link(rel="stylesheet", href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css", integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==", crossorigin="") script(src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js", integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==", crossorigin="") style. .versions-hidden-rows, .services-hidden-rows { display: none; } #map { height: 700px; } block content h1(class="h3") #{peerSummary.getpeerinfo.length} if (peerSummary.getpeerinfo.length == 1) span Peer else span Peers hr ul(class='nav nav-tabs mb-3') li(class="nav-item") a(data-toggle="tab", href="#tab-summary", class="nav-link active", role="tab") Summary li(class="nav-item") a(data-toggle="tab", href="#tab-json", class="nav-link", role="tab") JSON div(class="tab-content") div(id="tab-summary", class="tab-pane active", role="tabpanel") if (peerIpSummary.ips) div(id="map", class="mb-4") div(class="card mb-4 shadow-sm") div(class="card-header") h2(class="h6 mb-0") Summary div(class="card-body") div(class="row") div(class="col-md-6") span(class="font-weight-bold") Top Versions hr table(class="table table-striped table-responsive-sm") thead tr th th(class="data-header") Version th(class="data-header") Count tbody each item, index in peerSummary.versionSummary tr(class=(index >= 5 ? "versions-hidden-rows" : false)) td(class="data-cell font-weight-bold") #{index + 1} td(class="data-cell monospace") #{item[0]} td(class="data-cell monospace") #{item[1].toLocaleString()} div(class="col-md-6") span(class="font-weight-bold") Top Service Flags hr table(class="table table-striped table-responsive-sm") thead tr th th(class="data-header") Services th(class="data-header") Count tbody each item, index in peerSummary.servicesSummary tr(class=(index >= 5 ? "services-hidden-rows" : false)) td(class="data-cell font-weight-bold") #{index + 1} td(class="data-cell monospace") #{item[0]} td(class="data-cell monospace") #{item[1].toLocaleString()} div(class="card mb-4 shadow-sm") div(class="card-header") h2(class="h6 mb-0") #{peerSummary.getpeerinfo.length} if (peerSummary.getpeerinfo.length == 1) span Peer else span Peers div(class="card-body") table(class="table table-striped table-responsive-sm data-table mt-4") thead tr th th(class="data-header") Version th(class="data-header") Address th(class="data-header") Services if (peerIpSummary.ips) th(class="data-header") Location th(class="data-header") Last Send / Receive tbody each item, index in peerSummary.getpeerinfo - var lastSendAgo = moment.duration(moment.utc(new Date()).diff(moment.utc(new Date(parseInt(item.lastsend) * 1000)))).format().replace("milliseconds", "ms"); - var lastRecvAgo = moment.duration(moment.utc(new Date()).diff(moment.utc(new Date(parseInt(item.lastrecv) * 1000)))).format().replace("milliseconds", "ms"); tr th(class="data-cell") #{index + 1} td(class="data-cell monospace") #{item.subver} td(class="data-cell monospace") #{item.addr} td(class="data-cell monospace") #{item.services} if (peerIpSummary.ips) td(class="data-cell monospace") - var ipAddr = item.addr.substring(0, item.addr.lastIndexOf(":")); if (peerIpSummary.ips && peerIpSummary.ips.includes(ipAddr)) - var ipDetails = peerIpSummary.detailsByIp[ipAddr]; if (ipDetails.city) span #{ipDetails.city}, if (ipDetails.region) span #{ipDetails.region}, if (ipDetails.country) span #{ipDetails.country} else span ? - var ipAddr = null; td(class="data-cell monospace") #{lastSendAgo} / #{lastRecvAgo} div(id="tab-json", class="tab-pane", role="tabpanel") each item, index in peerSummary.getpeerinfo div(class="border-bottom p-1") a(href="javascript:void(0)" onclick=("javascript:var peer = document.getElementById('peerinfo_" + index + "'); peer.style.display = peer.style.display === 'none' ? '' : 'none';")) i(class="fas fa-plus-circle") span(class="monospace") #{item.addr} div(style="display: none;", id=("peerinfo_" + index), class="p-3") h6 Peer Details pre code(class="json bg-light") #{JSON.stringify(item, null, 4)} if (peerIpSummary && peerIpSummary.detailsByIp && peerIpSummary.detailsByIp[item.addr.substring(0, item.addr.lastIndexOf(":"))]) hr h6 IP Geo-Location Info pre code(class="json bg-light") #{JSON.stringify(peerIpSummary.detailsByIp[item.addr.substring(0, item.addr.lastIndexOf(":"))], null, 4)} block endOfBody script(src="/js/jquery.dataTables.min.js", integrity="sha384-rgWRqC0OFPisxlUvl332tiM/qmaNxnlY46eksSZD84t+s2vZlqGeHrncwIRX7CGp") script(src="/js/dataTables.bootstrap4.min.js", integrity="sha384-uiSTMvD1kcI19sAHJDVf68medP9HA2E2PzGis9Efmfsdb8p9+mvbQNgFhzii1MEX") script. $(document).ready(function() { $(".data-table").DataTable(); }); if (peerIpSummary.ips) script. var mymap = L.map('map').setView([21.505, -0.09], 3); L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', { maxZoom: 18, attribution: 'Map data © OpenStreetMap contributors, ' + 'CC-BY-SA, ' + 'Imagery © Mapbox', id: 'mapbox.streets' }).addTo(mymap); /*L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(mymap);*/ $(document).ready(function() { window.dispatchEvent(new Event('resize')); }); each ipAddress, index in peerIpSummary.ips - var ipDetails = peerIpSummary.detailsByIp[ipAddress]; if (ipDetails && ipDetails.lat && ipDetails.lon) - var ipDetailsPopupHtml = "" + ipAddress + "
"; if (ipDetails.city) - var ipDetailsPopupHtml = ipDetailsPopupHtml + ipDetails.city + ", "; if (ipDetails.region) - var ipDetailsPopupHtml = ipDetailsPopupHtml + ipDetails.region + ", "; if (ipDetails.country) - var ipDetailsPopupHtml = ipDetailsPopupHtml + ipDetails.countryCode + " "; script L.marker([#{ipDetails.lat}, #{ipDetails.lon}]).addTo(mymap).bindPopup("!{ipDetailsPopupHtml}");