PageSourceSearch

https://imkby.gr/custom/imkby-admin/tracker.js?v=6ab4b432

js imkby.gr collected 2026-09-25 01:31:02 UTC 6,693 bytes, 188 lines download raw bytes

1/**
2 * IMKBY Stats Tracker
3 * Συλλέγει anonymous στατιστικά επισκέψεων.
4 * Δεν χρησιμοποιεί cookies. Χρησιμοποιεί localStorage για visitor_hash.
5 */
6(function() {
7    'use strict';
8
9    // Find own script tag to get collect endpoint
10    var script = document.currentScript;
11    if (!script) {
12        var scripts = document.getElementsByTagName('script');
13        for (var i = scripts.length - 1; i >= 0; i--) {
14            if (scripts[i].src && scripts[i].src.indexOf('tracker.js') !== -1) {
15                script = scripts[i];
16                break;
17            }
18        }
19    }
20    if (!script) return;
21
22    var collectUrl = script.getAttribute('data-collect');
23    if (!collectUrl) {
24        // Default: same dir
25        collectUrl = script.src.replace(/tracker\.js.*/, 'collect.php');
26    }
27
28    // Don't track admin / preview pages
29    if (location.pathname.indexOf('/administrator') !== -1) return;
30    if (location.search.indexOf('tmpl=component') !== -1) return;
31
32    // ===== Bot detection (basic) =====
33    var ua = navigator.userAgent || '';
34    var botPattern = /bot|crawl|spider|slurp|search|fetch|monitor|preview|headless|phantom|selenium|playwright|puppeteer|lighthouse|pagespeed|gtmetrix|pingdom/i;
35    var isBot = botPattern.test(ua);
36
37    // ===== Visitor identification =====
38    // localStorage-based persistent visitor hash (per-browser)
39    var visitorHash;
40    try {
41        visitorHash = localStorage.getItem('_uss_v');
42        if (!visitorHash) {
43            visitorHash = generateHash();
44            localStorage.setItem('_uss_v', visitorHash);
45        }
46    } catch (e) {
47        visitorHash = generateHash();
48    }
49
50    // sessionStorage-based session hash (per-tab session)
51    var sessionHash;
52    try {
53        sessionHash = sessionStorage.getItem('_uss_s');
54        if (!sessionHash) {
55            sessionHash = generateHash();
56            sessionStorage.setItem('_uss_s', sessionHash);
57        }
58    } catch (e) {
59        sessionHash = generateHash();
60    }
61
62    function generateHash() {
63        var s = '';
64        var chars = 'abcdef0123456789';
65        for (var i = 0; i < 32; i++) {
66            s += chars[Math.floor(Math.random() * chars.length)];
67        }
68        return s + Date.now().toString(16);
69    }
70
71    // ===== Browser & device detection =====
72    function detectBrowser() {
73        var b = { name: 'Unknown', version: '' };
74        if (/Edg\//.test(ua)) { b.name = 'Edge'; b.version = (ua.match(/Edg\/([\d.]+)/) || [])[1] || ''; }
75        else if (/OPR\//.test(ua)) { b.name = 'Opera'; b.version = (ua.match(/OPR\/([\d.]+)/) || [])[1] || ''; }
76        else if (/Chrome\//.test(ua)) { b.name = 'Chrome'; b.version = (ua.match(/Chrome\/([\d.]+)/) || [])[1] || ''; }
77        else if (/Safari\//.test(ua)) { b.name = 'Safari'; b.version = (ua.match(/Version\/([\d.]+)/) || [])[1] || ''; }
78        else if (/Firefox\//.test(ua)) { b.name = 'Firefox'; b.version = (ua.match(/Firefox\/([\d.]+)/) || [])[1] || ''; }
79        return b;
80    }
81
82    function detectOS() {
83        if (/Windows NT 10/.test(ua)) return 'Windows 10/11';
84        if (/Windows NT 6\.3/.test(ua)) return 'Windows 8.1';
85        if (/Windows NT 6\.2/.test(ua)) return 'Windows 8';
86        if (/Windows NT 6\.1/.test(ua)) return 'Windows 7';
87        if (/Windows/.test(ua)) return 'Windows';
88        if (/iPhone|iPad/.test(ua)) return 'iOS';
89        if (/Macintosh|Mac OS/.test(ua)) return 'macOS';
90        if (/Android/.test(ua)) return 'Android';
91        if (/Linux/.test(ua)) return 'Linux';
92        return 'Unknown';
93    }
94
95    function detectDevice() {
96        if (/Mobile|iPhone|iPod/.test(ua)) return 'mobile';
97        if (/Tablet|iPad/.test(ua)) return 'tablet';
98        return 'desktop';
99    }
100
101    var browser = detectBrowser();
102
103    // ===== Build payload =====
104    var payload = {
105        visitor_hash: visitorHash,
106        session_hash: sessionHash,
107        url: location.href,
108        path: location.pathname,
109        query: location.search.substring(0, 500),
110        referrer: document.referrer.substring(0, 500),
111        user_agent: ua.substring(0, 500),
112        browser: browser.name,
113        browser_version: browser.version.substring(0, 30),
114        os: detectOS(),
115        device_type: detectDevice(),
116        screen_w: screen.width,
117        screen_h: screen.height,
118        viewport_w: window.innerWidth,
119        viewport_h: window.innerHeight,
120        language: navigator.language || '',
121        is_bot: isBot ? 1 : 0,
122        is_new_visitor: !localStorage.getItem('_uss_returning') ? 1 : 0,
123        timestamp: Date.now()
124    };
125
126    // Mark as returning visitor for next time
127    try { localStorage.setItem('_uss_returning', '1'); } catch (e) {}
128
129    // ===== Send beacon =====
130    function send(data) {
131        var json = JSON.stringify(data);
132        // Prefer sendBeacon (works on page unload too)
133        if (navigator.sendBeacon) {
134            try {
135                var blob = new Blob([json], { type: 'application/json' });
136                if (navigator.sendBeacon(collectUrl, blob)) return;
137            } catch (e) {}
138        }
139        // Fallback to fetch (keepalive)
140        if (window.fetch) {
141            try {
142                fetch(collectUrl, {
143                    method: 'POST',
144                    headers: { 'Content-Type': 'application/json' },
145                    body: json,
146                    keepalive: true,
147                    credentials: 'omit'
148                }).catch(function() {});
149                return;
150            } catch (e) {}
151        }
152        // Last resort: image pixel
153        try {
154            var img = new Image();
155            img.src = collectUrl + '?p=' + encodeURIComponent(json);
156        } catch (e) {}
157    }
158
159    // ===== Track time on page =====
160    var pageStart = Date.now();
161    function sendFinal() {
162        payload.duration_ms = Date.now() - pageStart;
163        send(payload);
164    }
165
166    // Send initial pageview (without duration)
167    send(payload);
168
169    // Send final on unload (with duration)
170    window.addEventListener('beforeunload', sendFinal);
171    window.addEventListener('pagehide', sendFinal);
172
173    // Also send search query if this looks like a search page
174    var searchQuery = '';
175    var params = new URLSearchParams(location.search);
176    ['searchword', 'q', 'search', 's', 'query'].forEach(function(key) {
177        if (params.get(key)) searchQuery = params.get(key);
178    });
179    if (searchQuery) {
180        send({
181            type: 'search',
182            query: searchQuery.substring(0, 200),
183            path: location.pathname,
184            visitor_hash: visitorHash,
185            session_hash: sessionHash
186        });
187    }
188})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.