PageSourceSearch

https://in2itcosmetics.com/wp-content/plugins/pixelyoursite/dist/scripts/public.js?ver=11.1.3

js in2itcosmetics.com collected 2026-10-08 12:33:35 UTC 155,047 bytes, 3,698 lines download raw bytes

1/* global pysOptions */
2
3
4! function ($, options) {
5    if (options.debug) {
6        console.log('PYS:', options);
7    }
8    var uniqueId = {};
9
10    let gtm_variables = {};
11    let gtm_datalayername = "dynamicVariable";
12
13    var domain = '';
14    if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) {
15        domain = getRootDomain(true);
16    }
17
18    var dummyPinterest = function () {
19
20        /**
21         * Public API
22         */
23        return {
24            isEnabled: function () {},
25            disable: function () {},
26            loadPixel: function () {},
27            fireEvent: function (name, data) {
28                return false;
29            },
30            onCommentEvent: function () {},
31            onDownloadEvent: function (params) {},
32            onFormEvent: function (params) {},
33            onWooAddToCartOnButtonEvent: function (product_id) {},
34            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {},
35            onWooRemoveFromCartEvent: function (cart_item_hash) {},
36            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
37            onEddRemoveFromCartEvent: function (item) {},
38            onPageScroll: function (event) {},
39            onTime: function (event) {},
40
41        }
42
43    }();
44
45    var dummyBing = function () {
46
47        /**
48         * Public API
49         */
50        return {
51            isEnabled: function () {},
52            disable: function () {},
53            loadPixel: function () {},
54            fireEvent: function (name, data) {
55                return false;
56            },
57            onAdSenseEvent: function () {},
58            onClickEvent: function (params) {},
59            onWatchVideo: function (params) {},
60            onCommentEvent: function () {},
61            onFormEvent: function (params) {},
62            onDownloadEvent: function (params) {},
63            onWooAddToCartOnButtonEvent: function (product_id) {},
64            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {},
65            onWooRemoveFromCartEvent: function (cart_item_hash) {},
66            onWooAffiliateEvent: function (product_id) {},
67            onWooPayPalEvent: function () {},
68            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
69            onEddRemoveFromCartEvent: function (item) {},
70            onPageScroll: function (event) {},
71            onTime: function (event) {},
72        }
73
74    }();
75
76    var Utils = function (options) {
77
78        var Pinterest = dummyPinterest;
79
80        var Bing = dummyBing;
81
82        var gtag_loaded = false;
83
84        var gtm_loaded = false;
85
86        let isNewSession = checkSession();
87
88        var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
89
90        var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
91
92        let dataLayerName = 'dataLayerPYS';
93
94        let GTMdataLayerName = 'dataLayer';
95
96        function validateEmail(email) {
97            var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
98            return re.test(email);
99        }
100        function getDomain(url) {
101
102            url = url.replace(/(https?:\/\/)?(www.)?/i, '');
103
104            if (url.indexOf('/') !== -1) {
105                return url.split('/')[0];
106            }
107
108            return url;
109        }
110        function loadPixels() {
111
112            if (!options.gdpr.all_disabled_by_api) {
113
114                if (!options.gdpr.facebook_disabled_by_api) {
115                    Facebook.loadPixel();
116                }
117
118                if (!options.gdpr.analytics_disabled_by_api) {
119                    Analytics.loadPixel();
120                }
121
122                if (!options.gdpr.analytics_disabled_by_api) {
123                    GTM.loadPixel();
124                }
125
126                if (!options.gdpr.pinterest_disabled_by_api) {
127                    Pinterest.loadPixel();
128                }
129
130                if (!options.gdpr.bing_disabled_by_api) {
131                    Bing.loadPixel();
132                }
133            }
134            if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
135                if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
136                    Analytics.loadPixel();
137                }
138            }
139
140        }
141
142        function checkSession() {
143            if( Cookies.get('pys_start_session') === undefined ||
144                Cookies.get('pys_session_limit') === undefined) {
145                firstVisit = true;
146                return true
147            }
148            return false
149
150        }
151
152        function getTrafficSource() {
153
154            try {
155
156                let referrer = document.referrer.toString(),
157                    source;
158
159                let direct = referrer.length === 0;
160                let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
161                let external = !direct && !internal;
162
163                if (external === false) {
164                    source = 'direct';
165                } else {
166                    source = referrer;
167                }
168
169                if (source !== 'direct') {
170                    // leave only domain (Issue #70)
171                    return getDomain(source);
172                } else {
173                    return source;
174                }
175
176            } catch (e) {
177                console.error(e);
178                return 'direct';
179            }
180
181        }
182
183        /**
184         * Return query variables object with where property name is query variable
185         * and property value is query variable value.
186         */
187        function getQueryVars() {
188
189            try {
190
191                var result = {},
192                    tmp = [];
193
194                window.location.search
195                    .substr(1)
196                    .split("&")
197                    .forEach(function (item) {
198
199                        tmp = item.split('=');
200
201                        if (tmp.length > 1) {
202                            result[tmp[0]] = tmp[1];
203                        }
204
205                    });
206
207                return result;
208
209            } catch (e) {
210                console.error(e);
211                return {};
212            }
213
214        }
215
216
217        function getLandingPageValue() {
218            let name = "pys_landing_page"
219            if(options.visit_data_model === "last_visit") {
220                name = "last_pys_landing_page"
221            }
222            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
223                return Cookies.get(name);
224            }
225            else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){
226                return options.tracking_analytics.TrafficLanding;
227            } else{
228                return "";
229            }
230        }
231        function getTrafficSourceValue() {
232            let name = "pysTrafficSource"
233            if(options.visit_data_model === "last_visit") {
234                name = "last_pysTrafficSource"
235            }
236            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
237                return Cookies.get(name);
238            }
239            else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficSource){
240                return options.tracking_analytics.TrafficSource;
241            } else{
242                return "";
243            }
244        }
245
246        function getUTMId(useLast = false) {
247            try {
248                let cookiePrefix = 'pys_'
249                let terms = [];
250                if (useLast) {
251                    cookiePrefix = 'last_pys_'
252                }
253                $.each(utmId, function (index, name) {
254                    if (Cookies.get(cookiePrefix + name)) {
255                        terms[name] = Cookies.get(cookiePrefix + name)
256                    }
257                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) {
258                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name])
259                    }
260                });
261                return terms;
262            } catch (e) {
263                console.error(e);
264                return [];
265            }
266        }
267        /**
268         * Return UTM terms from request query variables or from cookies.
269         */
270        function getUTMs(useLast = false) {
271
272            try {
273                let cookiePrefix = 'pys_'
274                if(useLast) {
275                    cookiePrefix = 'last_pys_'
276                }
277                let terms = [];
278                $.each(utmTerms, function (index, name) {
279                    if (Cookies.get(cookiePrefix + name)) {
280                        let value = Cookies.get(cookiePrefix + name);
281                        terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
282                    }
283                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) {
284                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name])
285                    }
286                });
287
288                return terms;
289
290            } catch (e) {
291                console.error(e);
292                return [];
293            }
294
295        }
296
297        function getDateTime() {
298            var dateTime = new Array();
299            var date = new Date(),
300                days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
301                months = ['January', 'February', 'March', 'April', 'May', 'June',
302                    'July', 'August', 'September', 'October', 'November', 'December'
303                ],
304                hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
305                    '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
306                    '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
307                ];
308            dateTime.push(hours[date.getHours()]);
309            dateTime.push(days[date.getDay()]);
310            dateTime.push(months[date.getMonth()]);
311            return dateTime;
312        }
313
314        function filterEmails(value) {
315            return validateEmail(value) ? undefined : value;
316        }
317
318        /**
319         * PUBLIC API
320         */
321        return {
322            PRODUCT_SIMPLE : 0,
323            PRODUCT_VARIABLE : 1,
324            PRODUCT_BUNDLE : 2,
325            PRODUCT_GROUPED : 3,
326            utmTerms : utmTerms,
327            utmId : utmId,
328            fireEventForAllPixel:function(functionName,events){
329                if (events.hasOwnProperty(Facebook.tag()))
330                    Facebook[functionName](events[Facebook.tag()]);
331                if (events.hasOwnProperty(Analytics.tag()))
332                    Analytics[functionName](events[Analytics.tag()]);
333                if (events.hasOwnProperty(Pinterest.tag()))
334                    Pinterest[functionName](events[Pinterest.tag()]);
335                if (events.hasOwnProperty(Bing.tag()))
336                    Bing[functionName](events[Bing.tag()]);
337
338                if (events.hasOwnProperty(GTM.tag()))
339                    GTM[functionName](events[GTM.tag()]);
340            },
341
342            setupPinterestObject: function () {
343                Pinterest = window.pys.Pinterest || Pinterest;
344                return Pinterest;
345            },
346
347            setupBingObject: function () {
348                Bing = window.pys.Bing || Bing;
349                return Bing;
350            },
351
352            // Clone all object members to another and return it
353            copyProperties: function (from, to) {
354                for (var key in from) {
355                    if("function" == typeof from[key]) {
356                        continue;
357                    }
358                    to[key] = from[key];
359                }
360                return to;
361            },
362
363            manageCookies: function () {
364
365                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
366                    if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) {
367                        return;
368                    }
369                }
370                let cm_consent_not_expressed = false;
371                if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) {
372                    if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) {
373                        cm_consent_not_expressed = true;
374                    }
375                }
376
377                if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) {
378                    let duration = options.last_visit_duration * 60000
379                    var now = new Date();
380                    now.setTime(now.getTime() + duration);
381                    Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain })
382                    Cookies.set('pys_start_session', true,{path: '/',domain: domain});
383                }
384
385                if (options.ajaxForServerEvent && !Cookies.get('pbid') && Facebook.isEnabled()) {
386                    jQuery.ajax({
387                        url: options.ajaxUrl,
388                        dataType: 'json',
389                        data: {
390                            action: 'pys_get_pbid'
391                        },
392                        success: function (res) {
393                            if (res.data && res.data.pbid != false && options.send_external_id) {
394                                if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
395                                    var expires = parseInt(options.external_id_expire || 180);
396                                    Cookies.set('pbid', res.data.pbid, { expires: expires, path: '/',domain: domain });
397                                }
398
399                                if(options.hasOwnProperty('facebook')) {
400                                    options.facebook.advancedMatching = {
401                                        ...options.facebook.advancedMatching,  // spread current advancedMatching values
402                                        external_id: res.data.pbid
403                                    };
404                                }
405                            }
406                        }
407                    });
408                } else if (Cookies.get('pbid') && Facebook.isEnabled()){
409                    if(Facebook.advancedMatching() && Facebook.advancedMatching().external_id && !(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
410                        let expires = parseInt(options.external_id_expire || 180);
411                        Cookies.set('pbid', Facebook.advancedMatching().external_id, { expires: expires, path: '/',domain: domain });
412                    }
413                }
414
415                let expires = parseInt(options.cookie_duration); //  days
416                let queryVars = getQueryVars();
417                let landing = window.location.href.split('?')[0];
418                try {
419                    // save data for first visit
420                    if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) {
421
422                        if(!options.cookie.disabled_first_visit_cookie)
423                        {
424                            Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain });
425                        }
426                        else {
427                            Cookies.remove('pys_first_visit')
428                        }
429
430                        if(!options.cookie.disabled_trafficsource_cookie)
431                        {
432                            Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
433                        }
434                        else {
435                            Cookies.remove('pysTrafficSource')
436                        }
437
438                        if(!options.cookie.disabled_landing_page_cookie)
439                        {
440                            Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
441                        }
442                        else {
443                            Cookies.remove('pys_landing_page')
444                        }
445
446                        if(!options.cookie.disabled_utmTerms_cookie)
447                        {
448                            $.each(utmTerms, function (index, name) {
449                                if (queryVars.hasOwnProperty(name)) {
450                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
451                                } else {
452                                    Cookies.remove('pys_' + name)
453                                }
454                            });
455                        }
456                        else {
457                            $.each(utmTerms, function (index, name) {
458                                Cookies.remove('pys_' + name)
459                            });
460                        }
461
462                        if(!options.cookie.disabled_utmId_cookie)
463                        {
464                            $.each(utmId,function(index,name) {
465                                if (queryVars.hasOwnProperty(name)) {
466                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
467                                } else {
468                                    Cookies.remove('pys_' + name)
469                                }
470                            })
471                        }
472                        else {
473                            $.each(utmId, function (index, name) {
474                                Cookies.remove('pys_' + name)
475                            });
476                        }
477                    }
478
479                    // save data for last visit if it new session
480                    if(isNewSession && (!options.cookie.disabled_all_cookie)) {
481                        if(!options.cookie.disabled_trafficsource_cookie)
482                        {
483                            Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
484                        }
485                        else {
486                            Cookies.remove('last_pysTrafficSource')
487                        }
488
489                        if(!options.cookie.disabled_landing_page_cookie)
490                        {
491                            Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
492                        }
493                        else {
494                            Cookies.remove('last_pys_landing_page')
495                        }
496
497                        if(!options.cookie.disabled_utmTerms_cookie)
498                        {
499                            $.each(utmTerms, function (index, name) {
500                                if (queryVars.hasOwnProperty(name)) {
501                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
502                                } else {
503                                    Cookies.remove('last_pys_' + name)
504                                }
505                            });
506                        }
507                        else {
508                            $.each(utmTerms, function (index, name) {
509                                Cookies.remove('last_pys_' + name)
510                            });
511                        }
512
513                        if(!options.cookie.disabled_utmId_cookie)
514                        {
515                            $.each(utmId,function(index,name) {
516                                if (queryVars.hasOwnProperty(name)) {
517                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
518                                } else {
519                                    Cookies.remove('last_pys_' + name)
520                                }
521                            })
522                        }
523                        else {
524                            $.each(utmId, function (index, name) {
525                                Cookies.remove('last_pys_' + name)
526                            });
527                        }
528
529                    }
530                    if(options.cookie.disabled_start_session_cookie) {
531                        Cookies.remove('pys_start_session')
532                        Cookies.remove('pys_session_limit')
533                    }
534                    if(options.cookie.disabled_all_cookie)
535                    {
536                        Cookies.remove('pys_first_visit')
537                        Cookies.remove('pysTrafficSource')
538                        Cookies.remove('pys_landing_page')
539                        Cookies.remove('last_pys_landing_page')
540                        Cookies.remove('last_pysTrafficSource')
541                        Cookies.remove('pys_start_session')
542                        Cookies.remove('pys_session_limit')
543                        $.each(Utils.utmTerms, function (index, name) {
544                            Cookies.remove('pys_' + name)
545                        });
546                        $.each(Utils.utmId,function(index,name) {
547                            Cookies.remove('pys_' + name)
548                        })
549                        $.each(Utils.utmTerms, function (index, name) {
550                            Cookies.remove('last_pys_' + name)
551                        });
552                        $.each(Utils.utmId,function(index,name) {
553                            Cookies.remove('last_pys_' + name)
554                        });
555                    }
556                } catch (e) {
557                    console.error(e);
558                }
559            },
560            /**
561             * Generate unique ID
562             */
563            generateUniqueId : function (event) {
564                if(event.eventID.length == 0 || (event.type == "static" && options.ajaxForServerStaticEvent) || (event.type !== "static" && options.ajaxForServerEvent)) {
565                    let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id;
566                    if (!uniqueId.hasOwnProperty(idKey)) {
567                        uniqueId[idKey] = pys_generate_token();
568                    }
569                    return uniqueId[idKey];
570                }
571                else if(event.eventID.length !== 0)
572                {
573                    return event.eventID;
574                }
575            },
576
577            // Flatten object for sendBeacon compatibility
578            flattenObject: function (obj, prefix = '', res = {}) {
579                for (const [key, value] of Object.entries(obj)) {
580                    const prefixedKey = prefix
581                        ? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
582                        : key;
583                    if (value !== null && typeof value === 'object' && !(value instanceof File)) {
584                        this.flattenObject(value, prefixedKey, res);
585                    } else {
586                        res[prefixedKey] = value;
587                    }
588                }
589                return res;
590            },
591
592            sendServerAjaxRequest : function(url, data) {
593                if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) {
594                    // Use Facebook REST API
595                    this.sendRestAPIRequest(data, 'facebook');
596                    return;
597                }
598
599                // Check if sendBeacon is enabled and supported
600                if (options.useSendBeacon && navigator.sendBeacon) {
601                    try {
602                        // Flatten the data object for sendBeacon compatibility
603                        const flattenedData = this.flattenObject(data);
604                        const formData = new URLSearchParams();
605
606                        // Convert flattened data to URLSearchParams
607                        for (const [key, value] of Object.entries(flattenedData)) {
608                            if (value !== null && value !== undefined) {
609                                formData.append(key, value);
610                            }
611                        }
612
613                        // Try to send using sendBeacon
614                        const success = navigator.sendBeacon(url, formData);
615                        if (success) {
616                            return; // Successfully sent via sendBeacon
617                        }
618                    } catch (e) {
619                        // If sendBeacon fails, fall back to jQuery.ajax
620                        if (options.debug) {
621                            console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e);
622                        }
623                    }
624                }
625
626                // Fallback to jQuery.ajax
627                jQuery.ajax( {
628                    type: 'POST',
629                    url: url,
630                    data: data,
631                    headers: {
632                        'Cache-Control': 'no-cache'
633                    },
634                    success: function () {
635                    },
636                } );
637            },
638
639            sendRestAPIRequest: function (data, platform) {
640                let restApiUrl;
641
642                // Get platform-specific REST API configuration
643                switch (platform) {
644                    case 'facebook':
645                        restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event';
646                        break;
647                    default:
648                        console.error('PYS: Unknown platform for REST API:', platform);
649                        this.sendAjaxFallback(data);
650                        return;
651                }
652
653                // Prepare data for REST API
654                const restApiData = {
655                    event: data.event,
656                    data: JSON.stringify(data.data || {}),
657                    ids: JSON.stringify(data.ids || []),
658                    eventID: data.event_id || data.eventID || '',
659                    woo_order: data.woo_order || '0',
660                    edd_order: data.edd_order || '0'
661                };
662
663                // Try to send using sendBeacon first (if enabled)
664                if (options.useSendBeacon && navigator.sendBeacon) {
665                    try {
666                        const formData = new URLSearchParams();
667                        for (const [key, value] of Object.entries(restApiData)) {
668                            formData.append(key, value);
669                        }
670
671                        if (navigator.sendBeacon(restApiUrl, formData)) {
672                            return;
673                        }
674                    } catch (e) {
675                        // sendBeacon failed, continue to fetch
676                    }
677                }
678
679                // Try to send using fetch with REST API
680                if (window.fetch) {
681                    const headers = {
682                        'Content-Type': 'application/json'
683                    };
684
685                    fetch(restApiUrl, {
686                        method: 'POST',
687                        headers: headers,
688                        body: JSON.stringify(restApiData)
689                    })
690                        .then(response => {
691                            if (!response.ok) {
692                                throw new Error(platform + ' REST API request failed: ' + response.status);
693                            }
694                        })
695                        .catch(error => {
696                            // Fallback to AJAX if REST API fails
697                            if (options.debug) {
698                                console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error);
699                            }
700                            this.sendAjaxFallback(data);
701                        });
702                } else {
703                    // Fallback to AJAX if fetch is not supported
704                    this.sendAjaxFallback(data);
705                }
706            },
707
708
709
710            // Fallback AJAX method
711            sendAjaxFallback: function (data) {
712                jQuery.ajax({
713                    type: 'POST',
714                    url: options.ajaxUrl,
715                    data: data,
716                    headers: {
717                        'Cache-Control': 'no-cache'
718                    },
719                    success: function () {
720                    },
721                });
722            },
723            // clone object
724            clone: function(obj) {
725                var copy;
726
727                // Handle the 3 simple types, and null or undefined
728                if (null == obj || "object" != typeof obj) return obj;
729
730                // Handle Date
731                if (obj instanceof Date) {
732                    copy = new Date();
733                    copy.setTime(obj.getTime());
734                    return copy;
735                }
736
737                // Handle Array
738                if (obj instanceof Array) {
739                    copy = [];
740                    for (var i = 0, len = obj.length; i < len; i++) {
741                        if("function" == typeof obj[i]) {
742                            continue;
743                        }
744                        copy[i] = Utils.clone(obj[i]);
745                    }
746                    return copy;
747                }
748
749                // Handle Object
750                if (obj instanceof Object) {
751                    copy = {};
752                    for (var attr in obj) {
753                        if (obj.hasOwnProperty(attr)) {
754                            if("function" == typeof obj[attr]) {
755                                continue;
756                            }
757                            copy[attr] = Utils.clone(obj[attr]);
758                        }
759                    }
760                    return copy;
761                }
762
763                return obj;
764            },
765
766            // Returns array of elements with given tag name
767            getTagsAsArray: function (tag) {
768                return [].slice.call(document.getElementsByTagName(tag));
769            },
770
771            getRequestParams: function () {
772                return [];
773            },
774
775            /**
776             * CUSTOM EVENTS
777             */
778
779            setupMouseOverClickEvents: function (eventId, triggers) {
780
781                // Non-default binding used to avoid situations when some code in external js
782                // stopping events propagation, eg. returns false, and our handler will never called
783                document.addEventListener('mouseover', function(event) {
784                    var matchedElements = Array.from(document.querySelectorAll(triggers));
785                    var clickedElement = event.target;
786                    var closestMatch = clickedElement.closest(triggers);
787                    if (matchedElements.includes(clickedElement) || closestMatch){
788                        if (event.target.classList.contains('pys-mouse-over-' + eventId)) {
789                            return true;
790                        } else {
791                            event.target.classList.add('pys-mouse-over-' + eventId);
792                        }
793
794                        Utils.fireTriggerEvent(eventId);
795                    }
796                });
797
798            },
799
800            setupCSSClickEvents: function (eventId, triggers) {
801                // Non-default binding used to avoid situations when some code in external js
802                // stopping events propagation, eg. returns false, and our handler will never called
803                document.addEventListener('click', function(event) {
804                    let matchedElements = Array.from(document.querySelectorAll(triggers)),
805                        clickedElement = event.target,
806                        closestMatch = clickedElement.closest(triggers);
807
808                    if (matchedElements.includes(clickedElement) || closestMatch){
809                        Utils.fireTriggerEvent(eventId);
810                    }
811                }, true);
812            },
813
814            setupURLClickEvents: function () {
815
816                if( !options.triggerEventTypes.hasOwnProperty('url_click') ) {
817                    return;
818                }
819                // Non-default binding used to avoid situations when some code in external js
820                // stopping events propagation, eg. returns false, and our handler will never called
821                $('a[data-pys-event-id]').onFirst('click', function (evt) {
822
823                    $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) {
824
825                        eventId = parseInt(eventId);
826
827                        if (isNaN(eventId) === false) {
828                            Utils.fireTriggerEvent(eventId);
829                        }
830
831                    });
832
833                });
834
835
836            },
837
838            setupScrollPosEvents: function (eventId, triggers) {
839
840                var scrollPosThresholds = {},
841                    docHeight = $(document).height() - $(window).height();
842
843                // convert % to absolute positions
844                $.each(triggers, function (index, scrollPos) {
845
846                    // convert % to pixels
847                    scrollPos = docHeight * scrollPos / 100;
848                    scrollPos = Math.round(scrollPos);
849
850                    scrollPosThresholds[scrollPos] = eventId;
851
852                });
853
854                $(document).on("scroll",function () {
855
856                    var scrollPos = $(window).scrollTop();
857
858                    $.each(scrollPosThresholds, function (threshold, eventId) {
859
860                        // position has not reached yes
861                        if (scrollPos <= threshold) {
862                            return true;
863                        }
864
865                        // fire event only once
866                        if (eventId === null) {
867                            return true;
868                        } else {
869                            scrollPosThresholds[threshold] = null;
870                        }
871
872                        Utils.fireTriggerEvent(eventId);
873
874                    });
875
876                });
877
878
879            },
880            setupCommentEvents : function (eventId,triggers) {
881                $('form.comment-form').on("submit",function () {
882                    Utils.fireTriggerEvent(eventId);
883                });
884            },
885
886            /**
887             * Events
888             */
889
890            fireTriggerEvent: function (eventId) {
891
892                if (!options.triggerEvents.hasOwnProperty(eventId)) {
893                    return;
894                }
895
896                var event = {};
897                var events = options.triggerEvents[eventId];
898
899                if (events.hasOwnProperty('facebook')) {
900                    event = events.facebook;
901                    Facebook.fireEvent(event.name, event);
902                }
903
904                if (events.hasOwnProperty('ga')) {
905                    event = events.ga;
906                    Analytics.fireEvent(event.name, event);
907                }
908
909                if (events.hasOwnProperty('pinterest')) {
910                    event = events.pinterest;
911                    Pinterest.fireEvent(event.name, event);
912                }
913
914                if (events.hasOwnProperty('bing')) {
915                    event = events.bing;
916                    Bing.fireEvent(event.name, event);
917                }
918
919                if (events.hasOwnProperty('gtm')) {
920                    event = events.gtm;
921                    GTM.fireEvent(event.name, event);
922                }
923            },
924
925            fireStaticEvents: function (pixel) {
926
927                if (options.staticEvents.hasOwnProperty(pixel)) {
928
929                    $.each(options.staticEvents[pixel], function (eventName, events) {
930                        $.each(events, function (index, eventData) {
931
932                            eventData.fired = eventData.fired || false;
933
934                            if (!eventData.fired) {
935
936                                var fired = false;
937
938                                // fire event
939                                if ('facebook' === pixel) {
940                                    fired = Facebook.fireEvent(eventData.name, eventData);
941                                } else if ('ga' === pixel) {
942                                    fired = Analytics.fireEvent(eventData.name, eventData);
943                                } else if ('pinterest' === pixel) {
944                                    fired = Pinterest.fireEvent(eventData.name, eventData);
945                                } else if ('bing' === pixel) {
946                                    fired = Bing.fireEvent(eventData.name, eventData);
947                                } else if ('gtm' === pixel) {
948                                    fired = GTM.fireEvent(eventData.name, eventData);
949                                }
950
951                                // prevent event double event firing
952                                eventData.fired = fired;
953
954                            }
955
956                        });
957                    });
958
959                }
960
961            },
962
963            /**
964             * Load tag's JS
965             *
966             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
967             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
968             */
969            loadGoogleTag: function (id) {
970
971                if (!gtag_loaded) {
972                    let dataLayerName = this.dataLayerName;
973                    if(options.hasOwnProperty('GATags')){
974                        switch (options.GATags.ga_datalayer_type) {
975                            case 'default':
976                                dataLayerName = 'dataLayerPYS';
977                                break;
978                            case 'custom':
979                                dataLayerName = options.GATags.ga_datalayer_name;
980                                break;
981                            default:
982                                dataLayerName = 'dataLayer';
983                        }
984                    }
985                    this.dataLayerName = dataLayerName;
986                    (function (window, document, src) {
987                        var a = document.createElement('script'),
988                            m = document.getElementsByTagName('script')[0];
989                        a.async = 1;
990                        a.src = src;
991                        m.parentNode.insertBefore(a, m);
992                    })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName);
993
994                    window[dataLayerName] = window[dataLayerName] || [];
995                    window.gtag = window.gtag || function gtag() {
996                        window[dataLayerName].push(arguments);
997                    };
998
999                    if ( options.google_consent_mode ) {
1000                        let data = {};
1001                        data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
1002                        data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
1003                        data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
1004                        data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
1005
1006                        this.loadDefaultConsent( 'consent', 'default', data );
1007                    }
1008
1009                    gtag('js', new Date());
1010                    gtag_loaded = true;
1011
1012                }
1013
1014            },
1015
1016            loadDefaultConsent: function() {
1017                window[ this.dataLayerName ].push( arguments );
1018            },
1019
1020            loadGTMScript: function (id = '') {
1021                const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com';
1022                const loader = options.gtm.gtm_container_identifier ?? 'gtm';
1023                const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed
1024                const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed
1025                const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
1026
1027                window[ datalayer_name ] = window[ datalayer_name ] || [];
1028                window.gtag = window.gtag || function gtag() {
1029                    window[ datalayer_name ].push( arguments );
1030                };
1031
1032                if ( options.google_consent_mode ) {
1033                    let data = {};
1034                    data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
1035                    data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
1036                    data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
1037                    data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
1038
1039                    this.GTMdataLayerName = datalayer_name;
1040                    this.loadDefaultGTMConsent( 'consent', 'default', data );
1041                }
1042
1043                (function(w, d, s, l, i) {
1044                    w[l] = w[l] || [];
1045                    w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
1046                    const f = d.getElementsByTagName(s)[0];
1047                    const j = d.createElement(s);
1048                    const dl = l !== 'dataLayer' ? '&l=' + l : '';
1049                    j.async = true;
1050                    j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl;
1051                    if (gtm_auth && gtm_preview) {
1052                        j.src += '&gtm_auth=' + gtm_auth + '&gtm_preview=' + gtm_preview + '&gtm_cookies_win=x';
1053                    }
1054                    f.parentNode.insertBefore(j, f);
1055                })(window, document, 'script', datalayer_name, id);
1056
1057            },
1058
1059            loadDefaultGTMConsent: function() {
1060                window[ this.GTMdataLayerName ].push( arguments );
1061            },
1062
1063            /**
1064             * GDPR
1065             */
1066
1067            loadPixels: function () {
1068
1069                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
1070
1071                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
1072                    $.get({
1073                        url: options.ajaxUrl,
1074                        dataType: 'json',
1075                        data: {
1076                            action: 'pys_get_gdpr_filters_values'
1077                        },
1078                        success: function (res) {
1079
1080                            if (res.success) {
1081
1082                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
1083                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
1084                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
1085                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
1086                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
1087                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
1088
1089                                options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api;
1090                                options.cookie.disabled_all_cookie = res.data.disabled_all_cookie;
1091                                options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie;
1092                                options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie;
1093                                options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie;
1094                                options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie;
1095                                options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie;
1096                                options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie;
1097                            }
1098
1099                            loadPixels();
1100
1101                        }
1102                    });
1103
1104                } else {
1105                    loadPixels();
1106                }
1107
1108            },
1109
1110            consentGiven: function (pixel) {
1111
1112                /**
1113                 * ConsentMagic
1114                 */
1115                if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
1116
1117                    let test_prefix = CS_Data.test_prefix;
1118                    if (
1119                        ( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) )
1120                        || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' )
1121                        || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' )
1122                    ) {
1123                        if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) {
1124                            return true;
1125                        } else {
1126                            return false;
1127                        }
1128                    }
1129
1130                    if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) {
1131                        return true;
1132                    } else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) {
1133                        return true;
1134                    } else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) {
1135                        return true;
1136                    } else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) {
1137                        return true;
1138                    } else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) {
1139                        return true;
1140                    } else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) {
1141                        return true;
1142                    }
1143
1144                    let substring = "cs_enabled_cookie_term",
1145                        theCookies = document.cookie.split( ';' );
1146
1147                    for ( let i = 1; i <= theCookies.length; i++ ) {
1148                        if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
1149                            let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
1150                            categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
1151                            let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
1152
1153                            if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
1154                                return cs_cookie_val == 'yes';
1155                            } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
1156                                return cs_cookie_val == 'yes';
1157                            } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
1158                                return cs_cookie_val == 'yes';
1159                            } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
1160                                return cs_cookie_val == 'yes';
1161                            } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
1162                                return cs_cookie_val == 'yes';
1163                            } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
1164                                return cs_cookie_val == 'yes';
1165                            }
1166                        }
1167                    }
1168
1169                    return false;
1170                }
1171
1172                /**
1173                 * Real Cookie Banner
1174                 */
1175                if(options.gdpr.real_cookie_banner_integration_enabled) {
1176                    var consentApi = window.consentApi;
1177                    if (consentApi) {
1178                        switch (pixel) {
1179                            case "analytics":
1180                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
1181                            case "facebook":
1182                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
1183                            case "pinterest":
1184                                return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
1185                            default:
1186                                return true;
1187                        }
1188                    }
1189                }
1190
1191                /**
1192                 * Cookiebot
1193                 */
1194                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1195
1196                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
1197
1198                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1199                        if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) {
1200                            return true;
1201                        }
1202                    } else {
1203                        if (Cookiebot.consent[cookiebot_consent_category]) {
1204                            return true;
1205                        }
1206                    }
1207
1208                    return false;
1209
1210                }
1211
1212                /**
1213                 * Cookie Notice
1214                 */
1215                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
1216
1217                    var cn_cookie = Cookies.get(cnArgs.cookieName);
1218
1219                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1220                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
1221                            return true;
1222                        }
1223                    } else {
1224                        if (cn_cookie === 'true') {
1225                            return true;
1226                        }
1227                    }
1228
1229                    return false;
1230
1231                }
1232
1233                /**
1234                 * Cookie Law Info
1235                 */
1236                if (options.gdpr.cookie_law_info_integration_enabled) {
1237                    var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
1238                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1239                        if (typeof cli_cookie === 'undefined') return true;
1240                        if (
1241                            cli_cookie &&
1242                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
1243                        ) {
1244                            if (getCookieYes('analytics') === 'yes') {
1245                                return true;
1246                            }
1247                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
1248                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
1249                                return true;
1250                            }
1251                        }
1252                    } else {
1253                        if (
1254                            cli_cookie &&
1255                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
1256                        ) {
1257                            if (getCookieYes('analytics') === 'yes') {
1258                                return true;
1259                            }
1260                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
1261                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
1262                                return true;
1263                            }
1264                        }
1265                    }
1266                    return false;
1267                }
1268
1269                return true;
1270
1271            },
1272
1273            setupGdprCallbacks: function () {
1274                /**
1275                 * ConsentMagic
1276                 */
1277                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
1278                    let test_prefix = CS_Data.test_prefix,
1279                        cs_refresh_after_consent = false,
1280                        substring = "cs_enabled_cookie_term";
1281
1282                    if (CS_Data.cs_refresh_after_consent == 1) {
1283                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
1284                    }
1285
1286                    let consent_actions = function () {
1287                        let theCookies = document.cookie.split( ';' );
1288
1289                        let consent = {
1290                            facebook: true,
1291                            ga: true,
1292                            google_ads: true,
1293                            tiktok: true,
1294                            bing: true,
1295                            pinterest: true,
1296                            gtm: true,
1297                        };
1298
1299                        for (let i = 1 ; i <= theCookies.length; i++) {
1300                            if (theCookies[i-1].indexOf(substring) !== -1) {
1301                                let categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_','');
1302                                categoryCookie = Number(categoryCookie.replace(/\D+/g,""));
1303                                let cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie);
1304                                if(cs_cookie_val == 'yes') {
1305                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) {
1306                                        Facebook.loadPixel();
1307                                    }
1308
1309                                    if ( categoryCookie === CS_Data.cs_script_cat.bing || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
1310                                        Bing.loadPixel();
1311                                    }
1312
1313                                    if (categoryCookie === CS_Data.cs_script_cat.analytics || (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1)
1313) {
1314
1315                                        Analytics.loadPixel();
1316                                    }
1317
1318                                    if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
1319                                        Pinterest.loadPixel();
1320                                    }
1321                                } else {
1322                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) {
1323                                        Facebook.disable();
1324                                        consent.facebook = false;
1325                                    }
1326
1327                                    if ( categoryCookie === CS_Data.cs_script_cat.bing && ( typeof CS_Data.cs_bing_consent_mode == "undefined" || !CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
1328                                        Bing.disable();
1329                                        consent.bing = false;
1330                                    }
1331                                    if (categoryCookie === CS_Data.cs_script_cat.analytics && (typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0)) {
1332                                        Analytics.disable();
1333                                        consent.ga = false;
1334                                        consent.gtm = false;
1335                                    }
1336
1337                                    if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
1338                                        Pinterest.disable();
1339                                        consent.pinterest = false;
1340                                    }
1341                                }
1342                                if (Cookies.get('cs_enabled_advanced_matching') == 'yes') {
1343                                    Facebook.loadPixel();
1344                                }
1345                            }
1346                        }
1347                        Utils.setupGDPRData( consent );
1348                    }
1349
1350                    if (!cs_refresh_after_consent) {
1351                        consent_actions();
1352
1353                        $(document).on('click','.cs_action_btn',function(e) {
1354                            e.preventDefault();
1355
1356                            let consent = {
1357                                facebook: true,
1358                                ga: true,
1359                                bing: true,
1360                                pinterest: true,
1361                                gtm: true,
1362                            };
1363
1364                            let elm = $(this),
1365                                button_action = elm.attr('data-cs_action');
1366
1367                            if(button_action === 'allow_all') {
1368                                Facebook.loadPixel();
1369                                Bing.loadPixel();
1370                                Analytics.loadPixel();
1371                                Pinterest.loadPixel();
1372
1373                                consent.facebook = true;
1374                                consent.bing = true;
1375                                consent.ga = true;
1376                                consent.pinterest = true;
1377                                consent.gtm = true;
1378
1379                                Utils.setupGDPRData( consent );
1380                            } else if ( button_action === 'disable_all' ) {
1381                                if ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) {
1382                                    Facebook.disable();
1383                                    consent.facebook = false;
1384                                }
1385
1386                                if ( typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) {
1387                                    Bing.disable();
1388                                    consent.bing = false;
1389                                }
1390
1391                                if ( CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined" ) {
1392                                    Analytics.disable();
1393                                    consent.ga = false;
1394                                    consent.gtm = false;
1395                                }
1396
1397                                Pinterest.disable();
1398                                consent.pinterest = false;
1399                                Utils.setupGDPRData( consent );
1400                            } else if ( button_action === 'cs_confirm' ) {
1401                                consent_actions();
1402                            }
1403                        });
1404                    }
1405                }
1406                /**
1407                 * Real Cookie Banner
1408                 */
1409                if(options.gdpr.real_cookie_banner_integration_enabled) {
1410                    let consentApi = window.consentApi;
1411                    if (consentApi) {
1412                        consentApi.consent("http", "_ga", "*")
1413                            .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics));
1414                        consentApi.consent("http", "_fbp", "*")
1415                            .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook));
1416                        consentApi.consent("http", "_pinterest_sess", ".pinterest.com")
1417                            .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest));
1418                        consentApi.consent("http", "_uetsid", "*")
1419                            .then(Bing.loadPixel.bind(Bing), Bing.disable.bind(Bing));
1420
1421                        let consent = {
1422                            facebook: true,
1423                            ga: true,
1424                            bing: true,
1425                            pinterest: true,
1426                            gtm: true,
1427                        };
1428
1429                        if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) {
1430                            consent.ga = false;
1431                            consent.gtm = false;
1432                        }
1433                        if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) {
1434                            consent.facebook = false;
1435                        }
1436                        if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) {
1437                            consent.pinterest = false;
1438                        }
1439                        if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) {
1440                            consent.bing = false;
1441                        }
1442                        Utils.setupGDPRData( consent );
1443                    }
1444                }
1445                /**
1446                 * Cookiebot
1447                 */
1448                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1449
1450                    window.addEventListener("CookiebotOnConsentReady", function() {
1451
1452                        let consent = {
1453                            facebook: true,
1454                            ga: true,
1455                            bing: true,
1456                            pinterest: true,
1457                            gtm: true,
1458                        };
1459
1460                        Utils.manageCookies();
1461                        if (Cookiebot.consent.marketing) {
1462                            Facebook.loadPixel();
1463                            Bing.loadPixel();
1464                            Pinterest.loadPixel();
1465
1466                            consent.facebook = true;
1467                            consent.bing = true;
1468                            consent.pinterest = true;
1469                        }
1470                        if (Cookiebot.consent.statistics) {
1471                            Analytics.loadPixel();
1472
1473                            consent.ga = true;
1474                            consent.gtm = true;
1475                        }
1476                        if (!Cookiebot.consent.marketing) {
1477                            Facebook.disable();
1478                            Pinterest.disable();
1479                            Bing.disable();
1480
1481                            consent.facebook = false;
1482                            consent.bing = false;
1483                            consent.pinterest = false;
1484                        }
1485                        if (!Cookiebot.consent.statistics) {
1486                            Analytics.disable();
1487
1488                            consent.ga = false;
1489                            consent.gtm = false;
1490                        }
1491
1492                        Utils.setupGDPRData( consent );
1493                    });
1494
1495                }
1496
1497                /**
1498                 * Cookie Notice
1499                 */
1500                if (options.gdpr.cookie_notice_integration_enabled) {
1501
1502                    $(document).onFirst('click', '.cn-set-cookie', function () {
1503
1504                        let consent = {};
1505
1506                        if ($(this).data('cookie-set') === 'accept') {
1507                            Facebook.loadPixel();
1508                            Analytics.loadPixel();
1509                            Pinterest.loadPixel();
1510                            Bing.loadPixel();
1511
1512                            consent = {
1513                                facebook: true,
1514                                ga: true,
1515                                bing: true,
1516                                pinterest: true,
1517                                gtm: true,
1518                            };
1519                        } else {
1520                            Facebook.disable();
1521                            Analytics.disable();
1522                            Pinterest.disable();
1523                            Bing.disable();
1524
1525                            consent = {
1526                                facebook: false,
1527                                ga: false,
1528                                bing: false,
1529                                pinterest: false,
1530                                gtm: false,
1531                            };
1532                        }
1533
1534                        Utils.setupGDPRData( consent );
1535                    });
1536
1537                    $(document).onFirst('click', '.cn-revoke-cookie', function () {
1538                        Facebook.disable();
1539                        Analytics.disable();
1540                        Pinterest.disable();
1541                        Bing.disable();
1542
1543                        let consent = {
1544                            facebook: false,
1545                            ga: false,
1546                            bing: false,
1547                            pinterest: false,
1548                            gtm: false,
1549                        };
1550                        Utils.setupGDPRData( consent );
1551
1552                    });
1553
1554                }
1555
1556                /**
1557                 * Cookie Law Info
1558                 */
1559                if (options.gdpr.cookie_law_info_integration_enabled) {
1560
1561                    $(document).onFirst('click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () {
1562                        setTimeout(function (){
1563                            let cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
1564                            if (typeof cli_cookie !== 'undefined') {
1565                                if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) {
1566                                    if (getCookieYes('analytics') === 'yes') {
1567                                        Utils.manageCookies();
1568                                    }
1569                                } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
1570                                    Utils.manageCookies();
1571                                }
1572                            }
1573                        },1000)
1574                        Facebook.loadPixel();
1575                        Analytics.loadPixel();
1576                        Pinterest.loadPixel();
1577                        Bing.loadPixel();
1578
1579                        let consent = {
1580                            facebook: true,
1581                            ga: true,
1582                            bing: true,
1583                            pinterest: true,
1584                            gtm: true,
1585                        };
1586                        Utils.setupGDPRData( consent );
1587                    });
1588
1589                    $(document).onFirst('click', '#cookie_action_close_header_reject, .cky-btn-reject', function () {
1590                        Facebook.disable();
1591                        Analytics.disable();
1592                        Pinterest.disable();
1593                        Bing.disable();
1594
1595                        let consent = {
1596                            facebook: false,
1597                            ga: false,
1598                            bing: false,
1599                            pinterest: false,
1600                            gtm: false,
1601                        };
1602                        Utils.setupGDPRData( consent );
1603                    });
1604
1605                }
1606
1607            },
1608
1609            setupGDPRData: function ( consent ) {
1610                consent = window.btoa( JSON.stringify( consent ) );
1611                Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } );
1612            },
1613
1614            /**
1615             * DOWNLOAD DOCS
1616             */
1617
1618            getLinkExtension: function (link) {
1619
1620                // Remove anchor, query string and everything before last slash
1621                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1622                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1623                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1624
1625                // If there's a period left in the URL, then there's a extension
1626                if (link.length > 0 && link.indexOf('.') !== -1) {
1627                    link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period
1628                    return link;
1629                } else {
1630                    return "";
1631                }
1632            },
1633
1634            getLinkFilename: function (link) {
1635
1636                // Remove anchor, query string and everything before last slash
1637                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1638                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1639                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1640
1641                // If there's a period left in the URL, then there's a extension
1642                if (link.length > 0 && link.indexOf('.') !== -1) {
1643                    return link;
1644                } else {
1645                    return "";
1646                }
1647            },
1648            /**
1649             * Enrich
1650             */
1651            isCheckoutPage: function () {
1652                return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
1653                    $('body').hasClass('edd-checkout');
1654            },
1655            addCheckoutFields : function() {
1656                var utm = "";
1657                var utms = getUTMs()
1658
1659                $.each(utmTerms, function (index, name) {
1660                    if(index > 0) {
1661                        utm+="|";
1662                    }
1663                    utm+=name+":"+utms[name];
1664                });
1665                var utmIdList = "";
1666                var utmsIds = getUTMId()
1667                $.each(utmId, function (index, name) {
1668                    if(index > 0) {
1669                        utmIdList+="|";
1670                    }
1671                    utmIdList+=name+":"+utmsIds[name];
1672                });
1673                var utmIdListLast = "";
1674                var utmsIdsLast = getUTMId(true)
1675                $.each(utmId, function (index, name) {
1676                    if(index > 0) {
1677                        utmIdListLast+="|";
1678                    }
1679                    utmIdListLast+=name+":"+utmsIdsLast[name];
1680                });
1681
1682
1683                var utmLast = "";
1684                var utmsLast = getUTMs(true)
1685                $.each(utmTerms, function (index, name) {
1686                    if(index > 0) {
1687                        utmLast+="|";
1688                    }
1689                    utmLast+=name+":"+utmsLast[name];
1690                });
1691
1692                var dateTime = getDateTime();
1693                var landing = getLandingPageValue();
1694                var lastLanding = getLandingPageValue();
1695                var trafic = getTrafficSourceValue();
1696                var lastTrafic = getTrafficSourceValue();
1697
1698                var $form = null;
1699                if($('body').hasClass('woocommerce-checkout')) {
1700                    $form = $("form.woocommerce-checkout");
1701                } else {
1702                    $form = $("#edd_purchase_form");
1703                }
1704                var inputs = {'pys_utm':utm,
1705                    'pys_utm_id':utmIdList,
1706                    'pys_browser_time':dateTime.join("|"),
1707                    'pys_landing':landing,
1708                    'pys_source':trafic,
1709                    'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
1710
1711                    'last_pys_landing':lastLanding,
1712                    'last_pys_source':lastTrafic,
1713                    'last_pys_utm':utmLast,
1714                    'last_pys_utm_id':utmIdListLast,
1715                }
1716
1717                Object.keys(inputs).forEach(function(key,index) {
1718                    $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
1719                });
1720
1721
1722            },
1723            getAdvancedFormData: function () {
1724                let dataStr = Cookies.get("pys_advanced_form_data");
1725                if(dataStr === undefined) {
1726                    return {'first_name':"",'last_name':"",'email':"",'phone':""};
1727                } else {
1728                    return JSON.parse(dataStr);
1729                }
1730            }
1731        };
1732
1733    }(options);
1734
1735    var Facebook = function (options) {
1736
1737
1738        var defaultEventTypes = [
1739            'PageView',
1740            'ViewContent',
1741            'Search',
1742            'AddToCart',
1743            'AddToWishlist',
1744            'InitiateCheckout',
1745            'AddPaymentInfo',
1746            'Purchase',
1747            'Lead',
1748
1749            'Subscribe',
1750            'CustomizeProduct',
1751            'FindLocation',
1752            'StartTrial',
1753            'SubmitApplication',
1754            'Schedule',
1755            'Contact',
1756            'Donate'
1757        ];
1758
1759        var initialized = false;
1760        var genereateFbp = function (){
1761            return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp');
1762        };
1763        var genereateFbc = function (){
1764            return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : ''
1765        };
1766        // fire server side event gdpr plugin installed
1767        var isApiDisabled = options.gdpr.all_disabled_by_api ||
1768            options.gdpr.facebook_disabled_by_api ||
1769            options.gdpr.cookiebot_integration_enabled ||
1770            options.gdpr.consent_magic_integration_enabled ||
1771            options.gdpr.cookie_notice_integration_enabled ||
1772            options.gdpr.cookie_law_info_integration_enabled;
1773
1774        /**
1775         *
1776         * @param allData
1777         * @param params
1778         * @returns {string | null}
1779         */
1780        function sendFbServerEvent(allData,name,params) {
1781            let eventId = null;
1782            if(options.facebook.serverApiEnabled) {
1783
1784                if(allData.e_id === "woo_remove_from_cart") {// server event will sended from hook
1785                    Facebook.updateEventId(allData.name);
1786                    allData.eventID = Facebook.getEventId(allData.name);
1787                } else {
1788                    // send event from server if they was bloc by gdpr or need send with delay
1789                    allData.eventID = Utils.generateUniqueId(allData);
1790
1791                    if(Cookies.get('_fbp')){
1792                        params._fbp = Cookies.get('_fbp');
1793                    }
1794                    if(Cookies.get('_fbc')){
1795                        params._fbc = Cookies.get('_fbc');
1796                    }
1797
1798                    if( options.ajaxForServerEvent || isApiDisabled ){
1799                        var json = {
1800                            action: 'pys_api_event',
1801                            pixel: 'facebook',
1802                            event: name,
1803                            data:params,
1804                            ids:options.facebook.pixelIds,
1805                            eventID:allData.eventID,
1806                            url:window.location.href,
1807                            ajax_event:options.ajax_event
1808                        };
1809                        if(allData.hasOwnProperty('woo_order')) {
1810                            json['woo_order'] = allData.woo_order;
1811                        }
1812                        if(allData.hasOwnProperty('edd_order')) {
1813                            json['edd_order'] = allData.edd_order;
1814                        }
1815
1816                        if (allData.e_id === "automatic_event_internal_link" || allData.e_id === "automatic_event_outbound_link") {
1817                            setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), 500);
1818                        } else if (allData.type != 'static') {
1819                            Utils.sendServerAjaxRequest(options.ajaxUrl, json);
1820                        }
1821
1822                        if ( ( allData.type == 'static' && options.ajaxForServerStaticEvent ) || ( allData.hasOwnProperty( 'ajaxFire' ) && allData.ajaxFire ) ) {
1823                            Utils.sendServerAjaxRequest( options.ajaxUrl, json );
1824                        }
1825                    }
1826                }
1827                delete params._fbp;
1828                delete params._fbc;
1829                eventId = allData.eventID
1830            }
1831            return eventId;
1832        }
1833
1834        function fireEvent(name, allData) {
1835
1836            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
1837                return;
1838            }
1839
1840            var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
1841            var data = allData.params;
1842            var params = {};
1843            var arg = {};
1844            Utils.copyProperties(data, params);
1845            let eventId = sendFbServerEvent(allData,name,params)
1846
1847
1848            if("hCR" === name) {
1849                return;
1850            }
1851
1852            if (options.debug) {
1853                console.log('[Facebook] ' + name, params,"eventID",eventId);
1854            }
1855
1856            if(eventId != null) {
1857                arg.eventID = eventId;
1858            }
1859
1860            fbq(actionType, name, params, arg);
1861
1862        }
1863
1864        /**
1865         * Public API
1866         */
1867        return {
1868            tag: function() {
1869                return "facebook";
1870            },
1871            isEnabled: function () {
1872                return options.hasOwnProperty('facebook');
1873            },
1874
1875            disable: function () {
1876                initialized = false;
1877            },
1878            advancedMatching: function () {
1879                if(options.facebook.advancedMatchingEnabled) {
1880                    let advancedMatchingForm = Utils.getAdvancedFormData();
1881                    let advancedMatching = {};
1882                    if(Object.keys(options.facebook.advancedMatching).length > 0) {
1883                        advancedMatching = options.facebook.advancedMatching;
1884                    }
1885
1886                    if(!advancedMatching.hasOwnProperty("em")
1887                        && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) {
1888                        advancedMatching["em"] = advancedMatchingForm["email"];
1889                    }
1890                    if(!advancedMatching.hasOwnProperty("ph")
1891                        && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) {
1892                        advancedMatching["ph"] = advancedMatchingForm["phone"];
1893                    }
1894                    if(!advancedMatching.hasOwnProperty("fn")
1895                        && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) {
1896                        advancedMatching["fn"] = advancedMatchingForm["first_name"];
1897                    }
1898                    if(!advancedMatching.hasOwnProperty("ln")
1899                        && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) {
1900                        advancedMatching["ln"] = advancedMatchingForm["last_name"];
1901                    }
1902                    if(!advancedMatching.hasOwnProperty("external_id")){
1903                        if (Cookies.get('pbid') || (options.hasOwnProperty('pbid') && options.pbid)) {
1904                            advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : options.pbid;
1905                        }
1906                    }
1907                    else if(advancedMatching.external_id != Cookies.get('pbid'))
1908                    {
1909                        advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
1910                    }
1911                    if(Object.keys(advancedMatching).length > 0) {
1912                        return advancedMatching;
1913                    }
1914                }
1915                return false
1916            },
1917            /**
1918             * Load pixel's JS
1919             */
1920            loadPixel: function () {
1921
1922                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
1923                    return;
1924                }
1925
1926                !function (f, b, e, v, n, t, s) {
1927                    if (f.fbq) return;
1928                    n = f.fbq = function () {
1929                        n.callMethod ?
1930                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
1931                    };
1932                    if (!f._fbq) f._fbq = n;
1933                    n.push = n;
1934                    n.loaded = !0;
1935                    n.version = '2.0';
1936                    n.agent = 'dvpixelyoursite';
1937                    n.queue = [];
1938                    t = b.createElement(e);
1939                    t.async = !0;
1940                    t.src = v;
1941                    s = b.getElementsByTagName(e)[0];
1942                    s.parentNode.insertBefore(t, s)
1943                }(window,
1944                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
1945
1946                let expires = parseInt(options.cookie_duration);
1947                if(!Cookies.get('_fbp')) {
1948                    Cookies.set('_fbp',genereateFbp(),  { expires: expires,path: '/',domain: domain });
1949                }
1950
1951                if(getUrlParameter('fbclid')) {
1952                    Cookies.set('_fbc',genereateFbc(),  { expires: expires,path: '/',domain: domain });
1953                }
1954                // initialize pixel
1955                options.facebook.pixelIds.forEach(function (pixelId) {
1956                    if (options.facebook.removeMetadata) {
1957                        fbq('set', 'autoConfig', false, pixelId);
1958                    }
1959                    let advancedMatching = Facebook.advancedMatching();
1960
1961                    if ( +options.facebook.meta_ldu === 1  ) {
1962                        fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 );
1963                    }
1964
1965                    if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
1966                        if(!advancedMatching) {
1967                            fbq('init', pixelId);
1968                        } else {
1969                            var test_prefix = CS_Data.test_prefix;
1970                            var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
1971                            if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
1972                                if (cs_advanced_matching == 'yes') {
1973                                    fbq('init', pixelId, advancedMatching);
1974                                } else {
1975                                    fbq('init', pixelId);
1976                                }
1977                            } else {
1978                                fbq('init', pixelId, advancedMatching);
1979                            }
1980                        }
1981                    } else {
1982                        if(!advancedMatching) {
1983                            fbq('init', pixelId);
1984                        }  else {
1985                            fbq('init', pixelId, advancedMatching);
1986                        }
1987                    }
1988                });
1989
1990                initialized = true;
1991
1992                Utils.fireStaticEvents('facebook');
1993
1994            },
1995
1996            fireEvent: function (name, data) {
1997
1998                if (!initialized || !this.isEnabled()) {
1999                    return false;
2000                }
2001
2002                data.delay = data.delay || 0;
2003                data.params = data.params || {};
2004
2005                if (data.delay === 0) {
2006
2007                    fireEvent(name, data);
2008
2009                } else {
2010
2011                    setTimeout(function (name, params) {
2012                        fireEvent(name, params);
2013                    }, data.delay * 1000, name, data);
2014
2015                }
2016
2017                return true;
2018
2019            },
2020
2021            onCommentEvent: function (event) {
2022                this.fireEvent(event.name, event);
2023            },
2024
2025            onDownloadEvent: function (event) {
2026                this.fireEvent(event.name, event);
2027            },
2028
2029            onFormEvent: function (event) {
2030
2031                this.fireEvent(event.name, event);
2032
2033            },
2034
2035            onWooAddToCartOnButtonEvent: function (product_id) {
2036
2037                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2038                    return;
2039                var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()];
2040                window.pysWooProductData = window.pysWooProductData || [];
2041                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2042                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
2043                        event = Utils.copyProperties(event, {})
2044                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params)
2045                        this.fireEvent(event.name, event);
2046                    }
2047                }
2048            },
2049
2050            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
2051
2052                window.pysWooProductData = window.pysWooProductData || [];
2053                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2054                    return;
2055                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2056
2057                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
2058                    product_id = parseInt($form.find('input[name="variation_id"]').val());
2059                }
2060
2061                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2062                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
2063
2064
2065                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params);
2066
2067                        var groupValue = 0;
2068                        if(product_type === Utils.PRODUCT_GROUPED ) {
2069                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
2070                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
2071                                var quantity = parseInt($(this).val());
2072                                if(isNaN(quantity)) {
2073                                    quantity = 0;
2074                                }
2075                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
2076
2077                                if(quantity == 0) {
2078                                    event.params.content_ids.forEach(function(el,index,array) {
2079                                        if(el == childItem.content_id) {
2080                                            array.splice(index, 1);
2081                                        }
2082                                    });
2083                                }
2084
2085                                if(event.params.hasOwnProperty('contents')) {
2086                                    event.params.contents.forEach(function(el,index,array) {
2087                                        if(el.id == childItem.content_id) {
2088                                            if(quantity > 0){
2089                                                el.quantity = quantity;
2090                                            } else {
2091                                                array.splice(index, 1);
2092                                            }
2093                                        }
2094                                    });
2095                                }
2096
2097
2098                                groupValue += childItem.price * quantity;
2099                            });
2100                            if(groupValue == 0) return;
2100 // skip if no items selected
2101                        }
2102
2103                        // maybe customize value option
2104                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
2105
2106                            if(product_type === Utils.PRODUCT_GROUPED) {
2107                                event.params.value = groupValue;
2108                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
2109                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
2110                                var items_sum = getBundlePriceOnSingleProduct(data);
2111                                event.params.value = (parseInt(data.base_price) + items_sum )* qty;
2112                            } else {
2113                                event.params.value = event.params.value * qty;
2114                            }
2115                        }
2116
2117                        // only when non Facebook for WooCommerce logic used
2118                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
2119                            event.params.contents[0].quantity = qty;
2120                        }
2121
2122                        this.fireEvent(event.name, event);
2123
2124                    }
2125                }
2126            },
2127
2128            onWooRemoveFromCartEvent: function (event) {
2129                this.fireEvent(event.name, event);
2130            },
2131
2132            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
2133
2134                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2135                    return;
2136                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2137
2138                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2139
2140                    var index;
2141
2142                    if (price_index) {
2143                        index = download_id + '_' + price_index;
2144                    } else {
2145                        index = download_id;
2146                    }
2147
2148                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2149                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
2150
2151
2152                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
2153
2154                            // maybe customize value option
2155                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
2156                                event.params.value = event.params.value * qty;
2157                            }
2158
2159                            // update contents qty param
2160                            var contents = event.params.contents;
2161                            contents[0].quantity = qty;
2162                            event.params.contents = contents;
2163
2164                            this.fireEvent(event.name,event);
2165
2166                        }
2167                    }
2168
2169                }
2170
2171            },
2172
2173            onEddRemoveFromCartEvent: function (event) {
2174                this.fireEvent(event.name, event);
2175            },
2176            onPageScroll: function (event) {
2177                this.fireEvent(event.name, event);
2178            },
2179            onTime: function (event) {
2180                this.fireEvent(event.name, event);
2181            },
2182            initEventIdCookies: function (key) {
2183                var ids = {};
2184                ids[key] = pys_generate_token(36)
2185                Cookies.set('pys_fb_event_id', JSON.stringify(ids));
2186            },
2187            updateEventId:function(key) {
2188                var cooData = Cookies.get("pys_fb_event_id")
2189                if(cooData === undefined) {
2190                    this.initEventIdCookies(key);
2191                } else {
2192                    var data = JSON.parse(cooData);
2193                    data[key] = pys_generate_token(36);
2194                    Cookies.set('pys_fb_event_id', JSON.stringify(data) );
2195                }
2196            },
2197
2198            getEventId:function (key) {
2199                var data = Cookies.get("pys_fb_event_id");
2200                if(data === undefined) {
2201                    this.initEventIdCookies(key);
2202                    data = Cookies.get("pys_fb_event_id");
2203                }
2204                return JSON.parse(data)[key];
2205            },
2206
2207            sendFacebookRestAPIRequest: function(allData, name, params) {
2208                if (typeof window.pysFacebookRest === 'undefined' || !window.pysFacebookRest.restApiUrl) {
2209                    return;
2210                }
2211
2212                const restApiData = {
2213                    event: name,
2214                    data: JSON.stringify(params),
2215                    ids: allData.pixelIds || options.facebook.pixelIds,
2216                    eventID: allData.eventID,
2217                    woo_order: allData.woo_order || 0,
2218                    edd_order: allData.edd_order || 0
2219                };
2220
2221                // Try sendBeacon first
2222                if (navigator.sendBeacon) {
2223                    const formData = new FormData();
2224                    Object.keys(restApiData).forEach(key => {
2225                        if (Array.isArray(restApiData[key])) {
2226                            restApiData[key].forEach(value => {
2227                                formData.append(key + '[]', value);
2228                            });
2229                        } else {
2230                            formData.append(key, restApiData[key]);
2231                        }
2232                    });
2233
2234                    if (navigator.sendBeacon(window.pysFacebookRest.restApiUrl, formData)) {
2235                        return;
2236                    }
2237                }
2238
2239                // Fallback to fetch
2240                fetch(window.pysFacebookRest.restApiUrl, {
2241                    method: 'POST',
2242                    headers: {
2243                        'Content-Type': 'application/x-www-form-urlencoded',
2244                    },
2245                    body: new URLSearchParams(restApiData)
2246                }).catch(() => {
2247                    // Fallback to AJAX if fetch fails
2248                    this.sendAjaxFallback(allData, name, params);
2249                });
2250            },
2251
2252            sendAjaxFallback: function(allData, name, params) {
2253                var json = {
2254                    action: 'pys_api_event',
2255                    pixel: 'facebook',
2256                    event: name,
2257                    data: params,
2258                    ids: allData.pixelIds || options.facebook.pixelIds,
2259                    eventID: allData.eventID,
2260                    url: window.location.href,
2261                    ajax_event: options.ajax_event
2262                };
2263                if (allData.hasOwnProperty('woo_order')) {
2264                    json['woo_order'] = allData.woo_order;
2265                }
2266                if (allData.hasOwnProperty('edd_order')) {
2267                    json['edd_order'] = allData.edd_order;
2268                }
2269
2270                Utils.sendServerAjaxRequest(options.ajaxUrl, json);
2271            },
2272        };
2273
2274    }(options);
2275
2276    var Analytics = function (options) {
2277
2278        var initialized = false;
2279
2280        /**
2281         * Fires event
2282         *
2283         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
2284         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
2285         * @link: https://developers.google.com/gtagjs/reference/event
2286         * @link: https://developers.google.com/gtagjs/reference/parameter
2287         *
2288         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
2289         *
2290         * @param name
2291         * @param data
2292         */
2293        function fireEvent(name, data) {
2294
2295            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
2296                return;
2297            }
2298
2299            var eventParams = Utils.copyProperties(data, {});
2300            var _fireEvent = function (tracking_id,name,params) {
2301
2302                params['send_to'] = tracking_id;
2303
2304                if (options.debug) {
2305                    console.log('[Google Analytics #' + tracking_id + '] ' + name, params);
2306                }
2307
2308                gtag('event', name, params);
2309
2310            };
2311            options.ga.trackingIds.forEach(function (tracking_id) {
2312                var copyParams = Utils.copyProperties(eventParam
2312s, {}); // copy params because mapParamsTov4 can modify it
2313                var params = mapParamsTov4(tracking_id,name,copyParams)
2314                _fireEvent(tracking_id,name,params);
2315            });
2316
2317        }
2318        function mapParamsTov4(tag,name,param) {
2319            //GA4 automatically collects a number of parameters for all events
2320            delete param.landing_page;
2321            // end
2322            if(isv4(tag)) {
2323                delete param.traffic_source;
2324                delete param.event_category;
2325                delete param.event_label;
2326                delete param.ecomm_prodid;
2327                delete param.ecomm_pagetype;
2328                delete param.ecomm_totalvalue;
2329                if(name === 'search') {
2330                    param['search'] = param.search_term;
2331                    delete param.search_term;
2332                    delete param.dynx_itemid;
2333                    delete param.dynx_pagetype;
2334                    delete param.dynx_totalvalue;
2335                }
2336            }
2337            return param;
2338        }
2339
2340        function isv4(tag) {
2341            return tag.indexOf('G') === 0;
2342        }
2343
2344        /**
2345         * Public API
2346         */
2347        return {
2348            tag: function() {
2349                return "ga";
2350            },
2351            isEnabled: function () {
2352                return options.hasOwnProperty('ga');
2353            },
2354
2355            disable: function () {
2356                initialized = false;
2357            },
2358
2359            loadPixel: function () {
2360
2361                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
2362                    return;
2363                }
2364
2365                Utils.loadGoogleTag(options.ga.trackingIds[0]);
2366                var config = {};
2367                // Cross-Domain tracking
2368                if (options.ga.crossDomainEnabled) {
2369                    config.linker = {
2370                        accept_incoming: options.ga.crossDomainAcceptIncoming,
2371                        domains: options.ga.crossDomainDomains
2372                    };
2373                }
2374                var ids = options.ga.trackingIds;
2375                // configure tracking ids
2376                ids.forEach(function (trackingId,index) {
2377                    var obj = options.ga.isDebugEnabled;
2378                    var searchValue = "index_"+index;
2379                    var config_for_tag = Object.assign({}, options.config);
2380                    config_for_tag.debug_mode = false;
2381                    config_for_tag.send_page_view = !options.ga.custom_page_view_event;
2382                    for (var key in obj) {
2383                        if (obj.hasOwnProperty(key) && obj[key] === searchValue) {
2384                            config_for_tag.debug_mode = true;
2385                            break;
2386                        }
2387                    }
2388                    if(!config_for_tag.debug_mode)
2389                    {
2390                        delete config_for_tag.debug_mode;
2391                    }
2392                    if(isv4(trackingId)) {
2393                        if(options.ga.disableAdvertisingFeatures) {
2394                            config_for_tag.allow_google_signals = false
2395                        }
2396                        if(options.ga.disableAdvertisingPersonalization) {
2397                            config_for_tag.allow_ad_personalization_signals = false
2398                        }
2399                    }
2400                    if(options.ga.hasOwnProperty('additionalConfig')){
2401                        if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){
2402                            config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection;
2403                        }
2404
2405                    }
2406                    if(options.ga.hasOwnProperty('serverContainerUrls')){
2407                        if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){
2408                            if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){
2409                                config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url;
2410                            }
2411                            if(options.ga.serverContainerUrls[trackingId].transport_url != ''){
2412                                config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url;
2413                            }
2414                        }
2415                    }
2416                    if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
2417
2418                        var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
2419                        if (options.gdpr['analytics_prior_consent_enabled']) {
2420                            if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
2421                                gtag('config', trackingId, config_for_tag);
2422                            }
2423                        } else {
2424                            if (Cookiebot.consent[cookiebot_consent_category]) {
2425                                gtag('config', trackingId, config_for_tag);
2426                            }
2427                        }
2428                    }
2429                    else
2430                    {
2431                        gtag('config', trackingId, config_for_tag);
2432                    }
2433                });
2434
2435                initialized = true;
2436
2437                Utils.fireStaticEvents('ga');
2438
2439            },
2440
2441            fireEvent: function (name, data) {
2442
2443                if (!initialized || !this.isEnabled()) {
2444                    return false;
2445                }
2446
2447                data.delay = data.delay || 0;
2448                data.params = data.params || {};
2449                data.params.eventID = Utils.generateUniqueId(data);
2450                if (data.delay === 0) {
2451
2452                    fireEvent(name, data.params);
2453
2454                } else {
2455
2456                    setTimeout(function (name, params) {
2457                        fireEvent(name, params);
2458                    }, data.delay * 1000, name, data.params);
2459
2460                }
2461
2462                return true;
2463
2464            },
2465
2466            onCommentEvent: function (event) {
2467                this.fireEvent(event.name, event);
2468            },
2469
2470            onDownloadEvent: function (event) {
2471                this.fireEvent(event.name, event);
2472            },
2473
2474            onFormEvent: function (event) {
2475                this.fireEvent(event.name, event);
2476            },
2477
2478            onWooAddToCartOnButtonEvent: function (product_id) {
2479
2480                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2481                    return;
2482                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2483
2484                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2485                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
2486                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
2487                        this.fireEvent(event.name, event);
2488                    }
2489                }
2490
2491
2492            },
2493
2494            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
2495
2496                window.pysWooProductData = window.pysWooProductData || [];
2497
2498                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2499                    return;
2500                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2501
2502                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
2503                    product_id = parseInt($form.find('input[name="variation_id"]').val());
2504                }
2505
2506                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2507                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
2508
2509                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
2510                        if(product_type === Utils.PRODUCT_GROUPED ) {
2511                            var groupValue = 0;
2512                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
2513                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
2514                                var quantity = parseInt($(this).val());
2515                                if(isNaN(quantity)) {
2516                                    quantity = 0;
2517                                }
2518                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
2519                                // update quantity
2520                                event.params.items.forEach(function(el,index,array) {
2521                                    if(el.id == childItem.content_id) {
2522                                        if(quantity > 0){
2523                                            el.quantity = quantity;
2524                                        } else {
2525                                            array.splice(index, 1);
2526                                        }
2527                                    }
2528                                });
2529                                groupValue += childItem.price * quantity;
2530                            });
2531                            if(options.woo.addToCartOnButtonValueEnabled &&
2532                                options.woo.addToCartOnButtonValueOption !== 'global' &&
2533                                event.params.hasOwnProperty('ecomm_totalvalue')) {
2534                                event.params.ecomm_totalvalue = groupValue;
2535                            }
2536
2537                            if(groupValue == 0) return; // skip if no items selected
2538                        } else {
2539                            // update items qty param
2540                            event.params.items[0].quantity = qty;
2541                        }
2542
2543                        // maybe customize value option
2544                        if (options.woo.addToCartOnButtonValueEnabled &&
2545                            options.woo.addToCartOnButtonValueOption !== 'global' &&
2546                            product_type !== Utils.PRODUCT_GROUPED)
2547                        {
2548                            if(event.params.hasOwnProperty('ecomm_totalvalue')) {
2549                                event.params.ecomm_totalvalue = event.params.items[0].price * qty;
2550                            }
2551
2552                        }
2553
2554
2555                        this.fireEvent(event.name, event);
2556                    }
2557                }
2558
2559            },
2560
2561            onWooRemoveFromCartEvent: function (event) {
2562
2563                this.fireEvent(event.name, event);
2564
2565            },
2566
2567            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
2568
2569                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2570                    return;
2571                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2572
2573
2574                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2575
2576                    var index;
2577
2578                    if (price_index) {
2579                        index = download_id + '_' + price_index;
2580                    } else {
2581                        index = download_id;
2582                    }
2583
2584                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2585                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
2586
2587                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
2588
2589                            // update items qty param
2590                            event.params.items[0].quantity = qty;
2591
2592                            this.fireEvent(event.name,event);
2593
2594                        }
2595                    }
2596
2597                }
2598
2599            },
2600
2601            onEddRemoveFromCartEvent: function (event) {
2602                this.fireEvent(event.name, event);
2603            },
2604            onPageScroll: function (event) {
2605                this.fireEvent(event.name, event);
2606            },
2607            onTime: function (event) {
2608                this.fireEvent(event.name, event);
2609            },
2610
2611        };
2612
2613    }(options);
2614
2615    var GTM = function (options) {
2616        var initialized = false;
2617
2618        var datalayer_name = 'dataLayer';
2619        /*
2620         * @param name
2621         * @param data
2622         */
2623        function fireEvent(name, event) {
2624            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) {
2625                return;
2626            }
2627
2628
2629            var eventParams = event.params;
2630            var data = event.params;
2631            var valuesArray = Object.values(event.trackingIds);
2632            var ids = valuesArray;
2633            Utils.copyProperties(Utils.getRequestParams(), eventParams);
2634            var _fireEvent = function (tracking_id,name,params, event=null) {
2635                var eventData = {};
2636                var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0;
2637                if(ContainerCodeHasTag) {
2638                    params['send_to'] = tracking_id;
2639                }
2640                else if(!options.gtm.gtm_just_data_layer){
2641                    return
2642                }
2643
2644                if (params.hasOwnProperty('ecommerce')) {
2645                    eventData.ecommerce = params.ecommerce;
2646                    delete params.ecommerce;
2647                }
2648
2649                var automatedParams = { ...params };
2650                [params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]);
2651                if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) {
2652                    eventData.automatedParameters = automatedParams;
2653                }
2654
2655// Move custom parameters to eventData
2656
2657                if (params.hasOwnProperty(params['manualName'])) {
2658                    eventData[params['manualName']] = params[params['manualName']];
2659                    delete params[params['manualName']];
2660                }
2661
2662                ['manualName','triggerType'].forEach(key => {
2663                    if (params.hasOwnProperty(key)) {
2664                        eventData[key] = params[key];
2665                        delete params[key];
2666                    }
2667                });
2668
2669                eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
2670
2671                eventData.event = name;
2672
2673                if (options.debug) {
2674                    if (ContainerCodeHasTag){
2675                        console.log('[Google GTM #' + tracking_id + '] ' + name, eventData);
2676                    }
2677                    else {
2678                        console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData);
2679                    }
2680                }
2681                window[datalayer_name].push(eventData);
2682
2683            };
2684
2685            var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it
2686
2687            var params = mapParamsToGTM(ids,name,copyParams)
2688
2689            params.event_id = Utils.generateUniqueId(event);
2690
2691            _fireEvent(ids, name, params, event);
2692        }
2693
2694        function normalizeEventName(eventName) {
2695
2696            var matches = {
2697                ViewContent: 'view_item',
2698                AddToCart: 'add_to_cart',
2699                AddToWishList: 'add_to_wishlist',
2700                InitiateCheckout: 'begin_checkout',
2701                Purchase: 'purchase',
2702                Lead: 'generate_lead',
2703                CompleteRegistration: 'sign_up',
2704                AddPaymentInfo: 'set_checkout_option'
2705            };
2706
2707            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
2708
2709        }
2710
2711        function mapParamsToGTM(tag,name,param) {
2712            //GA4 automatically collects a number of parameters for all events
2713            var hasGTM = false;
2714
2715            // end
2716            if (Array.isArray(tag)) {
2717                hasGTM = tag.some(function (element) {
2718                    return isGTM(element);
2719                });
2720            } else if(isGTM(tag)) {
2721                // tag is a string and matches GTM
2722                hasGTM = true;
2723            }
2724            if(hasGTM) {
2725                delete param.event_category;
2726                delete param.event_label;
2727
2728                delete param.analytics_storage;
2729                delete param.ad_storage;
2730                delete param.ad_user_data;
2731                delete param.ad_personalization;
2732
2733                if(name === 'search') {
2734                    param['search'] = param.search_term;
2735                    delete param.search_term;
2736                    delete param.dynx_itemid;
2737                    delete param.dynx_pagetype;
2738                    delete param.dynx_totalvalue;
2739                }
2740            }
2741            return param;
2742        }
2743
2744        function isGTM(tag) {
2745            return tag.indexOf('GTM') === 0;
2746        }
2747        /**
2748         * Public API
2749         */
2750        return {
2751            tag: function() {
2752                return "gtm";
2753            },
2754            isEnabled: function () {
2755                return options.hasOwnProperty('gtm');
2756            },
2757            disable: function () {
2758                initialized = false;
2759            },
2760            updateEnhancedConversionData : function () {
2761                if (!initialized || !this.isEnabled()) {
2762                    return;
2763                }
2764                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
2765                    var advanced = Utils.getAdvancedFormData();
2766                    if (Object.keys(advanced).length > 0) {
2767                        window[datalayer_name].push({'user_data' : advanced});
2768                    }
2769                }
2770            },
2771            loadPixel: function () {
2772
2773                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
2774                    return;
2775                }
2776                datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
2777
2778                for (var i = 0; i < options.gtm.trackingIds.length; i++) {
2779                    var trackingId = options.gtm.trackingIds[i];
2780                    if (!options.gtm.gtm_just_data_layer) {
2781                        console.log('[PYS] Google Tag Manager container code loaded');
2782                        Utils.loadGTMScript(trackingId);
2783                        break;
2784                    }
2785                }
2786                if(options.gtm.gtm_just_data_layer) {
2787                    console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!");
2788                    console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!");
2789                    if(options.gtm.trackingIds.length == 0){
2790                        Utils.loadGTMScript();
2791                    }
2792                }
2793
2794                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
2795                    var advanced = Utils.getAdvancedFormData();
2796                    if(Object.keys(advanced).length > 0){
2797                        window[datalayer_name].push({'user_data' : advanced});
2798                    }
2799                }
2800
2801
2802                var config = {};
2803
2804                if(options.user_id && options.user_id != 0) {
2805                    config.user_id = options.user_id;
2806                }
2807
2808                // Cross-Domain tracking
2809
2810                var ids = options.gtm.trackingIds;
2811
2812
2813                initialized = true;
2814
2815                Utils.fireStaticEvents('gtm');
2816            },
2817
2818            fireEvent: function (name, data) {
2819
2820                if (!initialized || !this.isEnabled()) {
2821                    return false;
2822                }
2823
2824                data.delay = data.delay || 0;
2825                data.params = data.params || {};
2826
2827                if (data.delay === 0) {
2828
2829                    fireEvent(name, data);
2830
2831                } else {
2832
2833                    setTimeout(function (name, params) {
2834                        fireEvent(name, params);
2835                    }, data.delay * 1000, name, data);
2836
2837                }
2838
2839                return true;
2840
2841            },
2842
2843            onCommentEvent: function (event) {
2844                this.fireEvent(event.name, event);
2845            },
2846
2847            onDownloadEvent: function (event) {
2848                this.fireEvent(event.name, event);
2849            },
2850
2851            onFormEvent: function (event) {
2852                this.fireEvent(event.name, event);
2853            },
2854
2855            onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
2856                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2857                    return;
2858                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2859
2860                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2861                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
2862                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params)
2863                        this.fireEvent(event.name, event);
2864                    }
2865                }
2866
2867            },
2868
2869            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
2870                window.pysWooProductData = window.pysWooProductData || [];
2871
2872                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2873                    return;
2874                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2875
2876                if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) {
2877                    product_id = parseInt($form.find('input[name="variation_id"]').val());
2878                }
2879
2880                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2881                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
2882
2883                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params);
2884
2885                        params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params;
2886
2887                        if(product_type === Utils.PRODUCT_GROUPED ) {
2888                            var groupValue = 0;
2889                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
2890                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
2891                                var quantity = parseInt($(this).val());
2892                                if(isNaN(quantity)) {
2893                                    quantity = 0;
2894                                }
2895                                var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId];
2896                                params.items.forEach(function(el,index,array) {
2897                                    if(el.id == childItem.content_id) {
2898                                        if(quantity > 0){
2899                                            el.quantity = quantity;
2900                                            el.price = childItem.price;
2901                                        } else {
2902                                            array.splice(index, 1);
2903                                        }
2904                                    }
2905                                });
2906                                groupValue += childItem.price * quantity;
2907                            });
2908
2909                            if(options.woo.addToCartOnButtonValueEnabled &&
2910                                options.woo.addToCartOnButtonValueOption !== 'global' &&
2911                                params.hasOwnProperty('value')) {
2912                                params.value = groupValue;
2913                            }
2914
2915                            if(groupValue == 0) return; // skip if no items selected
2916                        } else {
2917                            // update items qty param
2918                            params.items[0].quantity = qty;
2919                        }
2920
2921                        // maybe customize value option
2922                        if (options.woo.addToCartOnButtonValueEnabled &&
2923                            options.woo.addToCartOnButtonValueOption !== 'global' &&
2924                            product_type !== Utils.PRODUCT_GROUPED)
2925                        {
2926                            if(params.hasOwnProperty('value')) {
2927                                params.value = params.items[0].price * qty;
2928                            }
2929
2930                        }
2931
2932
2933                        this.fireEvent(event.name, event);
2934                    }
2935                }
2936
2937            },
2938
2939            onWooRemoveFromCartEvent: function (event) {
2940
2941                this.fireEvent(event.name, event);
2942
2943            },
2944
2945            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
2946                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2947                    return;
2948                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2949
2950
2951                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2952
2953                    var index;
2954
2955                    if (price_index) {
2956                        index = download_id + '_' + price_index;
2957                    } else {
2958                        index = download_id;
2959                    }
2960
2961                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2962                        if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) {
2963
2964                            Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params);
2965                            item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
2966                            // update items qty param
2967                            item.quantity = qty;
2968
2969                            this.fireEvent(event.name,event);
2970
2971                        }
2972                    }
2973
2974                }
2975
2976            },
2977
2978            onEddRemoveFromCartEvent: function (event) {
2979                this.fireEvent(event.name, event);
2980            },
2981            onPageScroll: function (event) {
2982                this.fireEvent(event.name, event);
2983            },
2984            onTime: function (event) {
2985                this.fireEvent(event.name, event);
2986            },
2987        };
2988
2989    }(options);
2990
2991    var getPixelBySlag = function getPixelBySlag(slug) {
2992        switch (slug) {
2993            case "facebook": return window.pys.Facebook;
2994            case "ga": return window.pys.Analytics;
2995            case "gtm": return window.pys.GTM;
2996            case "bing": return window.pys.Bing;
2997            case "pinterest": return window.pys.Pinterest;
2998        }
2999    }
3000
3001    window.pys = window.pys || {};
3002    window.pys.Facebook = Facebook;
3003    window.pys.Analytics = Analytics;
3004    window.pys.GTM = GTM;
3005    window.pys.Utils = Utils;
3006    window.pys.getPixelBySlag = getPixelBySlag;
3007
3008    // Export getPixelBySlag globally for backward compatibility
3009    window.getPixelBySlag = getPixelBySlag;
3010
3011
3012    $(document).ready(function () {
3013
3014        if($("#pys_late_event").length > 0) {
3015            var dirAttr = $("#pys_late_event").attr("dir");
3016            if (dirAttr) {
3017                try {
3018                    var events = JSON.parse(dirAttr);
3019                } catch (e) {
3020                    console.warn("Invalid JSON in pys_late_event dir attribute:", e);
3021                }
3022            } else {
3023                console.warn("pys_late_event dir attribute is undefined or empty");
3024            }
3025            if (events) {
3026                for (var key in events) {
3027                    var event = {};
3028                    event[events[key].e_id] = [events[key]];
3029                    if (options.staticEvents.hasOwnProperty(key)) {
3030                        Object.assign(options.staticEvents[key], event);
3031                    } else {
3032                        options.staticEvents[key] = event;
3033                    }
3034                }
3035            }
3036        }
3037
3038        var Pinterest = Utils.setupPinterestObject();
3039        var Bing = Utils.setupBingObject();
3040
3041        if(options.hasOwnProperty('cookie'))
3042        {
3043            if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie)
3044            {
3045                Cookies.remove('pbid')
3046            }
3047            if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie)
3048            {
3049                Cookies.remove('pys_advanced_form_data')
3050            }
3051            if(options.cookie.disabled_landing_page_cookie || options.cookie.disabled_all_cookie)
3052            {
3053                Cookies.remove('pys_landing_page')
3054                Cookies.remove('last_pys_landing_page')
3055            }
3056            if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie)
3057            {
3058                Cookies.remove('pysTrafficSource')
3059                Cookies.remove('last_pysTrafficSource')
3060            }
3061            if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie)
3062            {
3063                Cookies.remove('pys_first_visit')
3064
3065            }
3066            if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie)
3067            {
3068                $.each(Utils.utmTerms, function (index, name) {
3069                    Cookies.remove('pys_' + name)
3070                });
3071                $.each(Utils.utmTerms, function (index, name) {
3072                    Cookies.remove('last_pys_' + name)
3073                });
3074            }
3075            if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie)
3076            {
3077                $.each(Utils.utmId,function(index,name) {
3078                    Cookies.remove('pys_' + name)
3079                })
3080                $.each(Utils.utmId,function(index,name) {
3081                    Cookies.remove('last_pys_' + name)
3082                });
3083            }
3084        }
3085
3086
3087        if (options.gdpr.cookie_law_info_integration_enabled) {
3088            var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('viewed_cookie_policy');
3089
3090            if (typeof cli_cookie !== 'undefined') {
3091                if (cli_cookie === Cookies.get('cookieyes-consent') && getCookieYes('analytics') == 'yes') {
3092                    Utils.manageCookies();
3093                } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
3094                    Utils.manageCookies();
3095                }
3096            }
3097        }
3098
3099        if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
3100            if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) {
3101                Utils.manageCookies();
3102            } else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) {
3103                Utils.manageCookies();
3104            }
3105        } else {
3106            Utils.manageCookies();
3107        }
3108
3109        Utils.setupGdprCallbacks();
3110        // page scroll event
3111        if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
3112        ) {
3113
3114            var singlePageScroll = function () {
3115
3116
3117                var docHeight = $(document).height() - $(window).height();
3118                var isFired = false;
3119
3120                if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
3121                    var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
3122                    for(var i = 0;i<pixels.length;i++) {
3123                        var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
3124                        var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
3125
3126                        if(scroll < $(window).scrollTop()) {
3127                            Utils.copyProperties(Utils.getRequestParams(), event.params);
3128                            getPixelBySlag(pixels[i]).onPageScroll(event);
3129                            isFired = true
3130                        }
3131                    }
3132                }
3133                if(isFired) {
3134                    $(document).off("scroll",singlePageScroll);
3135                }
3136            }
3137            $(document).on("scroll",singlePageScroll);
3138        }
3139
3140
3141        if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
3142            var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
3143            var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
3144            setTimeout(function(){
3145                for(var i = 0;i<pixels.length;i++) {
3146                    var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
3147                    Utils.copyProperties(Utils.getRequestParams(), event.params);
3148                    getPixelBySlag(pixels[i]).onTime(event);
3149                }
3150            },time*1000);
3151        }
3152
3153        // setup Click Event
3154        if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
3155
3156            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
3157
3158                var $elem = $(this);
3159
3160                // Download
3161                if(options.dynamicEvents.hasOwnProperty("automatic_event_download")
3162                ) {
3163                    var isFired = false;
3164                    if ($elem.is('a')) {
3165                        var href = $elem.attr('href');
3166                        if (typeof href !== "string") {
3167                            return;
3168                        }
3169                        href = href.trim();
3170                        var extension = Utils.getLinkExtension(href);
3171                        var track_download = false;
3172
3173                        if (extension.length > 0) {
3174
3175                            if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
3176                                var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
3177                                for (var i = 0; i < pixels.length; i++) {
3178                                    var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
3179                                    var extensions = event.extensions;
3180                                    if (extensions.includes(extension)) {
3181
3182                                        if(pixels[i] == "tiktok") {
3183                                            getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event);
3184                                        } else {
3185                                            if (options.enable_remove_download_url_param) {
3186                                                href = href.split('?')[0];
3187                                            }
3188                                            event.params.download_url = href;
3189                                            event.params.download_type = extension;
3190                                            event.params.download_name = Utils.getLinkFilename(href);
3191                                            getPixelBySlag(pixels[i]).onDownloadEvent(event);
3192                                        }
3193
3194                                        isFired = true;
3195                                    }
3196                                }
3197                            }
3198                        }
3199                    }
3200                    if(isFired) { // prevent duplicate events on the same element
3201                        return;
3202                    }
3203                }
3204            });
3205        }
3206
3207
3208        // setup Dynamic events
3209        $.each(options.triggerEventTypes, function (triggerType, events) {
3210
3211            $.each(events, function (eventId, triggers) {
3212
3213                switch (triggerType) {
3214                    case 'url_click':
3215                        //@see: Utils.setupURLClickEvents()
3216                        break;
3217
3218                    case 'css_click':
3219                        Utils.setupCSSClickEvents(eventId, triggers);
3220                        break;
3221
3222                    case 'css_mouseover':
3223                        Utils.setupMouseOverClickEvents(eventId, triggers);
3224                        break;
3225
3226                    case 'scroll_pos':
3227                        Utils.setupScrollPosEvents(eventId, triggers);
3228                        break;
3229                    case 'comment':
3230                        Utils.setupCommentEvents(eventId, triggers);
3231                        break;
3232                }
3233
3234            });
3235
3236        });
3237        // setup WooCommerce events
3238        if (options.woo.enabled) {
3239
3240            // WooCommerce AddToCart
3241            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
3242                && options.woo.hasOwnProperty("addToCartCatchMethod")
3243                && options.woo.addToCartCatchMethod === "add_cart_js"
3244            ) {
3245
3246                // Loop, any kind of "simple" product, except external
3247                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
3248
3249                    var product_id = $(this).data('product_id');
3250                    if (typeof product_id !== 'undefined') {
3251                        if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")) {
3252                            var tmpEventID = pys_generate_token();
3253                            $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
3254                                tag.eventID = tmpEventID;
3255                            });
3256                        }
3257                        if (typeof product_id !== 'undefined') {
3258                            Facebook.onWooAddToCartOnButtonEvent(product_id);
3259                            Analytics.onWooAddToCartOnButtonEvent(product_id);
3260                            GTM.onWooAddToCartOnButtonEvent(product_id);
3261                            Pinterest.onWooAddToCartOnButtonEvent(product_id);
3262                            Bing.onWooAddToCartOnButtonEvent(product_id);
3263                        }
3264                    }
3265                });
3266
3267                // Single Product
3268                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
3269                //  $(document) not work
3270                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
3271
3272                    var $button = $(this);
3273
3274                    if ($button.hasClass('disabled')) {
3275                        return;
3276                    }
3277
3278                    var $form = $button.closest('form');
3279
3280                    var product_type = Utils.PRODUCT_SIMPLE;
3281
3282                    if ($form.length === 0) {
3283                        return ;
3284                    } else if ($form.hasClass('variations_form')) {
3285                        product_type = Utils.PRODUCT_VARIABLE;
3286                    } else if($form.hasClass('bundle_form')) {
3287                        product_type = Utils.PRODUCT_BUNDLE;
3288                    } else if($form.hasClass('grouped_form')) {
3289                        product_type = Utils.PRODUCT_GROUPED;
3290                    }
3291
3292
3293
3294
3295                    var product_id;
3296                    var qty;
3297
3298                    if (product_type === Utils.PRODUCT_GROUPED) {
3299                        qty = 1;
3300                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
3301                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
3302                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
3303                        var qtyTag = $form.find('input[name="quantity"]');
3304                        if(qtyTag.length <= 0) {
3305                            qtyTag = $form.find('select[name="quantity"]');
3306                        }
3307                        qty = parseInt(qtyTag.val());
3308                    } else {
3309                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
3310                        var qtyTag = $form.find('input[name="quantity"]');
3311                        if(qtyTag.length <= 0) {
3312                            qtyTag = $form.find('select[name="quantity"]');
3313                        }
3314                        qty = parseInt(qtyTag.val());
3315                    }
3316
3317                    if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
3318                        var tmpEventID = pys_generate_token();
3319                        $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
3320                            tag.eventID = tmpEventID;
3321                        });
3322                    }
3323
3324                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
3325                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
3326
3327                    GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
3328
3329                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
3330                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
3331
3332                });
3333
3334            }
3335
3336            // WooCommerce RemoveFromCart
3337            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
3338
3339                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
3340
3341                    var $a = $(e.currentTarget),
3342                        href = $a.attr('href');
3343
3344                    // extract cart item hash from remove button URL
3345                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
3346                        results = regex.exec(href);
3347
3348                    if (results !== null) {
3349
3350                        var item_hash = results[1];
3351
3352                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
3353                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
3354                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
3355                        }
3356
3357                    }
3358
3359                });
3360            }
3361        }
3362
3363        // setup EDD events
3364        if (options.edd.enabled) {
3365
3366            // EDD AddToCart
3367            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
3368
3369                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
3370
3371                    var $button = $(this);
3372                    var $form = $button.closest('form');
3373                    var variable_price = $button.data('variablePrice'); // yes/no
3374                    var price_mode = $button.data('priceMode'); // single/multi
3375                    var ids = [];
3376                    var quantities = [];
3377                    var qty;
3378                    var id;
3379
3380                    if (variable_price === 'yes' && price_mode === 'multi') {
3381
3382                        id = $form.find('input[name="download_id"]').val();
3383
3384                        // get selected variants
3385                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
3386                            ids.push(id + '_' + $(el).val());
3387                        });
3388
3389                        // get qty for selected variants
3390                        $.each(ids, function (i, variant_id) {
3391
3392                            var variant_index = variant_id.split('_', 2);
3393                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
3394
3395                            if (typeof qty !== 'undefined') {
3396                                quantities.push(qty);
3397                            } else {
3398                                quantities.push(1);
3399                            }
3400
3401                        });
3402
3403                    } else if (variable_price === 'yes' && price_mode === 'single') {
3404
3405                        id = $form.find('input[name="download_id"]').val();
3406                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
3407
3408                        qty = $form.find('input[name="edd_download_quantity"]').val();
3409
3410                        if (typeof qty !== 'undefined') {
3411                            quantities.push(qty);
3412                        } else {
3413                            quantities.push(1);
3414                        }
3415
3416                    } else {
3417
3418                        ids.push($button.data('downloadId'));
3419
3420                        qty = $form.find('input[name="edd_download_quantity"]').val();
3421
3422                        if (typeof qty !== 'undefined') {
3423                            quantities.push(qty);
3424                        } else {
3425                            quantities.push(1);
3426                        }
3427                    }
3428
3429                    // fire event for each download/variant
3430                    $.each(ids, function (i, download_id) {
3431
3432                        var q = parseInt(quantities[i]);
3433                        var variant_index = download_id.toString().split('_', 2);
3434                        var price_index;
3435
3436                        if (variant_index.length === 2) {
3437                            download_id = variant_index[0];
3438                            price_index = variant_index[1];
3439                        }
3440
3441                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
3442                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
3443                        GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q);
3444                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
3445                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
3446
3447                    });
3448
3449                });
3450
3451            }
3452
3453
3454            // EDD RemoveFromCart
3455            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
3456
3457                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
3458
3459                    var href = $(this).attr('href');
3460                    if(href) {
3461                        var key = href.substring(href.indexOf('=') + 1).charAt(0);
3462                        if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
3463                            var events = options.dynamicEvents.edd_remove_from_cart[key];
3464                            Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
3465                        }
3466                    }
3467                });
3468
3469            }
3470
3471        }
3472
3473        // setup Comment Event
3474        if (options.dynamicEvents.hasOwnProperty("automatic_event_c
3474omment")
3475        ) {
3476
3477            $('form.comment-form').on("submit",function () {
3478                if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
3479                    var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
3480                    for (var i = 0; i < pixels.length; i++) {
3481                        var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]);
3482                        Utils.copyProperties(Utils.getRequestParams(), event.params);
3483                        getPixelBySlag(pixels[i]).onCommentEvent(event);
3484                    }
3485                }
3486            });
3487
3488        }
3489
3490
3491        // setup Form Event
3492        if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
3493
3494            $(document).onFirst('submit', 'form', function (e) {
3495
3496                var $form = $(this);
3497
3498                // exclude WP forms
3499                if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
3500                    return;
3501                }
3502
3503                // exclude Woo forms
3504                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
3505                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
3506                    return;
3507                }
3508
3509                // exclude EDD forms
3510                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
3511                    return;
3512                }
3513// exclude CF7 forms
3514                if ($form.hasClass('wpcf7-form')) {
3515                    return;
3516                }
3517                // exclude Forminator forms
3518                if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
3519                    return;
3520                }
3521                // exclude WPforms forms
3522                if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
3523                    return;
3524                }
3525                // exclude Formidable forms
3526                /*if ($form.hasClass('frm-show-form')) {
3527                    return;
3528                }*/
3529                // exclude Ninja Forms forms
3530                if ($form.parent().hasClass('nf-form-layout')) {
3531                    return;
3532                }
3533                // exclude Fluent forms
3534                if ($form.hasClass('frm-fluent-form')) {
3535                    return;
3536                }
3537                if(!options.enable_success_send_form) {
3538                    var params = {
3539                        form_id: $form.attr('id'),
3540                        form_class: $form.attr('class'),
3541                        text: $form.find('[type="submit"]').is('input') ?
3542                            $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
3543                    };
3544
3545                    if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
3546                        var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
3547                        for (var i = 0; i < pixels.length; i++) {
3548                            var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
3549
3550                            if (pixels[i] === "tiktok") {
3551                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3552                            } else {
3553                                Utils.copyProperties(params, event.params,)
3554                                Utils.copyProperties(Utils.getRequestParam
3554s(), event.params);
3555                                getPixelBySlag(pixels[i]).onFormEvent(event);
3556                            }
3557                        }
3558                    }
3559                }
3560            });
3561
3562            document.addEventListener( 'wpcf7mailsent', function( event ) {
3563                var form_id = event.detail.contactFormId;
3564                sendFormAction($(event.target), form_id);
3565            }, false );
3566            //Forminator
3567            $(document).on( 'forminator:form:submit:success', function( event ){
3568                var form_id = $(event.target).find('input[name="form_id"]').val();
3569                sendFormAction($(event.target), form_id);
3570            });
3571
3572            //WPForm
3573            $('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => {
3574                var form_id = $(event.target).attr('data-formid');
3575                sendFormAction($(event.target), form_id);
3576            })
3577            $(document).on( 'frmFormComplete', function( event, form, response ) {
3578                const form_id = $(form).find('input[name="form_id"]').val();
3579                sendFormAction($(event.target), form_id);
3580            });
3581            // Ninja Forms
3582            $(document).onFirst('nfFormSubmitResponse', function (event, data) {
3583                const form_id = data.response.data.form_id;
3584                sendFormAction($(event.target), form_id);
3585            });
3586
3587            var fluentForms = $('form.frm-fluent-form');
3588            fluentForms.each(function() {
3589                var $form = $(this);
3590                $form.on('fluentform_submission_success', function(event) {
3591                    var $formItem = $(this);
3592                    var form_id = $formItem.attr('data-form_id');
3593                    sendFormAction($(event.target), form_id);
3594                });
3595            });
3596
3597        }
3598
3599
3600        // load pixel APIs
3601        Utils.loadPixels();
3602        // setup Enrich content
3603        if(Utils.isCheckoutPage()) {
3604            Utils.addCheckoutFields();
3605        }
3606    });
3607
3608    var sendFormAction = function (form_target, formId){
3609        var params = {
3610            form_id: formId,
3611            text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
3612                form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
3613                    form_target.find('[type="submit"]').text()
3614        };
3615
3616        if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
3617            var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
3618            for (var i = 0; i < pixels.length; i++) {
3619                var event = options.dynamicEvents.automatic_event_form[pixels[i]];
3620                if (pixels[i] === "tiktok") {
3621                    getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3622                } else {
3623                    Utils.copyProperties(params, event.params)
3624                    Utils.copyProperties(Utils.getRequestParams(), event.params);
3625                    getPixelBySlag(pixels[i]).onFormEvent(event);
3626                }
3627            }
3628        }
3629    }
3630
3631}(jQuery, pysOptions);
3632
3633function pys_generate_token() {
3634    return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
3635        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
3636    );
3637}
3638
3639function getBundlePriceOnSingleProduct(data) {
3640    var items_sum = 0;
3641    jQuery(".bundle_form .bundled_product").each(function(index){
3642        var id = jQuery(this).find(".cart").data("bundled_item_id");
3643        var item_price = data.prices[id];
3644        var item_quantity = jQuery(this).find(".bundled_qty").val();
3645        if(!jQuery(this).hasClass("bundled_item_optional") ||
3646            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
3647            items_sum += item_price*item_quantity;
3648        }
3649    });
3650    return items_sum;
3651}
3652function getUrlParameter(sParam) {
3653    var sPageURL = window.location.search.substring(1),
3654        sURLVariables = sPageURL.split('&'),
3655        sParameterName,
3656        i;
3657
3658    for (i = 0; i < sURLVariables.length; i++) {
3659        sParameterName = sURLVariables[i].split('=');
3660
3661        if (sParameterName[0] === sParam) {
3662            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
3663        }
3664    }
3665    return false;
3666};
3667function getCookieYes(key) {
3668    const cookiesObj = document.cookie
3669        .split(";")
3670        .reduce((ac, cv) => {
3671            const [k, v] = cv.split("=");
3672            if (k && v) ac[k.trim()] = v;
3673            return ac;
3674        }, {});
3675    const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"];
3676    if (!consentCookie) return undefined;
3677    const { [key]: value } = consentCookie
3678        .split(",")
3679        .reduce((obj, pair) => {
3680            const [k, v] = pair.split(":");
3681            if (k && v) obj[k] = v;
3682            return obj;
3683        }, {});
3684    return value;
3685}
3686function getRootDomain(useSubdomain = false) {
3687    const hostname = window.location.hostname; // Get the current hostname
3688    // Check if tldjs is defined before using it
3689    if (typeof tldjs === "undefined") {
3690        console.warn("tldjs is not defined");
3691        return hostname; // Return hostname as a fallback
3692    }
3693
3694    const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain
3695
3696    // Return the root domain with or without a leading dot based on useSubdomain
3697    return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname;
3698}

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.