\n docs (APIs, privacy, etc.) —\n mirror —\n stats ▼\n `;let osInstall="";async function fetchIPData(e){const t=document.getElementById(e);t.innerHTML='
Loading…
';const a=mirrors.map((t=>`https://${e}.${t}/json`));for(const e of a)try{const a=await fetch(e);if(!a.ok)continue;return t.innerHTML=renderIPData(await a.json()),void updateMaps("true"===localStorage.getItem("showMaps"))}catch(t){console.error(`Failed to fetch from ${e}:`,t)}t.innerHTML='Error: Failed to fetch IP data
'}function getLocation(){const e=navigator.geolocation;e?e.getCurrentPosition((({coords:{latitude:e,longitude:t}})=>{document.getElementById("browsercoord").innerHTML=`${e}, ${t}`;const a=document.getElementById("browsermap");Object.assign(a.dataset,{lat:e,long:t}),a.className="map-container","true"===localStorage.getItem("showMaps")&&(a.innerHTML=createMapIframe(e,t))}),(e=>{console.error("Geolocation error:",e),showGeolocateButton()})):document.getElementById("browsercoord").innerHTML="Geolocation not supported"}ua.includes("iPhone")?osInstall='iPhone appbrew install identme
scoop bucket add extras; scoop install identme
${e}`)).join(""))}catch(e){console.error(`Failed to fetch headers from ${t}:`,e)}e.classList.remove("loading"),e.innerHTML="Failed to fetch headers"})(),document.addEventListener("click",(async e=>{const t=e.target.closest(".copy");if(t){e.preventDefault();try{await navigator.clipboard.writeText(t.dataset.copy);const e=t.querySelector(".copy-icon");e.textContent="✅",setTimeout((()=>e.textContent="📋"),1e3)}catch(e){console.error("Failed to copy:",e)}}}));const showMapsCheckbox=document.getElementById("show-maps");showMapsCheckbox.checked="true"===localStorage.getItem("showMaps"),showMapsCheckbox.addEventListener("change",(e=>{const t=e.target.checked;localStorage.setItem("showMaps",t),document.querySelectorAll(".map-container").forEach((e=>{e.innerHTML=t?createMapIframe(Number(e.dataset.lat),Number(e.dataset.long)):""}))}));const windowSize=document.getElementById("window"),updateWindowSize=()=>{windowSize.innerHTML=`${innerWidth}×${innerHeight}`};function showGeolocateButton(){const e=document.getElementById("geolocate");e.style.display="block",e.onclick=()=>{getLocation(),e.remove()}}function setupCanvas(e){const t=window.devicePixelRatio||1,a=e.getBoundingClientRect();e.width=a.width*t,e.height=a.height*t;const n=e.getContext("2d");return n.scale(t,t),n}async function drawSparkline(e,t,a,n={}){const{color1:o="#4caf50",color2:r="#0077b6",label1:s="reqs",label2:i="IPs",stacked:c=!1}=n,l=document.getElementById(e),d=setupCanvas(l),{width:m,height:p}=l.getBoundingClientRect();d.font="1em sans-serif";const h=d.measureText(`${s}: ${t[0].toLocaleString()}`),u=h.actualBoundingBoxAscent+h.actualBoundingBoxDescent,g=h.actualBoundingBoxAscent,f=2*(2+u),y=[];let w=null;function $(e,n,o,r=Math.max(...e),l=Math.min(...e)){const h=r-l;d.beginPath(),d.strokeStyle=n,d.lineWidth=2,e.forEach(((n,r)=>{const c=5+r*(m-10)/(e.length-1),u=p-5-(p-10)*(n-l)/h;y[r]||(y[r]={x:c}),y[r][s]=t[r],y[r][i]=a[r],y[r][o]=u,d[0===r?"moveTo":"lineTo"](c,u)})),d.stroke(),c&&(d.lineTo(m-5,p-5),d.lineTo(5,p-5),d.closePath(),d.fillStyle=`${n}33`,d.fill())}function v(){if(d.clearRect(0,0,m,p),c){const e=Math.max(...t.map(((e,t)=>e+a[t])));$(a,r,"y2",e,0),$(t.map(((e,t)=>e+a[t])),o,"y",e,0)}else $(t,o,"y"),$(a,r,"y2");if(w){d.font="1em sans-serif",d.textAlign="right",d.fillStyle="rgba(0, 0, 0, 0.5)";const e=d.measureText(`${s}: ${w[s].toLocaleString()}`).width+4;d.fillRect(m-e,2,e,f),[{label:s,color:o},{label:i,color:r}].forEach((({label:e,color:t},a)=>{d.fillStyle=t,d.fillText(`${e}: ${w[e].toLocaleString()}`,m-2,2+g+a*u)}))}}v(),l.addEventListener("mousemove",(e=>{const t=l.getBoundingClientRect(),a=e.clientX-t.left;w=y.reduce(((e,t)=>Math.abs(a-t.x)
Failed to load stats
'}}function updateMaps(e){document.querySelectorAll(".map-container").forEach((t=>{if(e&&!t.querySelector("iframe")){const{lat:e,long:a}=t.dataset;t.innerHTML=createMapIframe(Number(e),Number(a))}else e||(t.innerHTML="")}))}async function getWebRTC(){const e=new Set;try{const t=new RTCPeerConnection({iceServers:[{urls:"stun:ident.me:3478"},{urls:"stun:tnedi.me:3478"}]});t.createDataChannel("");const a=await t.createOffer();await t.setLocalDescription(a),t.onicecandidate=({candidate:t})=>{if(!t)return;let a=t.address;a.startsWith("[")&&(a=a.slice(1,-1)),e.add(a),document.getElementById("webrtc").innerHTML=[...e].map((e=>`${e}`)).join("")},setTimeout((()=>t.close()),1e4)}catch(e){document.getElementById("webrtc").innerHTML="Detection failed",console.error("WebRTC detection failed:",e)}}addEventListener("resize",updateWindowSize),updateWindowSize(),"permissions"in navigator&&navigator.geolocation?navigator.permissions.query({name:"geolocation"}).then((e=>"granted"===e.state?getLocation():showGeolocateButton())):navigator.geolocation?showGeolocateButton():getLocation(),"true"===localStorage.getItem("showStats")&&toggleStats(),getWebRTC()