var rangeSize = 300; var shareSize = 61; var shareX, shareY; mapboxgl.accessToken = 'pk.eyJ1Ijoic2hldm9ua3VhbiIsImEiOiJja20yMjlnNDYybGg2Mm5zNW40eTNnNnUwIn0.6xj6sgjWvdQgT_7OQUy_Jg'; $(document).ready(function() { lockMap(); if (getQuery("ip") === null) { getInfo(); } else { $("input").val(getQuery("ip")); getInfo(); } $("#table").hide(); $("#share").hide(); $("button").click(function() { $(this).css({ 'border-color': '', 'background-color': '' }); $(this).text("Searching..."); lockMap(); $("#table").hide(500); $("input").val(trim($("input").val())); if ($("input").val() == '' || checkIP($("input").val()) == "ok") { getInfo(); } else { errorIP(); } }); $(".table tr:first td:first").dblclick(function(event) { event.stopPropagation(); getVersion(); }); $("input").dblclick(function(event) { event.stopPropagation(); }); $("button").dblclick(function(event) { event.stopPropagation(); }); $("table").dblclick(function(event) { event.stopPropagation(); }); $('#output').dblclick(function() { showQRCode(); }); $('#output').click(function() { hideQRCode(); }); $('#map').click(function() { hideQRCode(); }); $('body').mousemove(function() { checkRange(); }); $('body').mouseleave(function() { hideQRCode(); }); $(window).resize(function() { if (isPortrait()) { $(".positioncontrol").css('left', '0'); $(".positioncontrol").css('right', '0'); $(".positioncontrol").css('transform', 'translate(0, 0)'); } else { $(".positioncontrol").css('left', 'calc(80vw - 180px)'); $(".positioncontrol").css('right', ''); $(".positioncontrol").css('transform', 'translate(-20%, 0)'); } }); }); $(document).keydown(function(event) { if (event.keyCode == 13) { $("button").focus(); } }); function isPortrait() { if ($(document).width() < $(document).height()) { return true; } if ($(document).width() < 800) { return true; } return false; } function lockMap() { if (!isPortrait()) { return; } $(".positioncontrol").css('left', '0'); $(".positioncontrol").css('right', '0'); } function unlockMap() { if (!isPortrait()) { return; } var margin = $('#output').css('margin-left'); if (margin !== '0px') { $('.positioncontrol').css('left', margin); $('.positioncontrol').css('right', margin); } } function checkRange() { var distanceX = Math.abs(event.pageX - shareX); var distanceY = Math.abs(event.pageY - shareY); if ((distanceX >= rangeSize) || (distanceY >= rangeSize)) { hideQRCode(); } } function hideQRCode() { if (!$("#qrcode").is(':hidden')) { $("#share").hide(200); } } function showQRCode() { var ip = $("#ip").text(); if (checkIP(ip) == 'ok') { var pageUri = "https://" + window.location.host + "/?ip=" + ip; $("#qrcode").attr("href", pageUri); $("#qrcode").empty(); $('#qrcode').qrcode({ width: 100, height: 100, text: pageUri }); var shareLeft = event.pageX - shareSize; var shareTop = event.pageY - shareSize; if (shareLeft + shareSize * 2 > $(document).width()) { shareLeft = $(document).width() - shareSize * 2; } if (shareTop + shareSize * 2 > $(document).height()) { shareTop = $(document).height() - shareSize * 2; } if (shareLeft < 0) { shareLeft = 0; } if (shareTop < 0) { shareTop = 0; } shareX = shareLeft + shareSize; shareY = shareTop + shareSize; if ($("#qrcode").is(':hidden')) { $("#share").css('left', shareLeft); $("#share").css('top', shareTop); $("#share").show(200); } else { $("#share").hide(100, function() { $("#share").css('left', shareLeft); $("#share").css('top', shareTop); $("#share").show(150); }); } } } function getInfo() { $.get("/info/" + $("input").val(), function(data) { console.log(data); if (data.status == "F") { errorIP(); return; } if (!$("input").val()) { $("input").val(data.ip); } $("button").text("Search"); $("#ip").text(data.ip); data.city = (data.city == null) ? "Unknow" : data.city; data.region = (data.region == null) ? "Unknow" : data.region; data.country = (data.country == null) ? "Unknow" : data.country; data.timezone = (data.timezone == null) ? "Unknow" : data.timezone; data.isp = (data.isp == null) ? "Unknow" : data.isp; data.scope = (data.scope == null) ? "Unknow" : data.scope; data.detail = (data.detail == null || data.detail == ' ') ? "Unknow" : data.detail; $("#city").text(data.city); $("#region").text(data.region); $("#country").text(data.country); $("#timezone").text(data.timezone); $("#isp").text(data.isp); $("#scope").text(data.scope); $("#detail").text(data.detail); if (data.as == null) { $("#as").text("Unknow"); } else { $("#as").text(data.as); var asUri = "https://bgpview.io/asn/" + data.as.substr(2); $("#as").html('' + data.as + ''); } if (data.loc == null) { $("#loc").text("Unknow"); clear(); } else { var earthUri = "https://earth.google.com/web/@" + data.loc + ",9.963a,7999.357d,35y,-34.3h,45t,0r/data=KAI"; $("#loc").html('' + data.loc + ''); draw(parseFloat(data.loc.split(',')[0]), parseFloat(data.loc.split(',')[1])); } $("#table").show(500); setTimeout(function() { unlockMap(); }, 3000); }); } function getVersion() { $.get("/version", function(data) { console.log(data); data.qqwry = data.qqwry.slice(0, 4) + "-" + data.qqwry.slice(4, 6) + "-" + data.qqwry.slice(6, 8); data.ipip = data.ipip.slice(0, 4) + "-" + data.ipip.slice(4, 6) + "-" + data.ipip.slice(6, 8); var data_ver = ""; data_ver += "echoIP: " + data.echoip + "\n"; data_ver += "纯真数据库: " + data.qqwry + "\n"; data_ver += "IPIP.net数据库: " + data.ipip; alert(data_ver); }); } function trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } function errorIP() { $("button").text("Illegal IP"); $("button").css({ 'border-color': '#ff406f', 'background-color': '#ff406f' }); $("input").focus(); } function checkIP(ipStr) { if (ipStr === null) { return "error"; } var regIPv4=/^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/; var regIPv6=/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}(:[0-9A-Fa-f]{1,4}){1,2})|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){1,3})|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){1,4})|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){1,5})|([0-9A-Fa-f]{1,4}:(:[0-9A-Fa-f]{1,4}){1,6})|(:(:[0-9A-Fa-f]{1,4}){1,7})|(([0-9A-Fa-f]{1,4}:){6}(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){5}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|([0-9A-Fa-f]{1,4}:(:[0-9A-Fa-f]{1,4}){0,4}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(:(:[0-9A-Fa-f]{1,4}){0,5}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}))$/; var V4 = ipStr.match(regIPv4); var V6 = ipStr.match(regIPv6); if (V4 === null && V6 === null) { return "error"; } else { return "ok"; } } function getQuery(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var result = window.location.search.substr(1).match(reg); if (result != null) { return unescape(result[2]); } else { return null; } } function clear() { var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11', center: [0, 0], zoom: 1 }); map.on('load', function() { console.log("reset map"); }); }; function draw(x, y) { var size = 100; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11', center: [y, x], zoom: 3 }); var pulsingDot = { width: size, height: size, data: new Uint8Array(size * size * 4), onAdd: function() { var canvas = document.createElement('canvas'); canvas.width = this.width; canvas.height = this.height; this.context = canvas.getContext('2d'); }, render: function() { var duration = 1000; var t = (performance.now() % duration) / duration; var radius = size / 2 * 0.3; var outerRadius = size / 2 * 0.7 * t + radius; var context = this.context; context.clearRect(0, 0, this.width, this.height); context.beginPath(); context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2); context.fillStyle = 'rgba(255, 200, 200,' + (1 - t) + ')'; context.fill(); context.beginPath(); context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2); context.fillStyle = 'rgba(255, 100, 100, 1)'; context.strokeStyle = 'white'; context.lineWidth = 2 + 4 * (1 - t); context.fill(); context.stroke(); this.data = context.getImageData(0, 0, this.width, this.height).data; map.triggerRepaint(); return true; } }; map.on('load', function() { map.addImage('pulsing-dot', pulsingDot, { pixelRatio: 2 }); map.addLayer({ "id": "points", "type": "symbol", "source": { "type": "geojson", "data": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [y, x] } }] } }, "layout": { "icon-image": "pulsing-dot" } }); }); };