PageSourceSearch

https://loaderr.to/js/ga-download-tracking.js

js loaderr.to collected 2026-10-08 07:39:34 UTC 9,670 bytes, 334 lines download raw bytes

1(function (window, document) {
2    "use strict";
3
4    var sessionId =
5        Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 10);
6    var seen = {};
7    var funnelSeen = {};
8    var backendOperations = {};
9    var blockedParamKeys = {
10        url: true,
11        href: true,
12        ip: true,
13        email: true,
14        user_agent: true,
15        userAgent: true,
16        attemptedUrl: true,
17        attempted_url: true,
18        link: true,
19        selected_domain: true,
20    };
21    var funnelEvents = {
22        ad_eligible: true,
23        ad_impression: true,
24        start: true,
25        ready: true,
26        api_response: true,
27        download_started: true,
28        completed: true,
29    };
30
31    function hasAnalytics() {
32        return typeof window.gtag === "function" || typeof window.ga === "function";
33    }
34
35    function normalize(value, fallback) {
36        if (value === undefined || value === null || value === "") {
37            return fallback || "unknown";
38        }
39
40        return String(value).slice(0, 100);
41    }
42
43    function isValidOperationId(value) {
44        return typeof value === "string" && /^[a-f0-9]{32}$/.test(value);
45    }
46
47    function beginOperation() {
48        if (!window.crypto || typeof window.crypto.getRandomValues !== "function") {
49            return null;
50        }
51
52        var bytes = new Uint8Array(16);
53        window.crypto.getRandomValues(bytes);
54        var hex = "";
55        var index;
56
57        for (index = 0; index < bytes.length; index += 1) {
58            hex += ("0" + bytes[index].toString(16)).slice(-2);
59        }
60
61        return hex;
62    }
63
64    function bindBackendId(operationId, backendId) {
65        if (!isValidOperationId(operationId) || backendId === undefined || backendId === null || backendId === "") {
66            return;
67        }
68
69        backendOperations[String(backendId)] = operationId;
70    }
71
72    function resolveOperationId(params) {
73        params = params || {};
74
75        if (isValidOperationId(params.operation_id)) {
76            return params.operation_id;
77        }
78
79        if (params.download_id !== undefined && backendOperations[String(params.download_id)]) {
80            return backendOperations[String(params.download_id)];
81        }
82
83        return null;
84    }
85
86    function getHost(url) {
87        try {
88            return new URL(url).hostname || "unknown";
89        } catch (e) {
90            return "unknown";
91        }
92    }
93
94    function detectSource(url) {
95        var host = getHost(url).replace(/^www\./, "");
96
97        if (host.indexOf("youtu.be") > -1 || host.indexOf("youtube.com") > -1) {
98            return "youtube";
99        }
100
101        if (host.indexOf("soundcloud.com") > -1) {
102            return "soundcloud";
103        }
104
105        if (host.indexOf("tiktok.com") > -1) {
106            return "tiktok";
107        }
108
109        if (host.indexOf("vimeo.com") > -1) {
110            return "vimeo";
111        }
112
113        return host || "unknown";
114    }
115
116    function detectUrlType(url) {
117        if (!url) {
118            return "unknown";
119        }
120
121        if (url.indexOf("list=") > -1 || url.indexOf("/playlist") > -1) {
122            return "playlist";
123        }
124
125        return "single";
126    }
127
128    function trafficSource() {
129        var params = new URLSearchParams(window.location.search);
130        var campaignSource = params.get("utm_source");
131
132        if (campaignSource) {
133            return normalize(campaignSource);
134        }
135
136        return getHost(document.referrer || "direct").replace(/^www\./, "") || "direct";
137    }
138
139    function deviceType() {
140        var userAgent = navigator.userAgent || "";
141
142        if (/Tablet|iPad/i.test(userAgent)) {
143            return "tablet";
144        }
145
146        if (/Android|Mobile|iPhone|iPod/i.test(userAgent)) {
147            return "mobile";
148        }
149
150        return "desktop";
151    }
152
153    function eventName(name) {
154        return "download_" + name;
155    }
156
157    function attribution(params) {
158        params = params || {};
159
160        return {
161            download_session_id: sessionId,
162            download_id: normalize(params.download_id),
163            download_format: normalize(params.format),
164            download_quality: normalize(params.quality || params.format),
165            download_source: normalize(params.source || detectSource(params.url)),
166            download_url_type: normalize(params.url_type || detectUrlType(params.url)),
167            traffic_source: trafficSource(),
168            page_path: window.location.pathname,
169            page_host: window.location.hostname,
170            page_language: normalize(document.documentElement.lang || "unknown"),
171            device_type: deviceType(),
172            download_trigger: normalize(params.trigger),
173            download_status: normalize(params.status),
174            ad_eligible: params.ad_eligible === undefined ? undefined : Boolean(params.ad_eligible),
175            ad_provider: normalize(params.ad_provider),
176            ad_placement: normalize(params.ad_placement),
177        };
178    }
179
180    function beaconFunnel(name, params, attrs) {
181        if (!funnelEvents[name]) {
182            return;
183        }
184
185        var operationId = resolveOperationId(params);
186        var funnelKey = (operationId || sessionId) + ":" + name;
187
188        if (funnelSeen[funnelKey]) {
189            return;
190        }
191
192        funnelSeen[funnelKey] = true;
193
194        var payload = {
195            event: name,
196            download_session_id: sessionId,
197            source: attrs.download_source,
198            traffic_source: attrs.traffic_source,
199            page_host: attrs.page_host,
200            page_path: attrs.page_path,
201            language: attrs.page_language,
202            device: attrs.device_type,
203            format: attrs.download_format,
204            status: attrs.download_status,
205        };
206
207        if (operationId) {
208            payload.contract_version = 2;
209            payload.operation_id = operationId;
210        } else if (attrs.download_id && attrs.download_id !== "unknown") {
211            payload.download_id = attrs.download_id;
212        }
213
214        if (params.ad_eligible !== undefined) {
215            payload.ad_eligible = Boolean(params.ad_eligible);
216        }
217
218        try {
219            var body = JSON.stringify(payload);
220            var queued = false;
221
222            if (typeof navigator.sendBeacon === "function") {
223                queued = navigator.sendBeacon(
224                    "/api/analytics/ad-download-funnel",
225                    new Blob([body], { type: "application/json" })
226                );
227            }
228
229            if (queued) {
230                return;
231            }
232
233            fetch("/api/analytics/ad-download-funnel", {
234                method: "POST",
235                headers: {
236                    Accept: "application/json",
237                    "Content-Type": "application/json",
238                },
239                body: body,
240                keepalive: true,
241            }).catch(function () {});
242        } catch (e) {}
243    }
244
245    function send(name, params) {
246        params = params || {};
247
248        var attrs = attribution(params);
249        var payload = {
250            event_category: "Download",
251            event_label: normalize(params.label || params.format || params.download_id),
252            value: params.value || 1,
253        };
254
255        Object.keys(attrs).forEach(function (key) {
256            if (attrs[key] !== undefined) {
257                payload[key] = attrs[key];
258            }
259        });
260
261        Object.keys(params).forEach(function (key) {
262            if (
263                payload[key] === undefined &&
264                params[key] !== undefined &&
265                params[key] !== null &&
266                !blockedParamKeys[key]
267            ) {
268                payload[key] = String(params[key]).slice(0, 100);
269            }
270        });
271
272        beaconFunnel(name, params, attrs);
273
274        if (!hasAnalytics()) {
275            return;
276        }
277
278        if (typeof window.gtag === "function") {
279            window.gtag("event", eventName(name), payload);
280            return;
281        }
282
283        if (typeof window.ga === "function") {
284            window.ga("send", "event", "Download", eventName(name), payload.event_label);
285        }
286    }
287
288    function once(key, name, params) {
289        if (seen[key]) {
290            return;
291        }
292
293        seen[key] = true;
294        send(name, params);
295    }
296
297    window.DownloadAnalytics = {
298        send: send,
299        once: once,
300        source: detectSource,
301        urlType: detectUrlType,
302        beginOperation: beginOperation,
303        bindBackendId: bindBackendId,
304        resolveOperationId: resolveOperationId,
305    };
306
307    window.trackDownloadEvent = send;
308
309    document.addEventListener(
310        "click",
311        function (event) {
312            var target = event.target;
313            while (target && target !== document) {
314                if (target.tagName === "A" && target.href) {
315                    var id = target.id || "";
316                    if (
317                        id.indexOf("download") > -1 ||
318                        target.hasAttribute("download") ||
319                        target.className.indexOf("btn-download") > -1
320                    ) {
321                        send("link_click", {
322                            download_id: id.replace(/(_downloadLink|download_|card-downloadButton_)/g, ""),
323                            trigger: "result_link",
324                            status: target.className.indexOf("disabled") > -1 ? "disabled" : "enabled",
325                        });
326                    }
327                    return;
328                }
329                target = target.parentNode;
330            }
331        },
332        true
333    );
334})(window, document);

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.