🔐 Access Required

Enter PIN to continue

The overlay markup stays per-site (each site keeps its own colours), and this file finds it by id. `data-gate-key` names the localStorage slot, so each site remembers its own unlock. Optional: data-gate-input / data-gate-button / data-gate-error / data-gate-overlay to match different markup without editing this file. =========================================================================== */ (function () { 'use strict'; var self = document.currentScript; if (!self) return; var attr = function (name, fallback) { var v = self.getAttribute(name); return v === null ? fallback : v; }; /* ---- the canonical PIN: DDMMYYHH -------------------------------------- */ function standardPin(now) { var pz = function (n) { return n < 10 ? '0' + n : '' + n; }; return pz(now.getDate()) + pz(now.getMonth() + 1) + String(now.getFullYear()).slice(-2) + pz(now.getHours()); } var KEY = attr('data-gate-key', 'site_pin_8'); var ov = document.getElementById(attr('data-gate-overlay', 'pin-overlay')) || document.getElementById('gate'); var input = document.getElementById(attr('data-gate-input', 'pin-input')) || document.getElementById('gate-input'); var button = document.getElementById(attr('data-gate-button', 'pin-submit')) || document.getElementById('gate-btn'); var err = document.getElementById(attr('data-gate-error', 'pin-error')) || document.getElementById('gate-err'); if (!ov) return; // nothing to gate on this page var pin = standardPin(new Date()); function unlock() { ov.style.display = 'none'; ov.classList.add('hidden'); document.body.classList.remove('gated'); } function store(v) { try { localStorage.setItem(KEY, v); } catch (e) {} } function recall() { try { return localStorage.getItem(KEY); } catch (e) { return null; } } // Already unlocked this hour? Then stay unlocked. if (recall() === pin) { unlock(); } else { document.body.classList.add('gated'); } function submit() { if (input && input.value.trim() === pin) { store(pin); unlock(); } else { if (err) err.textContent = 'Invalid PIN'; if (input) { input.value = ''; input.focus(); } } } if (button) button.addEventListener('click', submit); if (input) { // accept one press of Enter as well as a click input.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); submit(); } }); if (recall() !== pin) input.focus(); } /* ---- source deterrents ------------------------------------------------ Blocks the casual "view source / inspect" route. Trivially bypassed by anyone who disables JavaScript or uses a proxy; it is a speed bump. */ function deterrents() { document.addEventListener('contextmenu', function (e) { e.preventDefault(); return false; }); document.addEventListener('keydown', function (e) { var k = (e.key || '').toUpperCase(); if (k === 'F12' || (e.ctrlKey && e.shiftKey && ['I', 'J', 'C', 'K'].indexOf(k) >= 0) || (e.ctrlKey && k === 'U')) { e.preventDefault(); return false; } }, true); // let people select text inside form fields, but not the page at large var inField = function (e) { return !!(e.target && e.target.closest && e.target.closest('input,textarea,select')); }; document.addEventListener('selectstart', function (e) { if (!inField(e)) e.preventDefault(); }); document.addEventListener('copy', function (e) { if (!inField(e)) e.preventDefault(); }); } deterrents(); })();

🛠️ NETLAB Tools

Network troubleshooting toolbox — DNS, port scan, ping, headers, subnet calc. All free.

IPv4 Calculator

Enter IP + prefix → results

Subnet Division

Enter prefix lengths → results

DNS Lookup (dig-style)

Results appear here…

DNS Propagation

Queries 4 public resolvers independently.

Results appear here…

TCP Ping

Results appear here…

Port Scanner

Results appear here…

Banner Grabber

Results appear here…

SSL Certificate Check

Results appear here…

HTTP Header Scanner

Results appear here…

What is my IP?

Click to find your IP…

IP Info & ASN Lookup

Results appear here…

WHOIS Lookup

IANA RDAP — free, no API key.

Results appear here…

Status Dashboard

Click to refresh status…

Ansible Config Generator

YAML output will appear here...

DNS Cache Clear — client-side

Windows:  ipconfig /flushdns
macOS:    sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Linux:    sudo systemd-resolve --flush-caches
Router/AP: reboot it