Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
portableapps
/
assets
/
admin
:
ipcard-20261026170859.js
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
// IP address hover cards. Each address is a Themestrap HoverCard that asks the blog for details the first time // it is shown. The blog fetches them from the lookup service and remembers the answer, so the browser never // contacts the service itself. (function ($) { 'use strict'; var root = document.querySelector('[data-ip-endpoint]'); if (!root || !$.fn.themestrapPluginHoverCard) return; var endpoint = root.getAttribute('data-ip-endpoint'); var cache = {}; function label(k) { return k.replace(/[_\-]+/g, ' ').replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, function (c) { return c.toUpperCase(); }); } // Two letter country code to a flag emoji function flag(cc) { if (!/^[A-Za-z]{2}$/.test(cc)) return ''; return String.fromCodePoint.apply(null, cc.toUpperCase().split('').map(function (c) { return 127397 + c.charCodeAt(0); })); } function pick(d, names) { var keys = Object.keys(d); for (var i = 0; i < names.length; i++) { for (var j = 0; j < keys.length; j++) if (keys[j].toLowerCase().replace(/[ _\-]/g, '') === names[i]) return keys[j]; } // Then names inside a group, such as "connection isp" for (var a = 0; a < names.length; a++) { if (names[a].length < 3) continue; for (var b = 0; b < keys.length; b++) if (keys[b].toLowerCase().replace(/[ _\-]/g, '').slice(-names[a].length) === names[a]) return keys[b]; } return null; } function render($card, ip, r) { $card.empty(); var $head = $('<div class="hc-name a-ip-title">').appendTo($card); if (!r.ok) { $head.text(ip); $('<p class="hc-bio a-ip-msg">').text(r.error || 'No details available.').appendTo($card); return; } if (r.local) { $head.text(ip); $('<p class="hc-bio a-ip-msg">').text('A private or local address. There is nothing to look up.').appendTo($card); return; } var d = r.data, used = {}; var cityK = pick(d, ['city']), regK = pick(d, ['region', 'regionname', 'state']), cK = pick(d, ['country', 'countryname']), ccK = pick(d, ['countrycode', 'countrycode2', 'cc', 'iso2']); var place = [cityK, regK, cK].filter(Boolean).map(function (k) { used[k] = 1; return d[k]; }); if (ccK) used[ccK] = 1; var f = ccK ? flag(d[ccK]) : (cK && flag(d[cK]) ? flag(d[cK]) : ''); $head.text((f ? f + ' ' : '') + (place.join(', ') || ip)); $('<div class="hc-handle a-mono">').text(ip).appendTo($card); ['ip', 'query', 'success', 'status', 'ipaddress'].forEach(function (n) { var k = pick(d, [n]); if (k) used[k] = 1; }); var order = [['isp', 'org', 'organization', 'organisation', 'asname'], ['asn', 'as'], ['timezone', 'timezoneid', 'timezonename'], ['latitude', 'lat'], ['longitude', 'lon', 'lng'], ['postal', 'zip', 'postalcode']]; var rows = []; order.forEach(function (names) { var k = pick(d, names); if (k && !used[k]) { used[k] = 1; rows.push(k); } }); Object.keys(d).forEach(function (k) { if (!used[k]) rows.push(k); }); if (rows.length) { $('<hr class="hc-divider">').appendTo($card); var $dl = $('<dl class="a-ip-rows">').appendTo($card); rows.forEach(function (k) { $('<dt>').text(label(k)).appendTo($dl); $('<dd>').text(d[k]).appendTo($dl); }); } } function load(inst) { var $wrap = inst.$el, ip = $wrap.attr('data-ip'), $card = inst.$content; if ($wrap.data('ipLoaded')) { inst.update(); return; } if (cache[ip]) { $wrap.data('ipLoaded', 1); render($card, ip, cache[ip]); inst.update(); return; } $card.empty().append($('<div class="hc-name a-ip-title">').text(ip), $('<p class="hc-bio a-ip-msg">').text('Looking up…')); inst.update(); var u = new URL(endpoint, location.href); u.searchParams.set('ip', ip); fetch(u.toString(), { credentials: 'same-origin', headers: { 'X-Requested-With': 'fetch' } }) .then(function (r) { return r.json(); }) .catch(function () { return { ok: false, error: 'The lookup failed. Try again in a moment.' }; }) .then(function (r) { if (r.ok) { cache[ip] = r; $wrap.data('ipLoaded', 1); } render($card, ip, r); inst.update(); }); } $('[data-plugin-hovercard][data-ip]').each(function () { $(this).themestrapPluginHoverCard({ side: 'bottom', align: 'start', arrow: true, portaling: true, delay: [250, 200], ariaLabel: 'IP address details', onShow: function () { load(this); } }); }); })(jQuery);