PageSourceSearch

https://www.sligro.nl/frontend-client-libraries/analytics/webinit.js

js sligro.nl collected 2026-10-02 06:25:52 UTC 59,654 bytes, 1,255 lines download raw bytes

1// Copyright © Springbok. Sligro is granted a perpetual, irrevocable and royalty-free
2// right to use, host, maintain and modify this First Party Pixel for its business
3// purposes, including after termination of Springbok’s services. Third-party service
4// providers acting on behalf of Sligro may access and manage the code solely to provide
5// services to Sligro. Any other use, reproduction, distribution, reuse or commercial
6// exploitation of this code or derivative works is strictly prohibited.
7
8window.pixel = {
9    // Configuration object
10    configuration: {
11        init_unix_timestamp: Date.now(),
12        last_interaction_unix_timestamp_ms: Date.now(),
13        cookie_value_separator: "--",
14        user_cookie_name: "sfguid",
15        cookie_expiration_milliseconds: 31536000000, // 365 days
16        session_cookie_name: "sfgsid",
17        session_cookie_lifetime_milliseconds: Number(1800000), // 30 min
18        cookie_domain: window.location.hostname.split(/\./).slice(-2).join("."),
19        session_start_trigger: false,
20        session_start_reasons: [],
21        session_start_sent: false,
22        session_start_sent_storage_name: "sfg_session_start_sent",
23        event_id_name: "sfgeid",
24        browser_support_safe_uuid: true,
25        consent_cookie_name: "sfg_consent",
26        cmp_update_handled: false,
27        session_start_handled: false,
28        floodgate_name: "sfg_floodgate_events",
29        floodgate_open: false,
30        session_info_storage_name: "sfg_session_info",
31        // click_ids_cookie_name: configuration.click_ids_cookie_name,
32        // microsoft_ads_tag_id: configuration.microsoft_ads_tag_id,
33        allow_pings: false,
34        blocking_detected: false,
35    },
36
37    // The user manager object
38    user_manager: {
39        is_legacy_user_cookie_format: function (cookie_value) {
40            // Legacy format: U + random digits + "-" + unix timestamp
41            return /^U\d+-\d+$/.test(cookie_value || "");
42        },
43
44        get_legacy_user_cookie_expiration_ms: function (cookie_value) {
45            // Legacy value format: U<random>-<unix_seconds_created>
46            var created_timestamp_seconds = window.pixel.helpers.safe_parse_int((cookie_value || "").split("-")[1]);
47            if (!created_timestamp_seconds) {
48                return 0;
49            }
50            return (created_timestamp_seconds * 1000) + window.pixel.configuration.cookie_expiration_milliseconds;
51        },
52
53        // A function the check if the user cookie is set.
54        user_cookie_exists: function() {
55            var configuration = window.pixel.configuration;
56            return window.pixel.helpers.get_cookie_value(configuration.user_cookie_name) !== null;
57        },
58
59        // A function to check if the user cookie is expired.
60        is_user_cookie_expired: function() {
61            var configuration = window.pixel.configuration;
62
63            if (!window.pixel.user_manager.user_cookie_exists()) {
64                return true;
65            }
66
67            var user_input = window.pixel.helpers.get_cookie_value(configuration.user_cookie_name);
68            if (window.pixel.user_manager.is_legacy_user_cookie_format(user_input)) {
69                var legacy_expiration_ms = window.pixel.user_manager.get_legacy_user_cookie_expiration_ms(user_input);
70                return legacy_expiration_ms === 0 || legacy_expiration_ms < Date.now();
71            }
72            var user_expire = parseInt(user_input.split(configuration.cookie_value_separator)[1]);
73            return new Date(user_expire) < new Date();
74        },
75
76        // A function to set the user cookie.
77        create_user_cookie: function() {
78            var configuration = window.pixel.configuration;
79            var current_user_cookie_value = window.pixel.helpers.get_cookie_value(configuration.user_cookie_name);
80
81            // Preserve existing legacy payload exactly as-is.
82            if (window.pixel.user_manager.is_legacy_user_cookie_format(current_user_cookie_value)) {
83                window.pixel.helpers.set_cookie(
84                    configuration.user_cookie_name,
85                    current_user_cookie_value,
86                    configuration.cookie_expiration_milliseconds,
87                    '/',
88                    configuration.cookie_domain
89                );
90                return current_user_cookie_value;
91            }
92
93            var user_id = window.pixel.helpers.generate_uuid();
94            var cookie_lifetime_milliseconds = configuration.cookie_expiration_milliseconds;
95            var user_expire = new Date().setTime(new Date().getTime() + cookie_lifetime_milliseconds).toString();
96            var user_cookie_value = user_id + configuration.cookie_value_separator + user_expire;
97
98            window.pixel.helpers.set_cookie(configuration.user_cookie_name, user_cookie_value, cookie_lifetime_milliseconds, '/', configuration.cookie_domain);
99            return user_id;
100        },
101
102        // Extend the lifetime of the user cookie.
103        extend_user_cookie_lifetime: function() {
104            var configuration = window.pixel.configuration;
105            var current_user_cookie_value = window.pixel.helpers.get_cookie_value(configuration.user_cookie_name);
106
107            if (window.pixel.user_manager.is_legacy_user_cookie_format(current_user_cookie_value)) {
108                // Preserve legacy cookie payload exactly as-is.
109                window.pixel.helpers.set_cookie(
110                    configuration.user_cookie_name,
111                    current_user_cookie_value,
112                    configuration.cookie_expiration_milliseconds,
113                    '/',
114                    configuration.cookie_domain
115                );
116                return current_user_cookie_value;
117            }
118
119            var user_id = window.pixel.user_manager.get_user_cookie_values()[0];
120
121            var user_expire = new Date().setTime(new Date().getTime() + configuration.cookie_expiration_milliseconds).toString();
122            var user_cookie_value = user_id + configuration.cookie_value_separator + user_expire;
123            window.pixel.helpers.set_cookie(configuration.user_cookie_name, user_cookie_value, configuration.cookie_expiration_milliseconds, '/', configuration.cookie_domain);
124
125            return user_id;
126        },
127
128        get_user_cookie_values: function () {
129        // Return in this order: user id, user expiration time
130        var configuration = window.pixel.configuration;
131        var user_cookie_value = window.pixel.helpers.get_cookie_value(configuration.user_cookie_name);
132        if (user_cookie_value !== null) {
133            if (window.pixel.user_manager.is_legacy_user_cookie_format(user_cookie_value)) {
134                return [user_cookie_value, undefined];
135            }
136            var user_cookie_value_parts = user_cookie_value.split("--");
137            return user_cookie_value_parts;
138        }
139        return [undefined, undefined];
140        },
141    },
142
143    // The session manager object
144    session_manager: {
145        session_cookie_exists: function () {
146        var configuration = window.pixel.configuration;
147
148        return (window.pixel.helpers.get_cookie_value(configuration.session_cookie_name) !== null);
149        },
150
151        is_session_cookie_expired: function () {
152        var configuration = window.pixel.configuration;
153
154        if (!window.pixel.session_manager.session_cookie_exists()) {
155            return true;
156        }
157
158        var session_cookie_value = window.pixel.helpers.get_cookie_value(
159            configuration.session_cookie_name
160        );
161        var session_expiration = parseInt(session_cookie_value.split("--")[1]);
162        return new Date(session_expiration) < new Date();
163        },
164
165        get_session_cookie_values: function () {
166        var configuration = window.pixel.configuration
167        // Return in this order: session id, session expiration time, session start time, session number
168        var session_cookie_value = window.pixel.helpers.get_cookie_value(configuration.session_cookie_name);
169        if (session_cookie_value !== null) {
170            var session_cookie_value_parts = session_cookie_value.split(configuration.cookie_value_separator);
171            return session_cookie_value_parts;
172        }
173        return [undefined, undefined, undefined, undefined];
174        },
175
176        create_session_cookie: function () {
177        window.pixel.helpers.log_debug("Session cookie creation started:", "log");
178        var configuration = window.pixel.configuration;
179        var session_start_timestamp_seconds = Math.floor(Date.now() / 1000);
180
181        // Default value
182        // var session_number = 1;
183        // // If session number exists in the user cookie
184        // var user_cookie_values = window.pixel.user_manager.get_user_cookie_values();
185        // // If only user exists, get it from the user and increment it with 1 (since this function is started to launch a new session)
186        // if (user_cookie_values[1] !== undefined) {
187        //     session_number = window.pixel.helpers.safe_parse_int(user_cookie_values[1]) + 1;
188        // }
189        var session_id = window.pixel.helpers.generate_uuid();
190        var session_expiration = new Date().getTime() + configuration.session_cookie_lifetime_milliseconds;
191        var session_cookie_new_value = session_id + configuration.cookie_value_separator + session_expiration + configuration.cookie_value_separator + session_start_timestamp_seconds;
192
193        // Set the session cookie with the session start time
194        //{session id}--{session expiration}--{session start time}
195        window.pixel.helpers.set_cookie(configuration.session_cookie_name, session_cookie_new_value, configuration.session_cookie_lifetime_milliseconds, "/", window.pixel.helpers.get_cookie_domain(window.location.hostname));
196        
197        // Update the user cookie with the session number variable
198        //{user id}--{session number}
199        // var user_cookie_new_value = user_cookie_values[0] + "--" + session_number;
200        // window.pixel.helpers.set_cookie(configuration.user_cookie_name, user_cookie_new_value, configuration.cookie_expiration_milliseconds, "/", window.pixel.helpers.get_cookie_domain(window.location.hostname));
201        return session_id;
202        },
203
204        extend_session_cookie_lifetime: function () {
205        var configuration = window.pixel.configuration;
206
207        if (!window.pixel.session_manager.session_cookie_exists()) {
208            return undefined;
209        }
210
211        if (window.pixel.session_manager.is_session_cookie_expired()) {
212            return window.pixel.session_manager.create_session_cookie();
213        }
214
215        var session_cookie_values = window.pixel.session_manager.get_session_cookie_values();
216        var new_session_expiration = new Date().getTime() +
217            configuration.session_cookie_lifetime_milliseconds;
218        var updated_session_cookie_value = session_cookie_values[0] +
219            configuration.cookie_value_separator +
220            new_session_expiration +
221            configuration.cookie_value_separator +
222            session_cookie_values[2];
223        window.pixel.helpers.set_cookie(
224            configuration.session_cookie_name,
225            updated_session_cookie_value,
226            configuration.session_cookie_lifetime_milliseconds,
227            "/",
228            window.pixel.helpers.get_cookie_domain(window.location.hostname)
229        );
230
231        return session_cookie_values[0];
232        },
233    },
234
235    // Helper functions
236    helpers: {
237        generate_uuid_non_secure: function () {
238        window.pixel.configuration.browser_support_safe_uuid = false;
239        return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(
240            /[018]/g,
241            function (c) {
242            return (
243                c ^
244                (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
245            ).toString(16);
246            }
247        );
248        },
249        generate_uuid_secure: function () {
250        window.pixel.configuration.browser_support_safe_uuid = true;
251        return crypto.randomUUID();
252        },
253        generate_uuid: function () {
254        try {
255            if (typeof crypto.randomUUID === "function") {
256            return window.pixel.helpers.generate_uuid_secure();
257            } else if (typeof crypto.getRandomValues === "function") {
258            return window.pixel.helpers.generate_uuid_non_secure();
259            }
260        } catch (e) {
261            window.pixel.configuration.browser_support_safe_uuid = false;
262            return (
263            Math.floor(100000000 + Math.random() * 900000000).toString() +
264            "." +
265            new Date().getTime().toString()
266            );
267        }
268
269        return (
270            Math.floor(100000000 + Math.random() * 900000000).toString() +
271            "." +
272            new Date().getTime().toString()
273        );
274        },
275        get_cookie_value: function (cookie_name) {
276        var value = "; " + document.cookie;
277        var parts = value.split("; " + cookie_name + "=");
278
279        if (parts.length == 2) {
280            return parts.pop().split(";").shift();
281        }
282
283        return null;
284        },
285        set_cookie: function (cookie_name, cookie_value, cookie_lifetime_in_milliseconds, cookie_path, cookie_domain) {
286            var cookie_secure = ";secure";
287            var cookie_samesite = "lax";
288
289            var d = new Date();
290            d.setTime(d.getTime() + cookie_lifetime_in_milliseconds);
291            document.cookie = cookie_name + "=" + cookie_value + ";expires=" + d.toUTCString() + ";path=" + cookie_path + ";domain=" + cookie_domain + cookie_secure + ";SameSite=" + cookie_samesite;
292        },
293        get_cookie_domain: function (hostname) {
294            var publicSuffixes = ['co.uk', 'com.au', 'org.uk'];
295            var parts = hostname.split('.');
296
297            for (let i = 0; i < publicSuffixes.length; i++) {
298                var suffix = publicSuffixes[i];
299                if (hostname.endsWith(suffix)) {
300                var suffixParts = suffix.split('.').length;
301                return '.' + parts.slice(-suffixParts - 1).join('.');
302                }
303            }
304            return '.' + parts.slice(-2).join('.');
305        },
306        get_url_parameter_value: function (url_parameter_name) {
307            var urlParams = new URLSearchParams(window.location.search);
308            return urlParams.get(url_parameter_name) || null;
309        },
310        log_debug: function (message, type) {
311            type = type || "log"; // Default parameter handling for ES5 compatibility
312
313            switch (type) {
314            case "log":
315                console.log(message);
316                break;
317            case "warn":
318                console.warn(message);
319                break;
320            case "error":
321                console.error(message);
322                break;
323            default:
324                console.log(message);
325            }
326        },
327        hash: async function (input) {
328        if (!input) {
329            return "";
330        }
331        try {
332            return Array.from(
333            new Uint8Array(
334                await crypto.subtle.digest(
335                "SHA-256",
336                new TextEncoder().encode(input.trim().toLowerCase())
337                )
338            )
339            )
340            .map((b) => b.toString(16).padStart(2, "0"))
341            .join("");
342        } catch (error) {
343            return input;
344        }
345        },
346        safe_parse_float: function (value) {
347            try {
348                if (value === null || typeof value === "undefined") {
349                    return 0;
350                }
351                var parsed = parseFloat(value);
352                if (isNaN(parsed)) {
353                    return 0;
354                }
355                return parsed;
356            } catch (e) {
357                return 0;
358            }
359        },
360        safe_parse_int: function (value) {
361            try {
362                if (value === null || typeof value === "undefined") {
363                    return 0;
364                }
365                var parsed = parseInt(value);
366                if (isNaN(parsed)) {
367                    return 0;
368                }
369                return parsed;
370            } catch (e) {
371                return 0;
372            }
373        },
374        safe_parse_string: function (value) {
375            if (value === null || typeof value === "undefined") {
376                return "";
377            }
378            return String(value);
379        },
380    },
381
382    // All consent management functionality
383    consent_manager: {
384        timeout_consent_listener_updates: function () {
385            // Reset flag after 1.5 seconds
386            setTimeout(function () {
387                window.pixel.configuration.cmp_update_handled = false;
388            }, 1500);
389        },
390
391        retrieve_consent_state: function () {
392            var onetrust_cookie = window.pixel.helpers.get_cookie_value("OptanonConsent");
393            if (onetrust_cookie !== null) {
394                var decoded_onetrust = decodeURIComponent(onetrust_cookie);
395                var groupsMatch = decoded_onetrust.match(/groups=([^;&]+)/);
396                var allow_strictly_necessary = "0", allow_analytical = "0", allow_functional = "0", allow_advertising = "0", allow_social_media = "0", allow_personalization = "0";
397                if (groupsMatch) {
398                    var groups = groupsMatch[1].split(',');
399                    groups.forEach(function (group) {
400                        var parts = group.split(':');
401                        if (parts[0] === "C0001") {
402                            allow_strictly_necessary = parts[1] === "1" ? "1" : "0";
403                        }
404                        if (parts[0] === "C0002") {
405                            allow_analytical = parts[1] === "1" ? "1" : "0";
406                        }
407                        if (parts[0] === "C0003") {
408                            allow_functional = parts[1] === "1" ? "1" : "0";
409                        }
410                        if (parts[0] === "C0004") {
411                            allow_advertising = parts[1] === "1" ? "1" : "0";
412                        }
413                        if (parts[0] === "C0005") {
414                            allow_social_media = parts[1] === "1" ? "1" : "0";
415                        }
416                        if (parts[0] === "C0007") {
417                            allow_personalization = parts[1] === "1" ? "1" : "0";
418                        }
419                    });
420                }
421                return {
422                    ad_storage: allow_advertising,
423                    analytics_storage: allow_analytical,
424                    functionality_storage: allow_strictly_necessary,
425                    personalization_storage: allow_personalization,
426                    security_storage: allow_strictly_necessary,
427                    ad_user_data: allow_advertising,
428                    ad_personalization: allow_personalization,
429                    social_media_storage: allow_social_media
430                }
431            }
432        },
433        
434
435            
436
437        // Initial consent check sequence
438        initial_consent_enforcement: function () {
439            // Start initial consent enforcement
440            window.pixel.helpers.log_debug("Initial consent enforcement triggered!", "log");
441
442            // First check the initial pixel consent cookie value (if available)
443            var pixel_consent_cookie = window.pixel.helpers.get_cookie_value(window.pixel.configuration.consent_cookie_name);
444
445            // Set initial check variables related to consent and system detection
446            var initial_pixel_allow_marketing = false; // pixel itself assumes marketing is not allowed by default
447            window.pixel.configuration.cmp_allow_marketing = false; // pixel assumes marketing is not allowed by default by the CMP
448            window.pixel.configuration.blocking_detected = undefined; // No blocking detected by default
449            window.pixel.helpers.log_debug("Initial consent enforcement cookie value: " + (pixel_consent_cookie || "null"), "log");
450
451            // If the pixel consent cookie is NOT emtpy
452            if (pixel_consent_cookie !== null) {
453                window.pixel.helpers.log_debug("Consent cookie !== to null, so open floodgate.", "log");
454                window.pixel.configuration.floodgate_open = true;
455                try {
456                    // If the value of the initial pixel consent cookie is 1, then this indicates that here is no dynamic loading necessary
457                    initial_pixel_allow_marketing = JSON.parse(decodeURIComponent(pixel_consent_cookie)).allow_marketing === "1";
458                    // If the blocking parameter is detected with a high probability (1), change the check variable to 1 else to 0 (because detection is completed)
459                    if (JSON.parse(decodeURIComponent(pixel_consent_cookie)).b === "1") {
460                        window.pixel.configuration.blocking_detected = "1";
461                    } else if (JSON.parse(decodeURIComponent(pixel_consent_cookie)).b === "0") {
462                        window.pixel.configuration.blocking_detected = "0";
463                    }
464                } catch (parse_error) {
465                    window.pixel.helpers.log_debug("pixel consent cookie parse error:", "log");
466                    window.pixel.helpers.log_debug(parse_error, "log");
467                }
468            }
469
470            /// CMP logic here
471            if (typeof window.pixel.consent_manager.cmp_init === "function") {
472                window.pixel.helpers.log_debug("start cmp init.", "log");
473                window.pixel.consent_manager.cmp_init();
474            }
475
476            // Evaluate floodgate after to trigger the pixel events
477            if (window.pixel.configuration.floodgate_open === true && window.pixel.configuration.cmp_update_handled === true) {
478                window.pixel.helpers.log_debug("Floodgate evaluation triggered from initial consent enforcement.", "log");
479                window.pixel.consent_manager.evaluate_consent_floodgate();
480            }
481
482            return window.pixel.configuration.cmp_allow_marketing;
483        },
484        // Function to evaluate the floodgate status
485        evaluate_consent_floodgate: function () {
486            window.pixel.helpers.log_debug("Start Floodgate evaluation...", "log");
487            // First check if the floodgate is open
488            if (!window.pixel.configuration.floodgate_open) {
489                window.pixel.helpers.log_debug(
490                "Floodgate evaluation stopped. Floodgate closed",
491                "log"
492                );
493                return;
494            }
495
496            // Retrieve floodgate events
497            var floodgate_events = [];
498            if ( typeof sessionStorage !== "undefined" && typeof window.pixel.floodgate_events === "undefined" ) {
499                floodgate_events = JSON.parse(sessionStorage.getItem(window.pixel.configuration.floodgate_name)) || [];
500            } else if (typeof window.pixel.floodgate_events !== "undefined") {
501                floodgate_events = window.pixel.floodgate_events;
502            }
503            window.pixel.helpers.log_debug(
504                "Collected floodgated events: " + floodgate_events.length.toString(),
505                "log"
506            );
507
508            // Store session info if available
509            if (typeof window.pixel.session_info !== "undefined" && typeof sessionStorage !== "undefined") {
510                sessionStorage.setItem(window.pixel.configuration.session_info_storage_name, window.pixel.session_info);
511            }
512
513            // If no floodgate events exist, log and exit
514            if (floodgate_events.length === 0) {
515                window.pixel.helpers.log_debug("No Floodgate events sent", "log");
516                return;
517            }
518
519            // Function to send floodgated events
520            function send_floodgated_events() {
521                window.pixel.helpers.log_debug("Sending floodgated events", "log");
522
523                for (var i = 0; i < floodgate_events.length; i++) {
524                    window.pixel.send_floodgated_event(floodgate_events[i]);
525                }
526
527                // Empty the floodgate to prevent double triggers
528                sessionStorage.removeItem(window.pixel.configuration.floodgate_name);
529                window.pixel.floodgate_events = [];
530            }
531
532            window.pixel.helpers.log_debug(
533                "Evaluation finished with floodgate status: " +
534                window.pixel.configuration.floodgate_open.toString(),
535                "log"
536            );
537
538            if (!window.pixel.user_manager.user_cookie_exists()) {
539                window.pixel.user_manager.create_user_cookie();
540            } else if (window.pixel.user_manager.is_user_cookie_expired()) {
541                window.pixel.user_manager.create_user_cookie();
542            } else {
543                window.pixel.user_manager.extend_user_cookie_lifetime();
544            }
545
546            if (!window.pixel.session_manager.session_cookie_exists()) {
547                window.pixel.session_manager.create_session_cookie();
548            } else if (window.pixel.session_manager.is_session_cookie_expired()) {
549                window.pixel.session_manager.create_session_cookie();
550            } else {
551                window.pixel.session_manager.extend_session_cookie_lifetime();
552            }
553            
554            send_floodgated_events();
555        },
556
557        // Function to manually overwrite the consent settings when no CMP is selected
558        update_consent: function (consent_object) {
559            var configuration = window.pixel.configuration;
560            var pixel_consent_cookie = window.pixel.helpers.get_cookie_value(configuration.consent_cookie_name);
561            if (pixel_consent_cookie !== null) {
562                var current_consent_object = JSON.parse(decodeURIComponent(pixel_consent_cookie));
563                configuration.blocking_detected = "0"; // No blocking detected by default
564                if (JSON.parse(decodeURIComponent(pixel_consent_cookie)).b === "1") {
565                    configuration.blocking_detected = "1";
566                }
567                var updated_consent_object = consent_object;
568                // Add the blocking parameter
569                updated_consent_object.b = configuration.blocking_detected;
570                // Merge new consent values into the current consent object (the current is the one that needs updating)
571                for (var key in updated_consent_object) {
572                    if (updated_consent_object.hasOwnProperty(key) && current_consent_object.hasOwnProperty(key)) {
573                        current_consent_object[key] = updated_consent_object[key].toString();
574                    }
575                }
576                current_consent_object["unix"] = Date.now();
577
578                window.pixel.helpers.set_cookie(configuration.consent_cookie_name, encodeURIComponent(JSON.stringify(current_consent_object)), configuration.cookie_expiration_milliseconds, "/", window.pixel.helpers.get_cookie_domain(window.location.hostname)
579                );
580            }
581        },
582
583        has_explicit_cmp_consent: function(){
584            var has_explicit_consent = false;
585            has_explicit_consent = window.pixel.helpers.get_cookie_value("OptanonConsent") !== null;
586            return has_explicit_consent;
587        }
588    },
589
590    // Send floodgated events
591    send_floodgated_event: function (stored_event) {
592        var configuration = window.pixel.configuration;
593        
594        // Determine the default event endpoint based on hostname
595        if (window.location.hostname.includes("acc") || window.location.hostname.includes("tst") || window.location.hostname.includes("test") || window.location.hostname.includes("sligro-digital") || window.location.hostname.includes("localhost")) {
596            configuration.default_event_endpoint = "https://slgcp-test.sligro-digital.nl/functions/pixel/pixel-retrieve";
597        } else {
598            configuration.default_event_endpoint = "https://slgcp.sligro-digital.nl/functions/pixel/pixel-retrieve";
599        }
600
601        window.pixel.helpers.log_debug("Preparing floodgated event for sending...", "log");
602        var current_stored_event = stored_event;
603        var consent_cookie_value = window.pixel.helpers.get_cookie_value(
604        window.pixel.configuration.consent_cookie_name
605        );
606        var pixel_consent_cookie_value = {};
607        if (consent_cookie_value) {
608            try {
609                pixel_consent_cookie_value = JSON.parse(decodeURIComponent(consent_cookie_value));
610            } catch (e) {
611                window.pixel.helpers.log_debug("Error parsing consent cookie: " + e.message, "error");
612                // handle parse error
613            }
614        }
615        var allow_uid = pixel_consent_cookie_value.allow_uid === "1";
616        var allow_sid = pixel_consent_cookie_value.allow_sid === "1";
617
618        // Apply consent settings on floodgated events
619        if (allow_uid) {
620            if (window.pixel.helpers.get_cookie_value(configuration.user_cookie_name) == null) {
621                window.pixel.user_manager.create_user_cookie();
622            }
623            current_stored_event[configuration.user_cookie_name] = window.pixel.user_manager.get_user_cookie_values()[0];
624        } else {
625            delete current_stored_event[configuration.user_cookie_name];
626        }
627        if (allow_sid) {
628            if (window.pixel.helpers.get_cookie_value(configuration.session_cookie_name) == null) {
629                window.pixel.session_manager.create_session_cookie();
630            }
631            current_stored_event[configuration.session_cookie_name] = window.pixel.session_manager.get_session_cookie_values()[0];
632        } else {
633            delete current_stored_event[configuration.session_cookie_name];
634        }
635        // Overwrite the consent object with the recent change
636        current_stored_event.consent = pixel_consent_cookie_value;
637
638        // Add additional floodgate context which we don't want stored before consent.
639        current_stored_event["screen_height"] = screen.height || "";
640        current_stored_event["screen_width"] = screen.width || "";
641        current_stored_event["user_agent"] = navigator.userAgent || "";
642        current_stored_event["language"] = navigator.language || "";
643        current_stored_event["consent"] = pixel_consent_cookie_value;
644        current_stored_event["consent_state"] = window.pixel.consent_manager.retrieve_consent_state() || undefined;
645        current_stored_event["context"]["floodgated"] = true;
646        current_stored_event["context"]["floodgate_release_unix_timestamp"] = Date.now();
647        // current_stored_event["context"]["session_number"] = window.pixel.user_manager.get_user_cookie_values()[1];
648        current_stored_event["context"]["session_start_time"] = window.pixel.session_manager.get_session_cookie_values()[2];
649        current_stored_event["context"]["engaged_time_ms"] = current_stored_event["event_unix_timestamp"] - configuration.last_interaction_unix_timestamp_ms;
650        configuration.last_interaction_unix_timestamp_ms = current_stored_event["event_unix_timestamp"];
651
652        // Prepare for data sending to API
653        window.pixel.helpers.log_debug("Sending event data to API...", "log");
654        if (navigator.sendBeacon) {
655            navigator.sendBeacon(configuration.default_event_endpoint, JSON.stringify(stored_event));
656            window.pixel.helpers.log_debug("Event sent using sendBeacon", "log");
657        } else {
658            var xmlhttp = new XMLHttpRequest();
659            xmlhttp.open("POST", configuration.default_event_endpoint, true);
660            xmlhttp.setRequestHeader("Content-Type", "application/json");
661            xmlhttp.send(JSON.stringify(stored_event));
662            window.pixel.helpers.log_debug("Event sent using XMLHttpRequest", "log");
663        }
664    },
665
666    // Send event function
667    send_event: function(event_name, context, user, ecommerce, target_params){
668        var configuration = window.pixel.configuration;
669
670        //get core objects
671        var sfg_core_user = user || {};
672        var sfg_core_context = context || {};
673        var sfg_core_ecommerce = ecommerce || {};
674        var sfg_core_target = target_params || {};
675        var _ga = window.pixel.helpers.get_cookie_value("_ga") || undefined;
676
677        //add conditional user params
678        sfg_core_user["fbclid"] = window.pixel.helpers.get_cookie_value("sfgfbclid") || undefined;
679        sfg_core_user["msclkid"] = window.pixel.helpers.get_cookie_value("sfgmsclkid") || undefined;
680        sfg_core_user["fbp"] = window.pixel.helpers.get_cookie_value("fbp") || undefined;
681        sfg_core_user["gclid"] = window.pixel.helpers.get_cookie_value("sfggclid") || undefined;
682        sfg_core_user["ehash"] = window.pixel.helpers.get_cookie_value("sfgehash") || undefined;
683        sfg_core_user["hotjar_id"] = window.pixel.helpers.get_cookie_value("_hjSessionUser_") || undefined; // hotjar session_id not working
684
685        for (var i = 0; i < dataLayer.length; i++) {
686            if (dataLayer[i].logged_in !== undefined && dataLayer[i].logged_in !== null && dataLayer[i].logged_in !== "") {
687                sfg_core_user["logged_in"] = dataLayer[i].logged_in;
688            }
689            if (dataLayer[i].customer_guid !== undefined && dataLayer[i].customer_guid !== null && dataLayer[i].customer_guid !== "") {
690                sfg_core_user["customer_guid"] = dataLayer[i].customer_guid;
691            }
692            if (dataLayer[i].customer_id !== undefined && dataLayer[i].customer_id !== null && dataLayer[i].customer_id !== "") {
693                sfg_core_user["customer_id"] = dataLayer[i].customer_id;
694            }
695            if (dataLayer[i].customer_root_id !== undefined && dataLayer[i].customer_root_id !== null && dataLayer[i].customer_root_id !== "") {
696                sfg_core_user["customer_root_id"] = dataLayer[i].customer_root_id;
697            }
698            if (dataLayer[i].customer_segment !== undefined && dataLayer[i].customer_segment !== null && dataLayer[i].customer_segment !== "") {
699                sfg_core_user["customer_segment"] = dataLayer[i].customer_segment;
700            }
701            if (dataLayer[i].user_bs_location !== undefined && dataLayer[i].user_bs_location !== null && dataLayer[i].user_bs_location !== "") {
702                sfg_core_user["user_bs_location"] = dataLayer[i].user_bs_location;
703            }
704            if (dataLayer[i].user_email_hashed !== undefined && dataLayer[i].user_email_hashed !== null && dataLayer[i].user_email_hashed !== "") {
705                sfg_core_user["user_email_hashed"] = dataLayer[i].user_email_hashed;
706            }
707            if (dataLayer[i].user_zb_location !== undefined && dataLayer[i].user_zb_location !== null && dataLayer[i].user_zb_location !== "") {
708                sfg_core_user["user_zb_location"] = dataLayer[i].user_zb_location;
709            }
710            if (dataLayer[i].user_permissions !== undefined && dataLayer[i].user_permissions !== null) {
711                // Check if user_permissions is a string
712                if (typeof dataLayer[i].user_permissions === "string" && dataLayer[i].user_permissions !== "") {
713                    sfg_core_user["user_permissions"] = dataLayer[i].user_permissions; 
714                }
715                // Check if user_permissions is an array
716                else if (Array.isArray(dataLayer[i].user_permissions) && dataLayer[i].user_permissions.length > 0) {
717                    sfg_core_user["user_permissions"] = dataLayer[i].user_permissions.join("|");
718                }
719                // Check if user_permissions is an object
720                else if (typeof dataLayer[i].user_permissions === "object" && Object.keys(dataLayer[i].user_permissions).length > 0) {
721                    sfg_core_user["user_permissions"] = Object.values(dataLayer[i].user_permissions).join("|"); 
722                }
723            }
724        }
725
726        // Determine the default event endpoint based on hostname
727        if (window.location.hostname.includes("acc") || window.location.hostname.includes("tst") || window.location.hostname.includes("test") || window.location.hostname.includes("sligro-digital") || window.location.hostname.includes("localhost")) {
728            configuration.default_event_endpoint = "https://slgcp-test.sligro-digital.nl/functions/pixel/pixel-retrieve";
729        } else {
730            configuration.default_event_endpoint = "https://slgcp.sligro-digital.nl/functions/pixel/pixel-retrieve";
731        }
732
733        // Construct the event context
734        var event_data = {};
735        var dlObj = (typeof dataLayer !== 'undefined' && dataLayer.length > 0) ? dataLayer[0] : {};
736        event_data[configuration.event_id_name] = window.pixel.helpers.generate_uuid();
737        event_data["event"] = event_name;
738        event_data["event_unix_timestamp"] = Date.now();
739        event_data["timestamp"] = new Date().toISOString();
740        event_data["ga_cid"] = _ga;
741        event_data["context"] = sfg_core_context || {};
742        event_data["location"] = {
743            fullurl: document.location.href || undefined,
744            pathname: document.location.pathname || undefined,
745            query: window.location.search || undefined,
746            hash: window.location.hash || undefined,
747            hostname: window.location.hostname || undefined,
748            protocol: window.location.protocol || undefined,
749            referrer: document.referrer || undefined,
750            title: document.title || undefined,
751            environment: dlObj.environment || "unknown",
752            platform: dlObj.platform || "unknown",
753            platform_country_code: (dlObj.platform_country_code || "unknown").toLowerCase()
754        };
755        event_data["context"]["browser_support_safe_uuid"] = configuration.browser_support_safe_uuid;
756        event_data["context"]["init_unix_timestamp"] = configuration.init_unix_timestamp;
757        // event_data["context"]["session_number"] = window.pixel.user_manager.get_user_cookie_values()[1];
758        event_data["context"]["session_start_time"] = window.pixel.session_manager.get_session_cookie_values()[2];
759        event_data["context"]["engaged_time_ms"] = event_data["event_unix_timestamp"] - configuration.last_interaction_unix_timestamp_ms;
760        event_data["user"] = sfg_core_user || {};
761        event_data["ecommerce"] = sfg_core_ecommerce || {};
762        event_data["target_params"] = sfg_core_target || {};
763
764        // Don't reset the engaged time if the event is a non-interaction event
765        if (event_data["context"].hasOwnProperty("non_interaction") && event_data["context"]["non_interaction"] !== "1") {
766            configuration.last_interaction_unix_timestamp_ms = event_data["event_unix_timestamp"];
767        }
768
769        // If consent cookie is available and floodgate open, handle based on the pixel consent cookie. Otherwise the event will be floodgated later
770        window.pixel.helpers.log_debug("Floodgate open:  " + configuration.floodgate_open.toString(), "log");
771        window.pixel.helpers.log_debug("Consent cookie value:  " + window.pixel.helpers.get_cookie_value(decodeURIComponent(configuration.consent_cookie_name)), "log");
772        window.pixel.helpers.log_debug("User cookie value: " + window.pixel.user_manager.get_user_cookie_values()[0], "log" );
773
774        // Only push events to the pixel API if the floodgates are open! 
775        if (configuration.floodgate_open) {
776            // First check consent information
777            var consent_cookie_value = window.pixel.helpers.get_cookie_value(configuration.consent_cookie_name);
778            var pixel_consent_cookie_value = {};
779            if (consent_cookie_value) {
780                pixel_consent_cookie_value = JSON.parse(decodeURIComponent(consent_cookie_value));
781            }
782            var allow_uid = pixel_consent_cookie_value.allow_uid === "1";
783            var allow_sid = pixel_consent_cookie_value.allow_sid === "1";
784            if (allow_uid) {
785                if (window.pixel.helpers.get_cookie_value(configuration.user_cookie_name) == null) {
786                    window.pixel.user_manager.create_user_cookie();
787                }
788                event_data[configuration.user_cookie_name] = window.pixel.user_manager.get_user_cookie_values()[0];
789            }
790            if (allow_sid) {
791                if (window.pixel.helpers.get_cookie_value(configuration.session_cookie_name) == null) {
792                    window.pixel.session_manager.create_session_cookie();
793                }
794                event_data[configuration.session_cookie_name] = window.pixel.session_manager.get_session_cookie_values()[0];
795            }
796
797            // Add other event-level context
798            event_data["screen_height"] = screen.height || "";
799            event_data["screen_width"] = screen.width || "";
800            event_data["user_agent"] = navigator.userAgent || "";
801            event_data["language"] = navigator.language || "";
802            event_data["consent"] = pixel_consent_cookie_value;
803            event_data["consent_state"] = window.pixel.consent_manager.retrieve_consent_state() || undefined;
804
805            // Trigger the main pixel event
806            window.pixel.helpers.log_debug("Sending event data to API...", "log");
807            if (navigator.sendBeacon) {
808                navigator.sendBeacon(configuration.default_event_endpoint, JSON.stringify(event_data));
809                window.pixel.helpers.log_debug("Event sent using sendBeacon", "log");
810            } else {
811                var xmlhttp = new XMLHttpRequest();
812                xmlhttp.open("POST", configuration.default_event_endpoint, true);
813                xmlhttp.setRequestHeader("Content-Type", "application/json");
814                xmlhttp.send(JSON.stringify(event_data));
815                window.pixel.helpers.log_debug("Event sent using XMLHttpRequest", "log");
816            }
817        }
818        // Floodgate closed, store event behind floodgate and send ping
819        else {
820            window.pixel.helpers.log_debug("Floodgate closed, storing event behind floodgate", "log");
821            if (configuration.allow_pings === true) {
822                //Trigger the ping
823                this.send_ping(event_name, event_data);
824            }
825
826            if (typeof sessionStorage !== "undefined") {
827                //Append to floodgate array in sessionStorage which is persisstent across pages.
828                window.pixel.floodgate_events = JSON.parse(sessionStorage.getItem(configuration.floodgate_name)) || [];
829                window.pixel.floodgate_events.push(event_data);
830                window.pixel.helpers.log_debug("Event floodgated using sessionStorage", "log");
831                sessionStorage.setItem(configuration.floodgate_name, JSON.stringify(window.pixel.floodgate_events));
832            } else {
833                //Append to floodgate array in JS variable which is not persisstent across pages!
834                window.pixel.floodgate_events = window.pixel.floodgate_events || [];
835                window.pixel.floodgate_events.push(event_data);
836                window.pixel.helpers.log_debug("Event floodgated using JS variable", "log");
837            }
838        }
839    },
840
841    // Send anonymous ping function
842    send_ping: function (event_name, event_body) {
843        var configuration = window.pixel.configuration;
844        var ping_url = configuration.default_event_endpoint.replace(/\/?$/, "/") + "ping/";
845        var origin = window.location.href;
846        var referrer = document.referrer;
847
848        // Use sendBeacon if available
849        if (navigator.sendBeacon) {
850        var payload = JSON.stringify({
851            origin: origin,
852            referrer: referrer,
853            event: event_name,
854            id: event_body[configuration.event_id_name],
855        });
856
857        navigator.sendBeacon(ping_url, payload);
858        }
859    },
860
861    // JS session definition logic
862    session_event_logic: function () {
863        var configuration = window.pixel.configuration;
864        window.pixel.helpers.log_debug("Start session logic function", "log");
865
866        // Persisted guard because GTM can inject multiple times per page
867        if (!configuration.session_start_sent && typeof sessionStorage !== "undefined") {
868            configuration.session_start_sent = sessionStorage.getItem(configuration.session_start_sent_storage_name) === "1";
869        }
870
871        function addSessionReason(reason) {
872            if (!configuration.session_start_reasons.includes(reason)) {
873                configuration.session_start_reasons.push(reason);
874            }
875        }
876
877
878        // Reload session exclusion
879        var nav = [];
880        if (typeof performance !== "undefined" && typeof performance.getEntriesByType === "function") {
881            nav = performance.getEntriesByType("navigation");
882        }
883        if (nav.length > 0 && nav[0] && nav[0].type === "reload") {
884            window.pixel.helpers.log_debug("Navigation type is reload, excluding from session start", "log");
885            return;
886        }
887
888        // Payment session exclusions
889        var payment_referrer_exclusions = [
890            "abnamro.nl",
891            "asnbank.nl",
892            "pay.mollie.nl",
893            "mollie.com",
894            "ecommerce-gateway.mollie.com",
895            "paypal.com",
896            "klarna.com",
897            "girogate.be",
898            "snsbank.nl",
899            "rabobank.nl",
900            "knab.nl",
901            "bunq.com",
902            ".ing.nl",
903            "regiobank.nl",
904            "triodos.nl",
905            "vanlanschot.nl",
906            "moneyou.nl",
907            "multisafepay.com",
908            "agone.com",
909            "pay.nl",
910            "sips-atos.com",
911            "curopayments.net",
912            "ideal.nl",
913            "adyen.com",
914            "afterpay.nl",
915            "tikkie.me",
916            "buckaroo.nl",
917            "sisow.nl",
918            "targetpay.com",
919            "paypro.nl",
920            "icepay.nl",
921            "omnikassa.rabobank.nl",
922            "postnl.nl",
923            "billink.nl",
924            "spraypay.nl",
925            "capayable.nl",
926            "in3.nl",
927            "klarna.nl",
928            "vividmoney.nl",
929            "revolut.com",
930            "n26.com",
931            "wise.com",
932            "bancontact.com",
933            "belfius.be",
934            "cbc.be",
935            "kbc.be",
936            ".ing.be",
937            "bnpparibasfortis.be",
938            "keytradebank.be",
939            "argenta.be",
940            "fintro.be",
941            "hellobank.be",
942            "crelan.be",
943            "axabank.be",
944            "recordbank.be",
945            "sofort.com",
946            "stripe.com",
947            "worldline.com",
948            "eps-payment.eu",
949            "ogone.com",
950            "viva.com",
951            "twikey.com",
952            "hipay.com",
953            "payconiq.com",
954            "postfinance.be",
955            "six-payment-services.com",
956        ];
957        var regex_payment = new RegExp(payment_referrer_exclusions.map(function (domain) {
958            return domain.replace(/\./g, "\\.");
959            }).join("|"), "i"
960        );
961
962        if (regex_payment.test(document.referrer)) {
963            return;
964        }
965
966        // Referrer session evaluation
967        if (document.referrer !== "") {
968        var referrerHost = new URL(document.referrer).hostname
969            .split(".")
970            .slice(-2)
971            .join(".");
972        var currentHost = location.hostname.split(".").slice(-2).join(".");
973        if (referrerHost !== currentHost) {
974            configuration.session_start_trigger = true;
975            addSessionReason("new referrer");
976        }
977        } else {
978            configuration.session_start_trigger = true;
979            addSessionReason("no referrer");
980        }
981
982        // UTM session evaluation
983        if (window.location.search.indexOf("utm_") > -1) {
984            configuration.session_start_trigger = true;
985            addSessionReason("utms detected");
986        }
987
988        // Advertising click tracker evaluation
989        var known_advertising_params = [
990            "__hsfp",
991            "__hssc",
992            "__hstc",
993            "__s",
994            "_hsenc",
995            "_openstat",
996            "dclid",
997            "fbclid",
998            "gclid",
999            "hsCtaTracking",
1000            "mc_eid",
1001            "mkt_tok",
1002            "ml_subscriber",
1003            "ml_subscriber_hash",
1004            "msclkid",
1005            "oly_anon_id",
1006            "oly_enc_id",
1007            "rb_clickid",
1008            "s_cid",
1009            "vero_conv",
1010            "vero_id",
1011            "wickedid",
1012            "yclid",
1013            "gbraid",
1014            "scid",
1015            "ttclid",
1016            "li_fat_id",
1017            "cnvsn_id",
1018            "nclid",
1019            "clickid",
1020            "tid",
1021        ];
1022
1023        var detected_advertising_params = [];
1024        var searchParams = window.location.search;
1025
1026        // Check for advertising parameters in the URL
1027        known_advertising_params.forEach(function (param) {
1028        if (searchParams.includes(param)) {
1029            detected_advertising_params.push(param);
1030        }
1031        });
1032        if (detected_advertising_params.length > 0) {
1033            var known_advertising_param_present = detected_advertising_params.length > 0;
1034            window.pixel.helpers.log_debug("Detected params: " + detected_advertising_params.join(","), "log");
1035        }
1036
1037
1038        // Add the context and click ids if they are available
1039        if (known_advertising_param_present && window.location.search.indexOf("_gl") === -1) {
1040            configuration.session_start_trigger = true;
1041            addSessionReason("advertising param detected");
1042            window.pixel.helpers.log_debug("Advertising parameters detected", "log");
1043        }
1044
1045        // Check if a duplicate session start is being triggered (when sessionStorage is available)
1046        var duplicate_session_start = false;
1047        if ( configuration.session_start_trigger && typeof sessionStorage !== "undefined" && configuration.floodgate_open) {
1048            var current_session_info = JSON.stringify({
1049                reasons: configuration.session_start_reasons,
1050                referrer: document.referrer,
1051                search: window.location.search,
1052            });
1053            var previous_session_info = sessionStorage.getItem(configuration.session_info_storage_name);
1054            // Duplicate session_start information detected.
1055            if (current_session_info === previous_session_info) {
1056                duplicate_session_start = true;
1057            } else {
1058                
1059                // Otherwise just add it to the window for later placement
1060                window.pixel.session_info = JSON.stringify({
1061                    reasons: configuration.session_start_reasons,
1062                    referrer: document.referrer,
1063                    search: window.location.search,
1064                });
1065            }
1066        }
1067        // Otherwise just add it to the window for later placement
1068        else {
1069            window.pixel.session_info = JSON.stringify({
1070                reasons: configuration.session_start_reasons,
1071                referrer: document.referrer,
1072                search: window.location.search,
1073            });
1074        }
1075
1076        // No session id exists
1077        if ( window.pixel.helpers.get_cookie_value(configuration.session_cookie_name) === null) {
1078            configuration.session_start_trigger = true;
1079            addSessionReason("no session id");
1080        }
1081
1082        // pixel default session evaluation
1083        if (!duplicate_session_start) {
1084            if (configuration.floodgate_open && configuration.session_start_trigger) {
1085                window.pixel.session_manager.create_session_cookie();
1086            } //else if (window.pixel.configuration.floodgate_open && window.pixel.configuration.session_start_trigger) {
1087                //window.pixel.session_manager.create_session_cookie();
1088            //}
1089            window.pixel.helpers.log_debug(
1090                "Eligible session_start: " + configuration.session_start_trigger.toString(), "log"
1091            );
1092            window.pixel.helpers.log_debug(
1093                "Eligible session_start reasons: " + configuration.session_start_reasons.toString(), "log"
1094            );
1095
1096            if (configuration.session_start_trigger && !configuration.session_start_sent) {
1097                configuration.session_start_trigger = false;
1098                configuration.session_start_sent = true;
1099                if (typeof sessionStorage !== "undefined") {
1100                    sessionStorage.setItem(configuration.session_start_sent_storage_name, "1");
1101                }
1102                window.pixel.send_event("session_start", {
1103                    reason: configuration.session_start_reasons.toString(),
1104                    trigger_type: "front-end",
1105                    }
1106                );
1107            }
1108        }
1109        // Cover the cookie if the session cookie is gone in a duplicate session state
1110        else if ( duplicate_session_start && configuration.session_start_trigger && window.pixel.helpers.get_cookie_value(configuration.session_cookie_name ) === null && configuration.floodgate_open) {
1111            window.pixel.session_manager.create_session_cookie();
1112        }
1113    },
1114};
1115
1116// Onetrust
1117// Create the Onetrust logic initialisation
1118window.pixel.consent_manager.cmp_init = function(){
1119    // Log the selected CMP
1120    window.pixel.helpers.log_debug(
1121        "Initial consent enforcement for: OneTrust",
1122        "log"
1123    );
1124    var onetrust_cookie = window.pixel.helpers.get_cookie_value("OptanonConsent");
1125    if (onetrust_cookie !== null && window.pixel.helpers.get_cookie_value("OptanonAlertBoxClosed")) {
1126        var decoded_onetrust = decodeURIComponent(onetrust_cookie);
1127        var groupsMatch = decoded_onetrust.match(/groups=([^;
1127&]+)/);
1128        var allow_necessary = "0", allow_marketing = "0";
1129
1130        if (groupsMatch) {
1131            var groups = groupsMatch[1].split(',');
1132            groups.forEach(function (group) {
1133                var parts = group.split(':');
1134                if (parts[0] === "C0001") {
1135                    allow_necessary = parts[1] === "1" ? "1" : "0";
1136                }
1137                if (parts[0] === "C0007" || parts[0] === "C0003") {
1138                    allow_marketing = parts[1] === "1" ? "1" : "0";
1139                    // Set the marketing pixel cookie value for dynamic loading of destinations
1140                    window.pixel.configuration.cmp_allow_marketing = parts[1] === "1";
1141                }
1142            });
1143        }
1144
1145        // Persist consent signal even if groups are missing/unexpected.
1146        var encoded_value_based_on_onetrust = encodeURIComponent(JSON.stringify({
1147            "allow_marketing": allow_marketing,
1148            "allow_pii": allow_marketing,
1149            "allow_uid": allow_necessary,
1150            "allow_sid": allow_necessary,
1151            "b": window.pixel.configuration.blocking_detected,
1152            "unix": Date.now()
1153        }));
1154        window.pixel.helpers.set_cookie(
1155            window.pixel.configuration.consent_cookie_name,
1156            encoded_value_based_on_onetrust,
1157            window.pixel.configuration.cookie_expiration_milliseconds,
1158            "/",
1159            window.pixel.helpers.get_cookie_domain(window.location.hostname)
1160        );
1161        window.pixel.configuration.floodgate_open = true;
1162        window.pixel.configuration.cmp_update_handled = true;
1163    }
1164    window.pixel.consent_manager.cmp_update_listener("OneTrustGroupsUpdated", document);
1165};
1166
1167// Function that adds event listeners for the chosen CMP
1168window.pixel.consent_manager.cmp_update_listener = function(cmp_update_trigger, context) {
1169    window.pixel.helpers.log_debug(("Add listener for consent update: " + cmp_update_trigger + context.toString()), "log");
1170    context.addEventListener(cmp_update_trigger, function () {
1171        // Check current status of consent cookie
1172        var pixel_consent_cookie = window.pixel.helpers.get_cookie_value(window.pixel.configuration.consent_cookie_name);
1173        window.pixel.helpers.log_debug(("Event listener triggered with pixel consent cookie value: " + (pixel_consent_cookie || "null")), "log");
1174
1175        // CMP update is already handled, if so, exit this function 
1176        if (window.pixel.configuration.cmp_update_handled) {
1177            // Extend timeout
1178            window.pixel.consent_manager.timeout_consent_listener_updates();
1179            return;
1180        }
1181
1182        // update pixel consent cookie
1183        window.pixel.helpers.log_debug("Trigger the initial consent enforcement after CMP update event listener", "log");
1184        window.pixel.consent_manager.initial_consent_enforcement();
1185    });
1186};
1187
1188// Check CMP consent status
1189window.pixel.consent_manager.has_explicit_cmp_consent = function(){
1190    var has_explicit_consent = false;
1191    has_explicit_consent = window.pixel.helpers.get_cookie_value("OptanonConsent") !== null;
1192    return has_explicit_consent;
1193};
1194
1195// Click listener for click events
1196window.pixel.click_listener = function(){
1197    document.addEventListener("click", function(event){
1198        window.pixel.configuration.last_interaction_unix_timestamp_ms = Date.now();
1199
1200        // Find the closest anchor element
1201        var link = event.target.closest ? event.target.closest('a') : null;
1202        if (link && link.href) {
1203            var classes = link.className.split(' ').join(', '); // Convert classes to a comma-separated string
1204            window.pixel.send_event("link_click", {
1205                href: link.href,
1206                text: link.innerText,
1207                id: link.id,
1208                classes: classes,
1209                target: link.target,
1210                isDifferentHostname: link.hostname !== window.location.hostname
1211            });
1212        }
1213    });
1214}();
1215
1216// Initialization
1217window.pixel.initialisation_sequence = function(){
1218    // Check if the user id cookie exists
1219    if (window.pixel.helpers.get_cookie_value(window.pixel.configuration.user_cookie_name) === null) {
1220        // Check if consent is already provided, but only pixel is not initialized properly yet
1221        var has_explicit_cmp_consent = window.pixel.consent_manager.has_explicit_cmp_consent(window.pixel.configuration.cmp_selection);
1222        if(has_explicit_cmp_consent){
1223            // Do nothing, cmp consent is present by default
1224
1225            // window.pixel.helpers.log_debug("Explicit CMP consent found but no user id, so set user cookie", "log");
1226            // window.pixel.user_manager.create_user_cookie();
1227            // window.pixel.consent_manager.initial_consent_enforcement();
1228            // window.pixel.session_event_logic();
1229        }
1230        
1231        // pixel is not initialized yet, there is no user id and no permission for placement before consent. There is also no explicit consent found for the CMP yet. Floodgate everything
1232        else {
1233            window.pixel.session_event_logic();
1234            window.pixel.consent_manager.initial_consent_enforcement();
1235            // window.pixel.session_event_logic();
1236        }
1237    }
1238    else {
1239        window.pixel.session_event_logic();
1240        window.pixel.consent_manager.initial_consent_enforcement();
1241        // window.pixel.consent_manager.evaluate_consent_floodgate();
1242        // window.pixel.session_event_logic();
1243    }
1244};
1245
1246window.pixel.initialisation_sequence();
1247
1248window.pixel_event = function(event_name, context, user, ecommerce, target_params){
1249    try {
1250        window.pixel.consent_manager.initial_consent_enforcement();
1251        window.pixel.send_event(event_name, context, user, ecommerce, target_params)
1252    } catch (error) {
1253        console.error("Error sending event:", error.message);
1254    }
1255}

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.