[ CRT: off ]
Visitors: 000003489 | Server: 2026-07-13 23:24:24 UTC | UTC: 2026-07-13 23:24:24 UTC
Best Viewed in Firefox | Powered by PHP 7.4.33 | Connection: HTTPS (secure) | No Cookies · No Tracking
*** Welcome to the last honest website on the internet *** +++ This site stores NOTHING about you -- everything is computed in YOUR browser +++ NEW! Live browser fingerprinting module added +++ NEW! Interactive terminal -- type help to begin +++ Best viewed in Firefox at 1024x768 or higher +++ Remember: if the product is free, usually YOU are the product -- but not here +++ Greetz to everyone still running an old CRT monitor <3

disk Source Code

The entire project, readable in your browser. No hidden JavaScript, no sneaky beacons. If we claimed we don't track you, this is where you check.

disk assets/js/detect.js  (21.2 KB, 494 lines)
   1  /* ============================================================================
   2     detect.js  --  Browser & hardware detection engine
   3     ----------------------------------------------------------------------------
   4     Probes the browser for everything it will tell us: engine/version, OS,
   5     architecture, cores, memory, screen, feature-support for 60+ Web APIs,
   6     permissions, media devices, codecs, image formats, fonts, and more.
   7  
   8     Exposes:  window.EYES.detect()  ->  Promise<object>
   9  
  10     Nothing here is transmitted anywhere. It is all read locally and handed back
  11     to the page that asked for it. The heavy fingerprint hashing lives in
  12     fingerprint.js; this file is pure feature/attribute enumeration.
  13     ========================================================================== */
  14  (function () {
  15    "use strict";
  16  
  17    window.EYES = window.EYES || {};
  18  
  19    /* ---- tiny helpers ------------------------------------------------------ */
  20    function safe(fn, dflt) {
  21      try { var v = fn(); return (v === undefined ? dflt : v); }
  22      catch (e) { return dflt; }
  23    }
  24    function has(obj, prop) { try { return prop in obj; } catch (e) { return false; } }
  25    function yn(v) { return v === true ? 'Yes' : (v === false ? 'No' : (v == null ? 'Unknown' : v)); }
  26  
  27    /* ---- User-Agent parsing (lightweight, no libraries) -------------------- */
  28    function parseUA(ua) {
  29      ua = ua || '';
  30      var out = { browser: 'Unknown', version: '', engine: 'Unknown', os: 'Unknown', osVersion: '' };
  31  
  32      // Engine
  33      if (/Gecko\/|rv:.*Gecko/.test(ua) && /Firefox/.test(ua)) out.engine = 'Gecko';
  34      else if (/AppleWebKit/.test(ua) && /Edg\//.test(ua))      out.engine = 'Blink';
  35      else if (/AppleWebKit/.test(ua) && /Chrome\//.test(ua))   out.engine = 'Blink';
  36      else if (/AppleWebKit/.test(ua))                          out.engine = 'WebKit';
  37      else if (/Trident/.test(ua))                              out.engine = 'Trident';
  38  
  39      // Browser + version (order matters: check derivatives before Chrome/Safari)
  40      var m;
  41      if ((m = ua.match(/Firefox\/([\d.]+)/)))      { out.browser = 'Firefox'; out.version = m[1]; }
  42      else if ((m = ua.match(/Edg\/([\d.]+)/)))     { out.browser = 'Edge';    out.version = m[1]; }
  43      else if ((m = ua.match(/OPR\/([\d.]+)/)))     { out.browser = 'Opera';   out.version = m[1]; }
  44      else if ((m = ua.match(/Vivaldi\/([\d.]+)/))) { out.browser = 'Vivaldi'; out.version = m[1]; }
  45      else if ((m = ua.match(/SamsungBrowser\/([\d.]+)/))) { out.browser = 'Samsung Internet'; out.version = m[1]; }
  46      else if ((m = ua.match(/Chrome\/([\d.]+)/)))  { out.browser = 'Chrome';  out.version = m[1]; }
  47      else if ((m = ua.match(/Version\/([\d.]+).*Safari/))) { out.browser = 'Safari'; out.version = m[1]; }
  48      else if (/MSIE|Trident/.test(ua)) {
  49        out.browser = 'Internet Explorer';
  50        m = ua.match(/(?:MSIE |rv:)([\d.]+)/); out.version = m ? m[1] : '';
  51      }
  52  
  53      // OS
  54      if (/Windows NT 10/.test(ua))      { out.os = 'Windows'; out.osVersion = '10/11'; }
  55      else if (/Windows NT 6\.3/.test(ua)) { out.os = 'Windows'; out.osVersion = '8.1'; }
  56      else if (/Windows NT 6\.2/.test(ua)) { out.os = 'Windows'; out.osVersion = '8'; }
  57      else if (/Windows NT 6\.1/.test(ua)) { out.os = 'Windows'; out.osVersion = '7'; }
  58      else if (/Windows NT 5\.1/.test(ua)) { out.os = 'Windows'; out.osVersion = 'XP'; }
  59      else if (/Windows/.test(ua))         { out.os = 'Windows'; }
  60      else if (/Android ([\d.]+)/.test(ua)){ out.os = 'Android'; out.osVersion = (ua.match(/Android ([\d.]+)/)||[])[1] || ''; }
  61      else if (/iPhone|iPad|iPod/.test(ua)){ out.os = 'iOS'; out.osVersion = ((ua.match(/OS ([\d_]+)/)||[])[1] || '').replace(/_/g,'.'); }
  62      else if (/Mac OS X ([\d_]+)/.test(ua)){ out.os = 'macOS'; out.osVersion = (ua.match(/Mac OS X ([\d_]+)/)[1] || '').replace(/_/g,'.'); }
  63      else if (/CrOS/.test(ua))            { out.os = 'ChromeOS'; }
  64      else if (/Linux/.test(ua))           { out.os = 'Linux'; }
  65      else if (/X11/.test(ua))             { out.os = 'Unix'; }
  66  
  67      return out;
  68    }
  69  
  70    /* ---- async: battery ---------------------------------------------------- */
  71    function getBattery() {
  72      return new Promise(function (resolve) {
  73        if (!navigator.getBattery) { resolve(null); return; }
  74        var done = false;
  75        var t = setTimeout(function () { if (!done) { done = true; resolve(null); } }, 1500);
  76        navigator.getBattery().then(function (b) {
  77          if (done) return; done = true; clearTimeout(t);
  78          resolve({
  79            charging: b.charging,
  80            level: Math.round(b.level * 100),
  81            chargingTime: b.chargingTime,
  82            dischargingTime: b.dischargingTime
  83          });
  84        }).catch(function () { if (!done) { done = true; clearTimeout(t); resolve(null); } });
  85      });
  86    }
  87  
  88    /* ---- async: permissions ------------------------------------------------ */
  89    function getPermissions() {
  90      return new Promise(function (resolve) {
  91        var results = {};
  92        if (!navigator.permissions || !navigator.permissions.query) { resolve(results); return; }
  93        var names = ['geolocation','notifications','camera','microphone','clipboard-read',
  94                     'clipboard-write','persistent-storage','midi','background-sync'];
  95        var pending = names.length;
  96        if (pending === 0) { resolve(results); return; }
  97        names.forEach(function (n) {
  98          var settled = false;
  99          var finish = function (state) {
 100            if (settled) return; settled = true;
 101            results[n] = state; if (--pending === 0) resolve(results);
 102          };
 103          try {
 104            navigator.permissions.query({ name: n }).then(function (p) { finish(p.state); })
 105              .catch(function () { finish('unsupported'); });
 106          } catch (e) { finish('unsupported'); }
 107        });
 108        // Safety timeout.
 109        setTimeout(function () { resolve(results); }, 2000);
 110      });
 111    }
 112  
 113    /* ---- async: media devices (counts only, no labels/permission) ---------- */
 114    function getMediaDevices() {
 115      return new Promise(function (resolve) {
 116        if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
 117          resolve({ supported: false }); return;
 118        }
 119        var t = setTimeout(function () { resolve({ supported: true, timeout: true }); }, 1500);
 120        navigator.mediaDevices.enumerateDevices().then(function (list) {
 121          clearTimeout(t);
 122          var counts = { audioinput: 0, audiooutput: 0, videoinput: 0 };
 123          var labelled = 0;
 124          list.forEach(function (d) {
 125            if (counts[d.kind] !== undefined) counts[d.kind]++;
 126            if (d.label) labelled++;
 127          });
 128          resolve({
 129            supported: true,
 130            cameras: counts.videoinput,
 131            microphones: counts.audioinput,
 132            speakers: counts.audiooutput,
 133            total: list.length,
 134            labelsExposed: labelled > 0
 135          });
 136        }).catch(function () { clearTimeout(t); resolve({ supported: true, error: true }); });
 137      });
 138    }
 139  
 140    /* ---- async: storage estimate ------------------------------------------- */
 141    function getStorageEstimate() {
 142      return new Promise(function (resolve) {
 143        if (!navigator.storage || !navigator.storage.estimate) { resolve(null); return; }
 144        var t = setTimeout(function () { resolve(null); }, 1500);
 145        navigator.storage.estimate().then(function (est) {
 146          clearTimeout(t);
 147          resolve({ quota: est.quota || null, usage: est.usage || null });
 148        }).catch(function () { clearTimeout(t); resolve(null); });
 149      });
 150    }
 151  
 152    /* ---- codecs & image formats -------------------------------------------- */
 153    function getCodecs() {
 154      var v = document.createElement('video');
 155      var a = document.createElement('audio');
 156      function can(el, type) {
 157        try { var r = el.canPlayType(type); return r === '' ? 'no' : r; }
 158        catch (e) { return 'no'; }
 159      }
 160      return {
 161        h264:  can(v, 'video/mp4; codecs="avc1.42E01E"'),
 162        hevc:  can(v, 'video/mp4; codecs="hev1.1.6.L93.B0"'),
 163        vp8:   can(v, 'video/webm; codecs="vp8"'),
 164        vp9:   can(v, 'video/webm; codecs="vp9"'),
 165        av1:   can(v, 'video/mp4; codecs="av01.0.05M.08"'),
 166        ogg:   can(v, 'video/ogg; codecs="theora"'),
 167        aac:   can(a, 'audio/mp4; codecs="mp4a.40.2"'),
 168        mp3:   can(a, 'audio/mpeg'),
 169        opus:  can(a, 'audio/webm; codecs="opus"'),
 170        flac:  can(a, 'audio/flac'),
 171        wav:   can(a, 'audio/wav; codecs="1"')
 172      };
 173    }
 174    function getImageFormats() {
 175      function supports(mime) {
 176        try {
 177          var c = document.createElement('canvas');
 178          if (!c.toDataURL) return false;
 179          return c.toDataURL(mime).indexOf('data:' + mime) === 0;
 180        } catch (e) { return false; }
 181      }
 182      return {
 183        webp:  supports('image/webp'),
 184        avif:  supports('image/avif'),
 185        png:   supports('image/png'),
 186        jpeg:  supports('image/jpeg'),
 187        gif:   true // universally supported for display
 188      };
 189    }
 190  
 191    /* ---- font detection (offset-width probe) ------------------------------- */
 192    function detectFonts() {
 193      var baseFonts = ['monospace', 'sans-serif', 'serif'];
 194      var testString = 'mmmmmmmmmmlli';
 195      var testSize = '72px';
 196      var candidates = [
 197        'Arial','Arial Black','Arial Narrow','Calibri','Cambria','Candara','Comic Sans MS',
 198        'Consolas','Courier','Courier New','Georgia','Helvetica','Impact','Lucida Console',
 199        'Lucida Sans Unicode','Microsoft Sans Serif','Palatino Linotype','Segoe UI','Tahoma',
 200        'Times','Times New Roman','Trebuchet MS','Verdana','Webdings','Wingdings','MS Gothic',
 201        'MS PGothic','MS Mincho','SimSun','SimHei','NSimSun','Menlo','Monaco','DejaVu Sans',
 202        'DejaVu Serif','DejaVu Sans Mono','Liberation Sans','Ubuntu','Cantarell','Roboto',
 203        'Noto Sans','Fira Sans','Droid Sans','San Francisco','Apple Color Emoji','Segoe UI Emoji'
 204      ];
 205  
 206      var body = document.body;
 207      var span = document.createElement('span');
 208      span.style.position = 'absolute';
 209      span.style.left = '-9999px';
 210      span.style.top = '-9999px';
 211      span.style.fontSize = testSize;
 212      span.style.lineHeight = 'normal';
 213      span.innerHTML = testString;
 214  
 215      var defaults = {};
 216      var el = {};
 217  
 218      baseFonts.forEach(function (base) {
 219        span.style.fontFamily = base;
 220        body.appendChild(span);
 221        defaults[base] = { w: span.offsetWidth, h: span.offsetHeight };
 222        body.removeChild(span);
 223      });
 224  
 225      function isAvailable(font) {
 226        for (var i = 0; i < baseFonts.length; i++) {
 227          span.style.fontFamily = "'" + font + "'," + baseFonts[i];
 228          body.appendChild(span);
 229          var matched = (span.offsetWidth !== defaults[baseFonts[i]].w ||
 230                         span.offsetHeight !== defaults[baseFonts[i]].h);
 231          body.removeChild(span);
 232          if (matched) return true;
 233        }
 234        return false;
 235      }
 236  
 237      var found = [];
 238      for (var i = 0; i < candidates.length; i++) {
 239        if (isAvailable(candidates[i])) found.push(candidates[i]);
 240      }
 241      return found;
 242    }
 243  
 244    /* ---- WebGL vendor/renderer (unmasked) ---------------------------------- */
 245    function getWebGLInfo() {
 246      var info = { supported: false, webgl2: false, vendor: null, renderer: null,
 247                   version: null, shading: null, maxTexture: null, extensions: 0 };
 248      try {
 249        var canvas = document.createElement('canvas');
 250        var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
 251        if (!gl) return info;
 252        info.supported = true;
 253        info.webgl2 = !!(window.WebGL2RenderingContext && canvas.getContext('webgl2'));
 254        info.version = gl.getParameter(gl.VERSION);
 255        info.shading = gl.getParameter(gl.SHADING_LANGUAGE_VERSION);
 256        info.maxTexture = gl.getParameter(gl.MAX_TEXTURE_SIZE);
 257        var dbg = gl.getExtension('WEBGL_debug_renderer_info');
 258        if (dbg) {
 259          info.vendor = gl.getParameter(dbg.UNMASKED_VENDOR_WEBGL);
 260          info.renderer = gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL);
 261        } else {
 262          info.vendor = gl.getParameter(gl.VENDOR);
 263          info.renderer = gl.getParameter(gl.RENDERER);
 264        }
 265        var ext = gl.getSupportedExtensions();
 266        info.extensions = ext ? ext.length : 0;
 267      } catch (e) {}
 268      return info;
 269    }
 270  
 271    /* ---- WebGPU (async but quick check) ------------------------------------ */
 272    function getWebGPU() {
 273      return new Promise(function (resolve) {
 274        if (!navigator.gpu) { resolve({ supported: false }); return; }
 275        var t = setTimeout(function () { resolve({ supported: true, adapter: null }); }, 1500);
 276        try {
 277          navigator.gpu.requestAdapter().then(function (adapter) {
 278            clearTimeout(t);
 279            if (!adapter) { resolve({ supported: true, adapter: null }); return; }
 280            var out = { supported: true, adapter: 'available' };
 281            if (adapter.info) {
 282              out.vendor = adapter.info.vendor || null;
 283              out.architecture = adapter.info.architecture || null;
 284            }
 285            resolve(out);
 286          }).catch(function () { clearTimeout(t); resolve({ supported: true, adapter: null }); });
 287        } catch (e) { clearTimeout(t); resolve({ supported: true }); }
 288      });
 289    }
 290  
 291    /* ---- network information ----------------------------------------------- */
 292    function getNetwork() {
 293      var c = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
 294      if (!c) return { supported: false };
 295      return {
 296        supported: true,
 297        type: c.type || null,
 298        effectiveType: c.effectiveType || null,
 299        downlink: c.downlink != null ? c.downlink : null,
 300        rtt: c.rtt != null ? c.rtt : null,
 301        saveData: c.saveData === true
 302      };
 303    }
 304  
 305    /* ---- storage / worker feature flags ------------------------------------ */
 306    function testStorageAPIs() {
 307      function localOK() {
 308        try { var k='__t'; localStorage.setItem(k,'1'); localStorage.removeItem(k); return true; }
 309        catch (e) { return false; }
 310      }
 311      function sessionOK() {
 312        try { var k='__t'; sessionStorage.setItem(k,'1'); sessionStorage.removeItem(k); return true; }
 313        catch (e) { return false; }
 314      }
 315      return {
 316        localStorage:    localOK(),
 317        sessionStorage:  sessionOK(),
 318        indexedDB:       has(window, 'indexedDB') && !!window.indexedDB,
 319        cacheAPI:        has(window, 'caches'),
 320        cookiesEnabled:  navigator.cookieEnabled === true,
 321        cookieStore:     has(window, 'cookieStore')
 322      };
 323    }
 324  
 325    /* ==== main ============================================================== */
 326    EYES.detect = function detect() {
 327      var nav = navigator;
 328      var ua = nav.userAgent || '';
 329      var uaInfo = parseUA(ua);
 330  
 331      var screenInfo = {
 332        width: safe(function(){return screen.width;}, null),
 333        height: safe(function(){return screen.height;}, null),
 334        availWidth: safe(function(){return screen.availWidth;}, null),
 335        availHeight: safe(function(){return screen.availHeight;}, null),
 336        colorDepth: safe(function(){return screen.colorDepth;}, null),
 337        pixelDepth: safe(function(){return screen.pixelDepth;}, null),
 338        pixelRatio: safe(function(){return window.devicePixelRatio;}, 1),
 339        orientation: safe(function(){return screen.orientation ? screen.orientation.type : null;}, null),
 340        viewportW: safe(function(){return window.innerWidth;}, null),
 341        viewportH: safe(function(){return window.innerHeight;}, null)
 342      };
 343  
 344      var mm = function (q) { return safe(function(){return window.matchMedia(q).matches;}, null); };
 345  
 346      // Synchronous block first.
 347      var base = {
 348        ua: {
 349          raw: ua,
 350          browser: uaInfo.browser,
 351          version: uaInfo.version,
 352          engine: uaInfo.engine,
 353          os: uaInfo.os,
 354          osVersion: uaInfo.osVersion,
 355          vendor: nav.vendor || '',
 356          product: nav.product || '',
 357          appName: nav.appName || '',
 358          appVersion: nav.appVersion || ''
 359        },
 360        platform: {
 361          platform: nav.platform || 'unknown',
 362          oscpu: nav.oscpu || null,
 363          architecture: safe(function () {
 364            // Guess architecture from UA hints.
 365            if (/x64|x86_64|Win64|WOW64|amd64/i.test(ua)) return '64-bit (x86_64)';
 366            if (/arm64|aarch64/i.test(ua)) return '64-bit (ARM)';
 367            if (/arm/i.test(ua)) return '32-bit (ARM)';
 368            if (/i686|i386|x86/i.test(ua)) return '32-bit (x86)';
 369            return 'unknown';
 370          }, 'unknown'),
 371          cores: nav.hardwareConcurrency || null,
 372          memory: nav.deviceMemory || null,
 373          maxTouchPoints: nav.maxTouchPoints || 0,
 374          languages: nav.languages || [nav.language],
 375          language: nav.language || null,
 376          pdfViewer: nav.pdfViewerEnabled === true,
 377          webdriver: nav.webdriver === true,
 378          online: nav.onLine === true,
 379          doNotTrack: (nav.doNotTrack || window.doNotTrack || nav.msDoNotTrack || null)
 380        },
 381        screen: screenInfo,
 382        preferences: {
 383          darkMode: mm('(prefers-color-scheme: dark)'),
 384          lightMode: mm('(prefers-color-scheme: light)'),
 385          reducedMotion: mm('(prefers-reduced-motion: reduce)'),
 386          reducedData: mm('(prefers-reduced-data: reduce)'),
 387          highContrast: mm('(prefers-contrast: more)'),
 388          forcedColors: mm('(forced-colors: active)'),
 389          touch: (('ontouchstart' in window) || nav.maxTouchPoints > 0),
 390          hover: mm('(hover: hover)'),
 391          pointerFine: mm('(pointer: fine)')
 392        },
 393        time: {
 394          timezone: safe(function(){return Intl.DateTimeFormat().resolvedOptions().timeZone;}, null),
 395          offsetMinutes: new Date().getTimezoneOffset(),
 396          locale: safe(function(){return Intl.DateTimeFormat().resolvedOptions().locale;}, null),
 397          calendar: safe(function(){return Intl.DateTimeFormat().resolvedOptions().calendar;}, null),
 398          numberingSystem: safe(function(){return Intl.DateTimeFormat().resolvedOptions().numberingSystem;}, null)
 399        },
 400        apis: {
 401          cookies: nav.cookieEnabled === true,
 402          clipboard: has(nav, 'clipboard'),
 403          notification: has(window, 'Notification'),
 404          permissions: has(nav, 'permissions'),
 405          geolocation: has(nav, 'geolocation'),
 406          serviceWorker: has(nav, 'serviceWorker'),
 407          sharedWorker: has(window, 'SharedWorker'),
 408          webWorker: has(window, 'Worker'),
 409          broadcastChannel: has(window, 'BroadcastChannel'),
 410          webAssembly: has(window, 'WebAssembly'),
 411          webGPU: has(nav, 'gpu'),
 412          webRTC: has(window, 'RTCPeerConnection') || has(window, 'webkitRTCPeerConnection'),
 413          webSocket: has(window, 'WebSocket'),
 414          webVR: has(nav, 'getVRDisplays'),
 415          webXR: has(nav, 'xr'),
 416          bluetooth: has(nav, 'bluetooth'),
 417          usb: has(nav, 'usb'),
 418          hid: has(nav, 'hid'),
 419          serial: has(nav, 'serial'),
 420          nfc: has(window, 'NDEFReader'),
 421          gamepad: has(nav, 'getGamepads'),
 422          speechRecognition: has(window, 'SpeechRecognition') || has(window, 'webkitSpeechRecognition'),
 423          speechSynthesis: has(window, 'speechSynthesis'),
 424          mediaDevices: has(nav, 'mediaDevices'),
 425          mediaRecorder: has(window, 'MediaRecorder'),
 426          mediaSession: has(nav, 'mediaSession'),
 427          paymentRequest: has(window, 'PaymentRequest'),
 428          credentials: has(nav, 'credentials'),
 429          wakeLock: has(nav, 'wakeLock'),
 430          share: has(nav, 'share'),
 431          contacts: has(nav, 'contacts'),
 432          vibration: has(nav, 'vibrate'),
 433          battery: has(nav, 'getBattery'),
 434          deviceMemory: has(nav, 'deviceMemory'),
 435          virtualKeyboard: has(nav, 'virtualKeyboard'),
 436          ambientLight: has(window, 'AmbientLightSensor'),
 437          accelerometer: has(window, 'Accelerometer'),
 438          gyroscope: has(window, 'Gyroscope'),
 439          magnetometer: has(window, 'Magnetometer'),
 440          idleDetection: has(window, 'IdleDetector'),
 441          fileSystemAccess: has(window, 'showOpenFilePicker'),
 442          eyeDropper: has(window, 'EyeDropper'),
 443          offscreenCanvas: has(window, 'OffscreenCanvas'),
 444          resizeObserver: has(window, 'ResizeObserver'),
 445          intersectionObserver: has(window, 'IntersectionObserver'),
 446          reportingObserver: has(window, 'ReportingObserver'),
 447          performanceMemory: !!(window.performance && performance.memory)
 448        },
 449        storage: testStorageAPIs(),
 450        network: getNetwork(),
 451        webgl: getWebGLInfo(),
 452        codecs: getCodecs(),
 453        imageFormats: getImageFormats(),
 454        audioContext: has(window, 'AudioContext') || has(window, 'webkitAudioContext'),
 455        canvas: (function(){ try { return !!document.createElement('canvas').getContext('2d'); } catch(e){ return false; } })(),
 456        plugins: safe(function () {
 457          var out = [];
 458          if (nav.plugins) for (var i = 0; i < nav.plugins.length; i++) out.push(nav.plugins[i].name);
 459          return out;
 460        }, []),
 461        mimeTypes: safe(function () { return nav.mimeTypes ? nav.mimeTypes.length : 0; }, 0),
 462        jsHeapLimit: safe(function(){ return performance.memory ? performance.memory.jsHeapSizeLimit : null; }, null),
 463        speechVoices: safe(function () {
 464          try { return window.speechSynthesis ? window.speechSynthesis.getVoices().length : 0; }
 465          catch (e) { return 0; }
 466        }, 0)
 467      };
 468  
 469      // Fonts are a little expensive; do them synchronously but guarded.
 470      base.fonts = safe(detectFonts, []);
 471  
 472      // Now the async probes, in parallel.
 473      return Promise.all([
 474        getBattery(),
 475        getPermissions(),
 476        getMediaDevices(),
 477        getStorageEstimate(),
 478        getWebGPU()
 479      ]).then(function (res) {
 480        base.battery       = res[0];
 481        base.permissions   = res[1];
 482        base.mediaDevices  = res[2];
 483        base.storageQuota  = res[3];
 484        base.webgpu        = res[4];
 485        base._collectedAt  = new Date().toISOString();
 486        return base;
 487      });
 488    };
 489  
 490    /* Expose helpers other modules reuse. */
 491    EYES._util = { safe: safe, has: has, yn: yn, parseUA: parseUA };
 492  
 493  })();
 494  

You are reading the real file being executed on the server. What you see is what runs.